1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
package com.intellij.refactoring.move.moveClassesOrPackages;
import com.intellij.codeInsight.ChangeContextUtil;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.listeners.RefactoringElementListener;
import com.intellij.refactoring.util.RefactoringConflictsUtil;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.Function;
import com.intellij.util.containers.MultiMap;
import com.intellij.psi.util.FileTypeUtils;
import java.util.*;
public class JavaMoveDirectoryWithClassesHelper extends MoveDirectoryWithClassesHelper {
@Override
public void findUsages(Collection<PsiFile> filesToMove,
PsiDirectory[] directoriesToMove,
Collection<UsageInfo> usages,
boolean searchInComments,
boolean searchInNonJavaFiles,
Project project) {
final Set<String> packageNames = new HashSet<String>();
for (PsiFile psiFile : filesToMove) {
if (psiFile instanceof PsiClassOwner) {
final PsiClass[] classes = ((PsiClassOwner)psiFile).getClasses();
for (PsiClass aClass : classes) {
Collections
.addAll(usages, MoveClassesOrPackagesUtil.findUsages(aClass, searchInComments, searchInNonJavaFiles, aClass.getName()));
}
packageNames.add(((PsiClassOwner)psiFile).getPackageName());
}
}
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
for (String packageName : packageNames) {
final PsiPackage aPackage = psiFacade.findPackage(packageName);
if (aPackage != null) {
boolean remainsNothing = true;
for (PsiDirectory packageDirectory : aPackage.getDirectories()) {
if (!isUnderRefactoring(packageDirectory, directoriesToMove)) {
remainsNothing = false;
break;
}
}
if (remainsNothing) {
for (PsiReference reference : ReferencesSearch.search(aPackage, GlobalSearchScope.projectScope(project))) {
final PsiElement element = reference.getElement();
final PsiImportStatementBase statementBase = PsiTreeUtil.getParentOfType(element, PsiImportStatementBase.class);
if (statementBase != null && statementBase.isOnDemand()) {
usages.add(new RemoveOnDemandImportStatementsUsageInfo(statementBase));
}
}
}
}
}
}
private static boolean isUnderRefactoring(PsiDirectory packageDirectory, PsiDirectory[] directoriesToMove) {
for (PsiDirectory directory : directoriesToMove) {
if (PsiTreeUtil.isAncestor(directory, packageDirectory, true)) {
return true;
}
}
return false;
}
@Override
public boolean move(PsiFile file,
PsiDirectory moveDestination,
Map<PsiElement, PsiElement> oldToNewElementsMapping,
List<PsiFile> movedFiles,
RefactoringElementListener listener) {
if (!(file instanceof PsiClassOwner)) {
return false;
}
if (!FileTypeUtils.isInServerPageFile(file)) {
return false;
}
for (PsiClass psiClass : ((PsiClassOwner)file).getClasses()) {
final PsiClass newClass = MoveClassesOrPackagesUtil.doMoveClass(psiClass, moveDestination);
oldToNewElementsMapping.put(psiClass, newClass);
listener.elementMoved(newClass);
}
return true;
}
@Override
public void postProcessUsages(UsageInfo[] usages, Function<PsiDirectory, PsiDirectory> newDirMapper) {
for (UsageInfo usage : usages) {
if (usage instanceof RemoveOnDemandImportStatementsUsageInfo) {
final PsiElement element = usage.getElement();
if (element != null) {
element.delete();
}
}
}
}
@Override
public void preprocessUsages(Project project,
Set<PsiFile> files,
UsageInfo[] infos,
PsiDirectory directory,
MultiMap<PsiElement, String> conflicts) {
RefactoringConflictsUtil.analyzeModuleConflicts(project, files, infos, directory, conflicts);
}
@Override
public void beforeMove(PsiFile psiFile) {
ChangeContextUtil.encodeContextInfo(psiFile, true);
}
@Override
public void afterMove(PsiElement newElement) {
ChangeContextUtil.decodeContextInfo(newElement, null, null);
}
private static class RemoveOnDemandImportStatementsUsageInfo extends UsageInfo {
public RemoveOnDemandImportStatementsUsageInfo(PsiImportStatementBase statementBase) {
super(statementBase);
}
}
}
|