From aba5ff0c1e984bf04c732935aaa7a21015ceef54 Mon Sep 17 00:00:00 2001 From: Igor Yakovlev Date: Tue, 19 Nov 2019 20:52:31 +0300 Subject: [PATCH] Fix copy refactoring for multiply kotlin files Fixed #KT-34971 --- .../copy/CopyKotlinDeclarationsHandler.kt | 15 ++++++++++----- .../after/bar/test.kt | 5 +++++ .../after/bar/test2.kt | 5 +++++ .../after/foo/test.kt | 5 +++++ .../after/foo/test2.kt | 5 +++++ .../before/foo/test.kt | 5 +++++ .../before/foo/test2.kt | 5 +++++ ...leFilesDifferentDirectoriesToNewDirectory.test | 6 ++++++ .../idea/refactoring/copy/AbstractCopyTest.kt | 9 ++++++++- .../idea/refactoring/copy/CopyTestGenerated.java | 5 +++++ 10 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/after/bar/test.kt create mode 100644 idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/after/bar/test2.kt create mode 100644 idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/after/foo/test.kt create mode 100644 idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/after/foo/test2.kt create mode 100644 idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/before/foo/test.kt create mode 100644 idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/before/foo/test2.kt create mode 100644 idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/copyMultipleFilesDifferentDirectoriesToNewDirectory.test diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationsHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationsHandler.kt index 4602bdb04b5..81dba8a6201 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationsHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationsHandler.kt @@ -68,7 +68,7 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() { private val copyFilesHandler by lazy { CopyFilesOrDirectoriesHandler() } - private fun getSourceFiles(elements: Array): Array? { + private fun getSourceFiles(elements: Array): Array? { return elements .map { it.containingFile ?: it as? PsiFileSystemItem ?: return null } .toTypedArray() @@ -243,7 +243,10 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() { } } - private fun trackedCopyFiles(sourceFiles: Array, initialTargetDirectory: PsiDirectory?): Set { + private fun trackedCopyFiles(sourceFiles: Array, initialTargetDirectory: PsiDirectory?): Set { + + if (!copyFilesHandler.canCopy(sourceFiles)) return emptySet() + val mapper = object : VirtualFileListener { val filesCopied = mutableSetOf() @@ -267,11 +270,11 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() { return mapper.filesCopied } - private fun doCopyFiles(filesToCopy: Array, initialTargetDirectory: PsiDirectory?) { + private fun doCopyFiles(filesToCopy: Array, initialTargetDirectory: PsiDirectory?) { if (filesToCopy.isEmpty()) return - val project = filesToCopy.first().project + val project = filesToCopy[0].project val psiManager = PsiManager.getInstance(project) project.executeCommand(commandName) { @@ -298,7 +301,9 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() { if (elements.isEmpty()) return if (!canCopyDeclarations(elements)) { - return doCopyFiles(elements, defaultTargetDirectory) + getSourceFiles(elements)?.let { + return doCopyFiles(it, defaultTargetDirectory) + } } val elementsToCopy = elements.mapNotNull { it.getCopyableElement() } diff --git a/idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/after/bar/test.kt b/idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/after/bar/test.kt new file mode 100644 index 00000000000..e30b31b39b1 --- /dev/null +++ b/idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/after/bar/test.kt @@ -0,0 +1,5 @@ +package bar + +class A { + val a: A = A() +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/after/bar/test2.kt b/idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/after/bar/test2.kt new file mode 100644 index 00000000000..e62c5217b0e --- /dev/null +++ b/idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/after/bar/test2.kt @@ -0,0 +1,5 @@ +package bar + +class B { + val b: B = B() +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/after/foo/test.kt b/idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/after/foo/test.kt new file mode 100644 index 00000000000..c2f32b2d8c3 --- /dev/null +++ b/idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/after/foo/test.kt @@ -0,0 +1,5 @@ +package foo + +class A { + val a: A = A() +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/after/foo/test2.kt b/idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/after/foo/test2.kt new file mode 100644 index 00000000000..a301d069c0d --- /dev/null +++ b/idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/after/foo/test2.kt @@ -0,0 +1,5 @@ +package boo + +class B { + val b: B = B() +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/before/foo/test.kt b/idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/before/foo/test.kt new file mode 100644 index 00000000000..c2f32b2d8c3 --- /dev/null +++ b/idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/before/foo/test.kt @@ -0,0 +1,5 @@ +package foo + +class A { + val a: A = A() +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/before/foo/test2.kt b/idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/before/foo/test2.kt new file mode 100644 index 00000000000..a301d069c0d --- /dev/null +++ b/idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/before/foo/test2.kt @@ -0,0 +1,5 @@ +package boo + +class B { + val b: B = B() +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/copyMultipleFilesDifferentDirectoriesToNewDirectory.test b/idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/copyMultipleFilesDifferentDirectoriesToNewDirectory.test new file mode 100644 index 00000000000..1b239ccb509 --- /dev/null +++ b/idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/copyMultipleFilesDifferentDirectoriesToNewDirectory.test @@ -0,0 +1,6 @@ +{ + "filesToMove": ["foo/test.kt", "foo/test2.kt"], + "extractClassOrObject": true, + "targetPackage": "bar", + "type": "COPY_FILES" +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/copy/AbstractCopyTest.kt b/idea/tests/org/jetbrains/kotlin/idea/refactoring/copy/AbstractCopyTest.kt index bc8b3cf43b1..d3eac6a73c5 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/copy/AbstractCopyTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/copy/AbstractCopyTest.kt @@ -10,6 +10,8 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile +import com.intellij.psi.util.PsiTreeUtil +import com.intellij.psi.util.PsiUtil import com.intellij.refactoring.PackageWrapper import com.intellij.refactoring.copy.CopyHandler import com.intellij.refactoring.move.moveClassesOrPackages.MultipleRootsMoveDestination @@ -21,6 +23,7 @@ import org.jetbrains.kotlin.idea.refactoring.AbstractMultifileRefactoringTest import org.jetbrains.kotlin.idea.refactoring.copy.CopyKotlinDeclarationsHandler.Companion.newName import org.jetbrains.kotlin.idea.refactoring.runRefactoringTest import org.jetbrains.kotlin.idea.util.application.runWriteAction +import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.utils.ifEmpty private enum class CopyAction : AbstractMultifileRefactoringTest.RefactoringAction { @@ -32,7 +35,11 @@ private enum class CopyAction : AbstractMultifileRefactoringTest.RefactoringActi if (virtualFile.isDirectory) virtualFile.toPsiDirectory(project)!! else virtualFile.toPsiFile(project)!! } - DEFAULT.runRefactoring(rootDir, mainFile, elementsToCopy, config) + val typesToCopy = if (config.getNullableString("extractClassOrObject") == "true") + elementsToCopy.flatMap { PsiTreeUtil.collectElementsOfType(it, KtClassOrObject::class.java) } + else elementsToCopy + + DEFAULT.runRefactoring(rootDir, mainFile, typesToCopy, config) } }, diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/copy/CopyTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/copy/CopyTestGenerated.java index 75a8c897ab0..65436a85c4b 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/copy/CopyTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/copy/CopyTestGenerated.java @@ -148,6 +148,11 @@ public class CopyTestGenerated extends AbstractCopyTest { runTest("idea/testData/refactoring/copy/copyMultipleFilesDifferentDirectoriesToNewDirectory/copyMultipleFilesDifferentDirectoriesToNewDirectory.test"); } + @TestMetadata("copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/copyMultipleFilesDifferentDirectoriesToNewDirectory.test") + public void testCopyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject_CopyMultipleFilesDifferentDirectoriesToNewDirectory() throws Exception { + runTest("idea/testData/refactoring/copy/copyMultipleFilesDirectoriesToNewDirectoryAsClassOrObject/copyMultipleFilesDifferentDirectoriesToNewDirectory.test"); + } + @TestMetadata("copyMultipleFilesToNewDirectory/copyMultipleFilesToNewDirectory.test") public void testCopyMultipleFilesToNewDirectory_CopyMultipleFilesToNewDirectory() throws Exception { runTest("idea/testData/refactoring/copy/copyMultipleFilesToNewDirectory/copyMultipleFilesToNewDirectory.test");