diff --git a/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java b/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java index dafbe4c54027..5f9dc3205b5b 100644 --- a/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java @@ -330,31 +330,23 @@ public class CopyClassesHandler extends CopyHandlerDelegateBase { return doCopyClasses(fileToClasses, null, copyClassName, targetDirectory, project); } - private static PsiDirectory getOrCreateRelativeDirectory(@NotNull PsiDirectory directory, @Nullable String relativePath) { - if (StringUtil.isNotEmpty(relativePath)) { - return WriteAction.compute(() -> buildRelativeDir(directory, relativePath).findOrCreateTargetDirectory()); - } else { - return directory; - } - } - private static List checkExistingFiles(@NotNull Collection files, @NotNull PsiDirectory directory, @Nullable Map relativePaths, @Nullable String className){ SkipOverwriteChoice choice = SkipOverwriteChoice.OVERWRITE; List filesToProcess = new ArrayList<>(); for (PsiFile file : files) { final String relativePath = relativePaths != null ? relativePaths.get(file) : null; - final PsiDirectory targetDirectory = relativePath != null ? buildRelativeDir(directory, relativePath).getTargetDirectory() : directory; + final PsiDirectory targetDirectory = buildRelativeDir(directory, relativePath).getTargetDirectory(); final String fileName = getNewFileName(file, className); - final boolean isExistingFile = targetDirectory != null && targetDirectory.findFile(fileName) != null; - if (isExistingFile) { + final PsiFile existingFile = targetDirectory != null ? targetDirectory.findFile(fileName) : null; + if (existingFile != null) { if (choice != SkipOverwriteChoice.SKIP_ALL && choice != SkipOverwriteChoice.OVERWRITE_ALL) { String message = ExecutionBundle.message("copy.classes.command.name"); choice = SkipOverwriteChoice.askUser(targetDirectory, fileName, message, files.size() > 1); } } - if (!isExistingFile || choice == SkipOverwriteChoice.OVERWRITE || choice == SkipOverwriteChoice.OVERWRITE_ALL) { - filesToProcess.add(file); + if (existingFile == null || choice == SkipOverwriteChoice.OVERWRITE || choice == SkipOverwriteChoice.OVERWRITE_ALL) { + if (existingFile != file) filesToProcess.add(file); } } return filesToProcess; @@ -405,7 +397,9 @@ public class CopyClassesHandler extends CopyHandlerDelegateBase { } final PsiClass[] sources = fileToClasses.get(psiFile); final String relativePath = fileToRelativePath != null ? fileToRelativePath.get(psiFile) : null; - final PsiDirectoryImpl directory = (PsiDirectoryImpl)getOrCreateRelativeDirectory(targetDirectory, relativePath); + final PsiDirectoryImpl directory = WriteAction.compute(() -> + (PsiDirectoryImpl) buildRelativeDir(targetDirectory, relativePath).findOrCreateTargetDirectory() + ); Ref createdFileReference = new Ref<>(); directory.executeWithUpdatingAddedFilesDisabled(() -> createdFileReference.set(copy(directory, psiFile, copyClassName))); final PsiFile createdFile = createdFileReference.get(); @@ -511,7 +505,8 @@ public class CopyClassesHandler extends CopyHandlerDelegateBase { @NotNull private static MoveDirectoryWithClassesProcessor.TargetDirectoryWrapper buildRelativeDir(final @NotNull PsiDirectory directory, - final @NotNull String relativePath) { + final @Nullable String relativePath) { + if (StringUtil.isEmpty(relativePath)) return new MoveDirectoryWithClassesProcessor.TargetDirectoryWrapper(directory); MoveDirectoryWithClassesProcessor.TargetDirectoryWrapper current = null; for (String pathElement : relativePath.split("/")) { if (current == null) { diff --git a/java/java-tests/testData/refactoring/copyClass/conflictInSameFolder/Foo.java b/java/java-tests/testData/refactoring/copyClass/conflictInSameFolder/Foo.java new file mode 100644 index 000000000000..68f63a94dd59 --- /dev/null +++ b/java/java-tests/testData/refactoring/copyClass/conflictInSameFolder/Foo.java @@ -0,0 +1,8 @@ +public class Foo { + public Foo(Foo f) { + } + + Foo> foos() { + return new Foo>(new Foo>(null)); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/refactoring/CopyClassTest.java b/java/java-tests/testSrc/com/intellij/java/refactoring/CopyClassTest.java index 6ec6d929ea6a..f1ff094b5f43 100644 --- a/java/java-tests/testSrc/com/intellij/java/refactoring/CopyClassTest.java +++ b/java/java-tests/testSrc/com/intellij/java/refactoring/CopyClassTest.java @@ -39,6 +39,10 @@ public class CopyClassTest extends LightMultiFileTestCase { doTest("Foo", "Bar"); } + public void testConflictInSameFolder() throws Exception { + assertThrows(RuntimeException.class, "already exist", () -> doTest("Foo", "Foo")); + } + public void testLibraryClass() throws Exception { // IDEADEV-28791 JavaCodeStyleSettings javaSettings = JavaCodeStyleSettings.getInstance(getProject()); javaSettings.CLASS_NAMES_IN_JAVADOC = JavaCodeStyleSettings.FULLY_QUALIFY_NAMES_ALWAYS;