blob: 88f8151576656aaac942285370c9fd90fcb686aa [file] [log] [blame]
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);
}
}
}