From 7188f547852d45666a68ac5bd05dbb09bf29a4db Mon Sep 17 00:00:00 2001 From: "Kirill.Safonov" Date: Thu, 23 Jun 2011 19:06:42 +0400 Subject: [PATCH] exctract language-independent part from MoveDirectoryWithClassesProcessor --- .../JavaMoveDirectoryWithClassesHelper.java | 112 ++++++++++++++++++ .../MoveClassToInnerProcessor.java | 7 +- .../MoveClassesOrPackagesProcessor.java | 30 +---- .../MoveMultipleElementsViewDescriptor.java | 33 ++---- .../moveClassesOrPackages/CommonMoveUtil.java | 46 +++++++ .../MoveDirectoryWithClassesHelper.java | 86 ++++++++++++++ .../MoveDirectoryWithClassesProcessor.java | 102 ++++------------ .../src/META-INF/LangExtensionPoints.xml | 1 + .../src/META-INF/LangExtensions.xml | 2 + .../move/MoveGroovyScriptProcessor.java | 3 +- resources/src/META-INF/IdeaPlugin.xml | 2 + 11 files changed, 289 insertions(+), 135 deletions(-) create mode 100644 java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveDirectoryWithClassesHelper.java rename java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesViewDescriptor.java => platform/lang-impl/src/com/intellij/refactoring/move/MoveMultipleElementsViewDescriptor.java (58%) create mode 100644 platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/CommonMoveUtil.java create mode 100644 platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesHelper.java rename {java/java-impl => platform/lang-impl}/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java (73%) diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveDirectoryWithClassesHelper.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveDirectoryWithClassesHelper.java new file mode 100644 index 000000000000..18d5ab743b9b --- /dev/null +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveDirectoryWithClassesHelper.java @@ -0,0 +1,112 @@ +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.searches.ReferencesSearch; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.listeners.RefactoringElementListener; +import com.intellij.usageView.UsageInfo; + +import java.util.*; + +public class JavaMoveDirectoryWithClassesHelper extends MoveDirectoryWithClassesHelper { + + @Override + public void findUsages(Collection filesToMove, + PsiDirectory[] directoriesToMove, + Collection usages, + boolean searchInComments, + boolean searchInNonJavaFiles, + Project project) { + final Set packageNames = new HashSet(); + 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)) { + 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 oldToNewElementsMapping, + List movedFiles, + RefactoringElementListener listener) { + if (!(file instanceof PsiClassOwner)) { + 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) { + for (UsageInfo usage : usages) { + if (usage instanceof RemoveOnDemandImportStatementsUsageInfo) { + final PsiElement element = usage.getElement(); + if (element != null) { + element.delete(); + } + } + } + } + + @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); + } + } +} diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassToInnerProcessor.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassToInnerProcessor.java index 8097599a0eba..3a25fb25c195 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassToInnerProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassToInnerProcessor.java @@ -36,6 +36,7 @@ import com.intellij.refactoring.PackageWrapper; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.move.MoveCallback; import com.intellij.refactoring.move.MoveClassesOrPackagesCallback; +import com.intellij.refactoring.move.MoveMultipleElementsViewDescriptor; import com.intellij.refactoring.rename.RenameUtil; import com.intellij.refactoring.util.*; import com.intellij.usageView.UsageInfo; @@ -93,9 +94,7 @@ public class MoveClassToInnerProcessor extends BaseRefactoringProcessor { } protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) { - return new MoveClassesOrPackagesViewDescriptor(myClassesToMove, - mySearchInComments, mySearchInNonJavaFiles, - myTargetClass.getQualifiedName()); + return new MoveMultipleElementsViewDescriptor(myClassesToMove, myTargetClass.getQualifiedName()); } @NotNull @@ -155,7 +154,7 @@ public class MoveClassToInnerProcessor extends BaseRefactoringProcessor { oldToNewElementsMapping.put(classToMove, newClass); } - myNonCodeUsages = MoveClassesOrPackagesProcessor.retargetUsages(usages, oldToNewElementsMapping); + myNonCodeUsages = CommonMoveUtil.retargetUsages(usages, oldToNewElementsMapping); retargetNonCodeUsages(oldToNewElementsMapping); retargetClassRefsInMoved(oldToNewElementsMapping); diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesProcessor.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesProcessor.java index a1f370567f5d..cf04a5e61329 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesProcessor.java @@ -38,6 +38,7 @@ import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.listeners.RefactoringElementListener; import com.intellij.refactoring.move.MoveCallback; import com.intellij.refactoring.move.MoveClassesOrPackagesCallback; +import com.intellij.refactoring.move.MoveMultipleElementsViewDescriptor; import com.intellij.refactoring.rename.RenameUtil; import com.intellij.refactoring.util.*; import com.intellij.refactoring.util.classRefs.ClassInstanceScanner; @@ -114,8 +115,7 @@ public class MoveClassesOrPackagesProcessor extends BaseRefactoringProcessor { protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) { PsiElement[] elements = new PsiElement[myElementsToMove.length]; System.arraycopy(myElementsToMove, 0, elements, 0, myElementsToMove.length); - return new MoveClassesOrPackagesViewDescriptor(elements, mySearchInComments, mySearchInNonJavaFiles, - MoveClassesOrPackagesUtil.getPackageName(myTargetPackage)); + return new MoveMultipleElementsViewDescriptor(elements, MoveClassesOrPackagesUtil.getPackageName(myTargetPackage)); } public boolean verifyValidPackageName() { @@ -486,7 +486,7 @@ public class MoveClassesOrPackagesProcessor extends BaseRefactoringProcessor { } } - myNonCodeUsages = retargetUsages(usages, oldToNewElementsMapping); + myNonCodeUsages = CommonMoveUtil.retargetUsages(usages, oldToNewElementsMapping); } catch (IncorrectOperationException e) { myNonCodeUsages = new NonCodeUsageInfo[0]; @@ -494,30 +494,6 @@ public class MoveClassesOrPackagesProcessor extends BaseRefactoringProcessor { } } - public static NonCodeUsageInfo[] retargetUsages(final UsageInfo[] usages, final Map oldToNewElementsMapping) - throws IncorrectOperationException { - List nonCodeUsages = new ArrayList(); - for (UsageInfo usage : usages) { - if (usage instanceof NonCodeUsageInfo) { - nonCodeUsages.add((NonCodeUsageInfo)usage); - } - else if (usage instanceof MoveRenameUsageInfo) { - final MoveRenameUsageInfo moveRenameUsage = (MoveRenameUsageInfo)usage; - final PsiElement oldElement = moveRenameUsage.getReferencedElement(); - final PsiElement newElement = oldToNewElementsMapping.get(oldElement); - LOG.assertTrue(newElement != null); - final PsiReference reference = moveRenameUsage.getReference(); - if (reference != null) { - try { - reference.bindToElement(newElement); - } catch (IncorrectOperationException e) {// - } - } - } - } - return nonCodeUsages.toArray(new NonCodeUsageInfo[nonCodeUsages.size()]); - } - protected void performPsiSpoilingRefactoring() { RenameUtil.renameNonCodeUsages(myProject, myNonCodeUsages); if (myMoveCallback != null) { diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesViewDescriptor.java b/platform/lang-impl/src/com/intellij/refactoring/move/MoveMultipleElementsViewDescriptor.java similarity index 58% rename from java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesViewDescriptor.java rename to platform/lang-impl/src/com/intellij/refactoring/move/MoveMultipleElementsViewDescriptor.java index cee788604434..441624c51020 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesViewDescriptor.java +++ b/platform/lang-impl/src/com/intellij/refactoring/move/MoveMultipleElementsViewDescriptor.java @@ -18,11 +18,9 @@ * created at Sep 17, 2001 * @author Jeka */ -package com.intellij.refactoring.move.moveClassesOrPackages; +package com.intellij.refactoring.move; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiElement; import com.intellij.refactoring.RefactoringBundle; import com.intellij.usageView.UsageViewBundle; @@ -30,36 +28,25 @@ import com.intellij.usageView.UsageViewDescriptor; import com.intellij.usageView.UsageViewUtil; import org.jetbrains.annotations.NotNull; -class MoveClassesOrPackagesViewDescriptor implements UsageViewDescriptor { +public class MoveMultipleElementsViewDescriptor implements UsageViewDescriptor { private final PsiElement[] myPsiElements; - private final boolean mySearchInComments; - private final boolean mySearchInNonJavaFiles; - private final String myNewParentPackageName; private String myProcessedElementsHeader; private final String myCodeReferencesText; - public MoveClassesOrPackagesViewDescriptor(PsiElement[] psiElements, - boolean isSearchInComments, - boolean searchInNonJavaFiles, - String targetName) { + public MoveMultipleElementsViewDescriptor(PsiElement[] psiElements, + String targetName) { myPsiElements = psiElements; - mySearchInComments = isSearchInComments; - mySearchInNonJavaFiles = searchInNonJavaFiles; - myNewParentPackageName = targetName; if (psiElements.length == 1) { myProcessedElementsHeader = StringUtil.capitalize( - RefactoringBundle.message("move.single.element.elements.header", UsageViewUtil.getType(psiElements[0]), myNewParentPackageName)); - myCodeReferencesText = RefactoringBundle.message("references.in.code.to.0.1", UsageViewUtil.getType(psiElements[0]), UsageViewUtil.getLongName(psiElements[0])); + RefactoringBundle.message("move.single.element.elements.header", UsageViewUtil.getType(psiElements[0]), targetName)); + myCodeReferencesText = RefactoringBundle + .message("references.in.code.to.0.1", UsageViewUtil.getType(psiElements[0]), UsageViewUtil.getLongName(psiElements[0])); } else { if (psiElements.length > 0) { - if (psiElements[0] instanceof PsiClass) { - myProcessedElementsHeader = StringUtil.capitalize(RefactoringBundle.message("move.classes.elements.header", myNewParentPackageName)); - } - else if (psiElements[0] instanceof PsiDirectory){ - myProcessedElementsHeader = - StringUtil.capitalize(RefactoringBundle.message("move.packages.elements.header", myNewParentPackageName)); - } + myProcessedElementsHeader = StringUtil.capitalize( + RefactoringBundle + .message("move.single.element.elements.header", StringUtil.pluralize(UsageViewUtil.getType(psiElements[0])), targetName)); } myCodeReferencesText = RefactoringBundle.message("references.found.in.code"); } diff --git a/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/CommonMoveUtil.java b/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/CommonMoveUtil.java new file mode 100644 index 000000000000..475c16c2f326 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/CommonMoveUtil.java @@ -0,0 +1,46 @@ +package com.intellij.refactoring.move.moveClassesOrPackages; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.intellij.refactoring.util.MoveRenameUsageInfo; +import com.intellij.refactoring.util.NonCodeUsageInfo; +import com.intellij.usageView.UsageInfo; +import com.intellij.util.IncorrectOperationException; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class CommonMoveUtil { + + private CommonMoveUtil() { + } + + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.move.moveClassesOrPackages.CommonMoveUtil"); + + public static NonCodeUsageInfo[] retargetUsages(final UsageInfo[] usages, final Map oldToNewElementsMapping) + throws IncorrectOperationException { + List nonCodeUsages = new ArrayList(); + for (UsageInfo usage : usages) { + if (usage instanceof NonCodeUsageInfo) { + nonCodeUsages.add((NonCodeUsageInfo)usage); + } + else if (usage instanceof MoveRenameUsageInfo) { + final MoveRenameUsageInfo moveRenameUsage = (MoveRenameUsageInfo)usage; + final PsiElement oldElement = moveRenameUsage.getReferencedElement(); + final PsiElement newElement = oldToNewElementsMapping.get(oldElement); + LOG.assertTrue(newElement != null); + final PsiReference reference = moveRenameUsage.getReference(); + if (reference != null) { + try { + reference.bindToElement(newElement); + } + catch (IncorrectOperationException e) {// + } + } + } + } + return nonCodeUsages.toArray(new NonCodeUsageInfo[nonCodeUsages.size()]); + } +} diff --git a/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesHelper.java b/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesHelper.java new file mode 100644 index 000000000000..5e488d8e2aab --- /dev/null +++ b/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesHelper.java @@ -0,0 +1,86 @@ +package com.intellij.refactoring.move.moveClassesOrPackages; + +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.refactoring.listeners.RefactoringElementListener; +import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFileHandler; +import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil; +import com.intellij.usageView.UsageInfo; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * @author ksafonov + */ +public abstract class MoveDirectoryWithClassesHelper { + private static final ExtensionPointName EP_NAME = + ExtensionPointName.create("com.intellij.refactoring.moveDirectoryWithClassesHelper"); + + public abstract void findUsages(Collection filesToMove, PsiDirectory[] directoriesToMove, Collection result, + boolean searchInComments, boolean searchInNonJavaFiles, Project project); + + public abstract boolean move(PsiFile file, + PsiDirectory moveDestination, + Map oldToNewElementsMapping, + List movedFiles, + RefactoringElementListener listener); + + public abstract void postProcessUsages(UsageInfo[] usages); + + public abstract void beforeMove(PsiFile psiFile); + + public abstract void afterMove(PsiElement newElement); + + public static MoveDirectoryWithClassesHelper[] findAll() { + return Extensions.getExtensions(EP_NAME); + } + + + public static class Default extends MoveDirectoryWithClassesHelper { + + @Override + public void findUsages(Collection filesToMove, PsiDirectory[] directoriesToMove, Collection result, + boolean searchInComments, boolean searchInNonJavaFiles, Project project) { + } + + @Override + public boolean move(PsiFile psiFile, + PsiDirectory moveDestination, + Map oldToNewElementsMapping, + List movedFiles, + RefactoringElementListener listener) { + if (moveDestination.equals(psiFile.getContainingDirectory())) { + return false; + } + + MoveFileHandler.forElement(psiFile).prepareMovedFile(psiFile, moveDestination, oldToNewElementsMapping); + + PsiFile moving = moveDestination.findFile(psiFile.getName()); + if (moving == null) { + MoveFilesOrDirectoriesUtil.doMoveFile(psiFile, moveDestination); + } + moving = moveDestination.findFile(psiFile.getName()); + movedFiles.add(moving); + listener.elementMoved(psiFile); + return true; + } + + @Override + public void postProcessUsages(UsageInfo[] usages) { + } + + @Override + public void beforeMove(PsiFile psiFile) { + } + + @Override + public void afterMove(PsiElement newElement) { + } + } +} diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java b/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java similarity index 73% rename from java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java rename to platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java index 36f119eec048..a2196e37234b 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java +++ b/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java @@ -21,22 +21,21 @@ package com.intellij.refactoring.move.moveClassesOrPackages; import com.intellij.CommonBundle; -import com.intellij.codeInsight.ChangeContextUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.VfsUtil; -import com.intellij.psi.*; -import com.intellij.psi.search.searches.ReferencesSearch; -import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiUtilBase; import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.listeners.RefactoringElementListener; import com.intellij.refactoring.move.FileReferenceContextUtil; import com.intellij.refactoring.move.MoveCallback; +import com.intellij.refactoring.move.MoveMultipleElementsViewDescriptor; import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFileHandler; -import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil; import com.intellij.refactoring.rename.RenameUtil; import com.intellij.refactoring.util.NonCodeUsageInfo; import com.intellij.refactoring.util.RefactoringUIUtil; @@ -69,7 +68,7 @@ public class MoveDirectoryWithClassesProcessor extends BaseRefactoringProcessor super(project); if (targetDirectory != null) { final List dirs = new ArrayList(Arrays.asList(directories)); - for (Iterator iterator = dirs.iterator(); iterator.hasNext();) { + for (Iterator iterator = dirs.iterator(); iterator.hasNext(); ) { final PsiDirectory directory = iterator.next(); if (targetDirectory.equals(directory.getParentDirectory()) || targetDirectory.equals(directory)) { iterator.remove(); @@ -88,12 +87,13 @@ public class MoveDirectoryWithClassesProcessor extends BaseRefactoringProcessor } } + @NotNull @Override protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) { PsiElement[] elements = new PsiElement[myFilesToMove.size()]; final PsiFile[] classes = PsiUtilBase.toPsiFileArray(myFilesToMove.keySet()); System.arraycopy(classes, 0, elements, 0, classes.length); - return new MoveClassesOrPackagesViewDescriptor(elements, false, false, getTargetName()); + return new MoveMultipleElementsViewDescriptor(elements, getTargetName()); } protected String getTargetName() { @@ -104,51 +104,12 @@ public class MoveDirectoryWithClassesProcessor extends BaseRefactoringProcessor @Override public UsageInfo[] findUsages() { final List usages = new ArrayList(); - final Set packageNames = new HashSet(); - for (PsiFile psiFile : myFilesToMove.keySet()) { - if (psiFile instanceof PsiClassOwner) { - final PsiClass[] classes = ((PsiClassOwner)psiFile).getClasses(); - for (PsiClass aClass : classes) { - Collections.addAll(usages, MoveClassesOrPackagesUtil.findUsages(aClass, mySearchInComments, mySearchInNonJavaFiles, aClass.getName())); - } - packageNames.add(((PsiClassOwner)psiFile).getPackageName()); - } - } - final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(myProject); - for (String packageName : packageNames) { - final PsiPackage aPackage = psiFacade.findPackage(packageName); - if (aPackage != null) { - boolean remainsNothing = true; - for (PsiDirectory packageDirectory : aPackage.getDirectories()) { - if (!isUnderRefactoring(packageDirectory)) { - remainsNothing = false; - break; - } - } - if (remainsNothing) { - for (PsiReference reference : ReferencesSearch.search(aPackage)) { - final PsiElement element = reference.getElement(); - final PsiImportStatementBase statementBase = PsiTreeUtil.getParentOfType(element, PsiImportStatementBase.class); - if (statementBase != null && statementBase.isOnDemand()) { - usages.add(new RemoveOnDemandImportStatementsUsageInfo(statementBase)); - } - } - } - } + for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) { + helper.findUsages(myFilesToMove.keySet(), myDirectories, usages, mySearchInComments, mySearchInNonJavaFiles, myProject); } return UsageViewUtil.removeDuplicatedUsages(usages.toArray(new UsageInfo[usages.size()])); } - private boolean isUnderRefactoring(PsiDirectory packageDirectory) { - for (PsiDirectory directory : myDirectories) { - if (PsiTreeUtil.isAncestor(directory, packageDirectory, true)) { - return true; - } - } - return false; - } - - @Override protected boolean preprocessUsages(Ref refUsages) { final MultiMap conflicts = new MultiMap(); @@ -189,31 +150,23 @@ public class MoveDirectoryWithClassesProcessor extends BaseRefactoringProcessor final List movedFiles = new ArrayList(); final Map oldToNewElementsMapping = new HashMap(); for (PsiFile psiFile : myFilesToMove.keySet()) { - ChangeContextUtil.encodeContextInfo(psiFile, true); + for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) { + helper.beforeMove(psiFile); + } final RefactoringElementListener listener = getTransaction().getElementListener(psiFile); final PsiDirectory moveDestination = myFilesToMove.get(psiFile).getTargetDirectory(); - if (psiFile instanceof PsiClassOwner) { - for (PsiClass psiClass : ((PsiClassOwner)psiFile).getClasses()) { - final PsiClass newClass = MoveClassesOrPackagesUtil.doMoveClass(psiClass, moveDestination); - oldToNewElementsMapping.put(psiClass, newClass); - listener.elementMoved(newClass); - } - } else { - if (!moveDestination.equals(psiFile.getContainingDirectory())) { - MoveFileHandler.forElement(psiFile).prepareMovedFile(psiFile, moveDestination, oldToNewElementsMapping); - PsiFile moving = moveDestination.findFile(psiFile.getName()); - if (moving == null) { - MoveFilesOrDirectoriesUtil.doMoveFile(psiFile, moveDestination); - } - moving = moveDestination.findFile(psiFile.getName()); - movedFiles.add(moving); - listener.elementMoved(psiFile); + for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) { + boolean processed = helper.move(psiFile, moveDestination, oldToNewElementsMapping, movedFiles, listener); + if (processed) { + break; } } } for (PsiElement newElement : oldToNewElementsMapping.values()) { - ChangeContextUtil.decodeContextInfo(newElement, null, null); + for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) { + helper.afterMove(newElement); + } } // fix references in moved files to outer files @@ -222,14 +175,9 @@ public class MoveDirectoryWithClassesProcessor extends BaseRefactoringProcessor FileReferenceContextUtil.decodeFileReferences(movedFile); } - myNonCodeUsages = MoveClassesOrPackagesProcessor.retargetUsages(usages, oldToNewElementsMapping); - for (UsageInfo usage : usages) { - if (usage instanceof RemoveOnDemandImportStatementsUsageInfo) { - final PsiElement element = usage.getElement(); - if (element != null) { - element.delete(); - } - } + myNonCodeUsages = CommonMoveUtil.retargetUsages(usages, oldToNewElementsMapping); + for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) { + helper.postProcessUsages(usages); } for (PsiDirectory directory : myDirectories) { directory.delete(); @@ -273,12 +221,6 @@ public class MoveDirectoryWithClassesProcessor extends BaseRefactoringProcessor return new TargetDirectoryWrapper(myTargetDirectory); } - private static class RemoveOnDemandImportStatementsUsageInfo extends UsageInfo { - public RemoveOnDemandImportStatementsUsageInfo(PsiImportStatementBase statementBase) { - super(statementBase); - } - } - public static class TargetDirectoryWrapper { private TargetDirectoryWrapper myParentDirectory; private PsiDirectory myTargetDirectory; diff --git a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml index 649ba91e14db..a5e6af8bae96 100644 --- a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml @@ -220,6 +220,7 @@ + diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index 483650698b32..20ae55754f8a 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -629,4 +629,6 @@ + + diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/move/MoveGroovyScriptProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/move/MoveGroovyScriptProcessor.java index 219789fc3754..5d6318a759be 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/move/MoveGroovyScriptProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/move/MoveGroovyScriptProcessor.java @@ -27,6 +27,7 @@ import com.intellij.refactoring.listeners.RefactoringElementListener; import com.intellij.refactoring.move.MoveCallback; import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesProcessor; import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesUtil; +import com.intellij.refactoring.move.moveClassesOrPackages.CommonMoveUtil; import com.intellij.refactoring.util.NonCodeUsageInfo; import com.intellij.refactoring.util.RefactoringUIUtil; import com.intellij.usageView.UsageInfo; @@ -128,7 +129,7 @@ public class MoveGroovyScriptProcessor extends MoveClassesOrPackagesProcessor { GroovyChangeContextUtil.decodeContextInfo(element, null, null); } - myNonCodeUsages = retargetUsages(usages, oldToNewElementsMapping); + myNonCodeUsages = CommonMoveUtil.retargetUsages(usages, oldToNewElementsMapping); } catch (IncorrectOperationException e) { myNonCodeUsages = new NonCodeUsageInfo[0]; diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 3e1eca7def3c..72bd8c784440 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -722,6 +722,8 @@ + +