From 85fb323064771f4558b6091a22f024c490beeb9f Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Mon, 21 Aug 2017 16:05:50 +0200 Subject: [PATCH] rename package: ensure move targets are not deleted (IDEA-177845) --- .../after/src1/pack1/pack2/S1.java | 3 +++ .../before/src1/pack1/pack2/pack2/S1.java | 3 +++ .../MovePackageAsDirectoryTest.java | 12 +++++++++ .../MoveDirectoryWithClassesProcessor.java | 27 ++++++++++++++++--- 4 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 java/java-tests/testData/refactoring/movePackageAsDir/renamePackageUp/after/src1/pack1/pack2/S1.java create mode 100644 java/java-tests/testData/refactoring/movePackageAsDir/renamePackageUp/before/src1/pack1/pack2/pack2/S1.java diff --git a/java/java-tests/testData/refactoring/movePackageAsDir/renamePackageUp/after/src1/pack1/pack2/S1.java b/java/java-tests/testData/refactoring/movePackageAsDir/renamePackageUp/after/src1/pack1/pack2/S1.java new file mode 100644 index 000000000000..42b3a8020e08 --- /dev/null +++ b/java/java-tests/testData/refactoring/movePackageAsDir/renamePackageUp/after/src1/pack1/pack2/S1.java @@ -0,0 +1,3 @@ +package pack1.pack2; + +public class S1{} diff --git a/java/java-tests/testData/refactoring/movePackageAsDir/renamePackageUp/before/src1/pack1/pack2/pack2/S1.java b/java/java-tests/testData/refactoring/movePackageAsDir/renamePackageUp/before/src1/pack1/pack2/pack2/S1.java new file mode 100644 index 000000000000..c0a5f31dbfba --- /dev/null +++ b/java/java-tests/testData/refactoring/movePackageAsDir/renamePackageUp/before/src1/pack1/pack2/pack2/S1.java @@ -0,0 +1,3 @@ +package pack1; + +public class S1{} diff --git a/java/java-tests/testSrc/com/intellij/java/refactoring/MovePackageAsDirectoryTest.java b/java/java-tests/testSrc/com/intellij/java/refactoring/MovePackageAsDirectoryTest.java index f1dd6cdb56e7..52f776372b30 100644 --- a/java/java-tests/testSrc/com/intellij/java/refactoring/MovePackageAsDirectoryTest.java +++ b/java/java-tests/testSrc/com/intellij/java/refactoring/MovePackageAsDirectoryTest.java @@ -64,6 +64,18 @@ public class MovePackageAsDirectoryTest extends MultiFileTestCase { doTest(action); } + public void testRenamePackageUp() { + final PerformAction action = (rootDir, rootAfter) -> { + final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(myProject); + final PsiPackage sourcePackage = psiFacade.findPackage("pack1.pack2"); + assertNotNull(sourcePackage); + + RenamePsiPackageProcessor.createRenameMoveProcessor("pack1", sourcePackage, false, false).run(); + FileDocumentManager.getInstance().saveAllDocuments(); + }; + doTest(action); + } + public void testRenamePackageStaticImportsToNestedClasses() { final PerformAction action = (rootDir, rootAfter) -> { final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(myProject); diff --git a/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java b/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java index 12d6799679df..069f8bb57311 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java +++ b/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java @@ -86,7 +86,7 @@ public class MoveDirectoryWithClassesProcessor extends BaseRefactoringProcessor mySearchInNonJavaFiles = searchInNonJavaFiles; myMoveCallback = moveCallback; myFilesToMove = new HashMap<>(); - myNestedDirsToMove = new HashMap<>(); + myNestedDirsToMove = new LinkedHashMap<>(); for (PsiDirectory dir : directories) { collectFiles2Move(myFilesToMove, myNestedDirsToMove, dir, includeSelf ? dir.getParentDirectory() : dir, getTargetDirectory(dir)); } @@ -195,12 +195,17 @@ public class MoveDirectoryWithClassesProcessor extends BaseRefactoringProcessor helper.postProcessUsages(usages, dir -> getResultDirectory(dir).findOrCreateTargetDirectory()); } for (PsiDirectory directory : myDirectories) { - final TargetDirectoryWrapper wrapper = myNestedDirsToMove.get(directory); - final PsiDirectory targetDirectory = wrapper.getTargetDirectory(); - if (targetDirectory == null || !PsiTreeUtil.isAncestor(directory, targetDirectory, false)) { + if (!isUsedInTarget(directory)) { directory.delete(); } } + + for (PsiDirectory directory : myNestedDirsToMove.keySet()) { + if (directory.isValid() && directory.getChildren().length == 0) { + directory.delete(); + } + } + } catch (IncorrectOperationException e) { myNonCodeUsages = new NonCodeUsageInfo[0]; @@ -208,6 +213,20 @@ public class MoveDirectoryWithClassesProcessor extends BaseRefactoringProcessor } } + private boolean isUsedInTarget(PsiDirectory directory) { + PsiDirectory targetDirectory = myNestedDirsToMove.get(directory).getTargetDirectory(); + //don't delete super directory if move was performed inside subpackage + if (targetDirectory != null && PsiTreeUtil.isAncestor(directory, targetDirectory, false)) { + return true; + } + //don't delete subdirectory: something could be moved in there + if (PsiTreeUtil.isAncestor(targetDirectory, directory, false)) { + return true; + } + + return false; + } + @Nullable @Override protected String getRefactoringId() {