From 1072495001c33a53b2aad67d8c9a5a9921312fb6 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 16 May 2017 12:57:28 +0300 Subject: [PATCH] Copy: Support top-level declarations --- idea/src/META-INF/plugin.xml | 2 +- ...alog.kt => CopyKotlinDeclarationDialog.kt} | 22 +++--- ...er.kt => CopyKotlinDeclarationsHandler.kt} | 69 +++++++++++-------- .../copy/copyLocalClass/after/bar/test.kt | 5 ++ .../copy/copyLocalClass/after/foo/test.kt | 5 ++ .../copy/copyLocalClass/before/foo/test.kt | 5 ++ .../copy/copyLocalClass/copyLocalClass.test | 4 ++ .../copy/copyLocalFunction/after/bar/a.kt | 8 +++ .../copy/copyLocalFunction/after/foo/test.kt | 8 +++ .../copy/copyLocalFunction/before/foo/test.kt | 8 +++ .../copyLocalFunction/copyLocalFunction.test | 4 ++ .../copy/copyLocalVariable/after/bar/a.kt | 5 ++ .../copy/copyLocalVariable/after/foo/test.kt | 5 ++ .../copy/copyLocalVariable/before/foo/test.kt | 5 ++ .../copyLocalVariable/copyLocalVariable.test | 4 ++ .../copy/copyMemberFunction/after/bar/A.kt | 11 +++ .../copy/copyMemberFunction/after/foo/test.kt | 11 +++ .../copyMemberFunction/before/foo/test.kt | 11 +++ .../copyMemberFunction.test | 4 ++ .../copy/copyMemberProperty/after/bar/A.kt | 6 ++ .../copy/copyMemberProperty/after/foo/test.kt | 6 ++ .../copyMemberProperty/before/foo/test.kt | 6 ++ .../copyMemberProperty.test | 4 ++ .../after/bar/test.kt | 26 +++++++ .../after/foo/test.kt | 33 +++++++++ .../before/foo/test.kt | 33 +++++++++ .../copyMultipleDeclarations.test | 4 ++ .../copy/copyTopLevelFunction/after/bar/a.kt | 8 +++ .../copyTopLevelFunction/after/foo/test.kt | 11 +++ .../copyTopLevelFunction/before/foo/test.kt | 11 +++ .../copyTopLevelFunction.test | 4 ++ .../after/bar/x.kt | 8 +++ .../after/foo/test.kt | 11 +++ .../before/foo/test.kt | 11 +++ .../copyTopLevelFunctionWithRename.test | 5 ++ .../copy/copyTopLevelProperty/after/bar/a.kt | 9 +++ .../copyTopLevelProperty/after/foo/test.kt | 12 ++++ .../copyTopLevelProperty/before/foo/test.kt | 12 ++++ .../copyTopLevelProperty.test | 4 ++ .../after/bar/x.kt | 9 +++ .../after/foo/test.kt | 12 ++++ .../before/foo/test.kt | 12 ++++ .../copyTopLevelPropertyWithRename.test | 5 ++ .../idea/refactoring/copy/AbstractCopyTest.kt | 2 +- .../refactoring/copy/CopyTestGenerated.java | 60 ++++++++++++++++ 45 files changed, 477 insertions(+), 43 deletions(-) rename idea/src/org/jetbrains/kotlin/idea/refactoring/copy/{CopyKotlinClassDialog.kt => CopyKotlinDeclarationDialog.kt} (91%) rename idea/src/org/jetbrains/kotlin/idea/refactoring/copy/{CopyKotlinClassesHandler.kt => CopyKotlinDeclarationsHandler.kt} (75%) create mode 100644 idea/testData/refactoring/copy/copyLocalClass/after/bar/test.kt create mode 100644 idea/testData/refactoring/copy/copyLocalClass/after/foo/test.kt create mode 100644 idea/testData/refactoring/copy/copyLocalClass/before/foo/test.kt create mode 100644 idea/testData/refactoring/copy/copyLocalClass/copyLocalClass.test create mode 100644 idea/testData/refactoring/copy/copyLocalFunction/after/bar/a.kt create mode 100644 idea/testData/refactoring/copy/copyLocalFunction/after/foo/test.kt create mode 100644 idea/testData/refactoring/copy/copyLocalFunction/before/foo/test.kt create mode 100644 idea/testData/refactoring/copy/copyLocalFunction/copyLocalFunction.test create mode 100644 idea/testData/refactoring/copy/copyLocalVariable/after/bar/a.kt create mode 100644 idea/testData/refactoring/copy/copyLocalVariable/after/foo/test.kt create mode 100644 idea/testData/refactoring/copy/copyLocalVariable/before/foo/test.kt create mode 100644 idea/testData/refactoring/copy/copyLocalVariable/copyLocalVariable.test create mode 100644 idea/testData/refactoring/copy/copyMemberFunction/after/bar/A.kt create mode 100644 idea/testData/refactoring/copy/copyMemberFunction/after/foo/test.kt create mode 100644 idea/testData/refactoring/copy/copyMemberFunction/before/foo/test.kt create mode 100644 idea/testData/refactoring/copy/copyMemberFunction/copyMemberFunction.test create mode 100644 idea/testData/refactoring/copy/copyMemberProperty/after/bar/A.kt create mode 100644 idea/testData/refactoring/copy/copyMemberProperty/after/foo/test.kt create mode 100644 idea/testData/refactoring/copy/copyMemberProperty/before/foo/test.kt create mode 100644 idea/testData/refactoring/copy/copyMemberProperty/copyMemberProperty.test create mode 100644 idea/testData/refactoring/copy/copyMultipleDeclarations/after/bar/test.kt create mode 100644 idea/testData/refactoring/copy/copyMultipleDeclarations/after/foo/test.kt create mode 100644 idea/testData/refactoring/copy/copyMultipleDeclarations/before/foo/test.kt create mode 100644 idea/testData/refactoring/copy/copyMultipleDeclarations/copyMultipleDeclarations.test create mode 100644 idea/testData/refactoring/copy/copyTopLevelFunction/after/bar/a.kt create mode 100644 idea/testData/refactoring/copy/copyTopLevelFunction/after/foo/test.kt create mode 100644 idea/testData/refactoring/copy/copyTopLevelFunction/before/foo/test.kt create mode 100644 idea/testData/refactoring/copy/copyTopLevelFunction/copyTopLevelFunction.test create mode 100644 idea/testData/refactoring/copy/copyTopLevelFunctionWithRename/after/bar/x.kt create mode 100644 idea/testData/refactoring/copy/copyTopLevelFunctionWithRename/after/foo/test.kt create mode 100644 idea/testData/refactoring/copy/copyTopLevelFunctionWithRename/before/foo/test.kt create mode 100644 idea/testData/refactoring/copy/copyTopLevelFunctionWithRename/copyTopLevelFunctionWithRename.test create mode 100644 idea/testData/refactoring/copy/copyTopLevelProperty/after/bar/a.kt create mode 100644 idea/testData/refactoring/copy/copyTopLevelProperty/after/foo/test.kt create mode 100644 idea/testData/refactoring/copy/copyTopLevelProperty/before/foo/test.kt create mode 100644 idea/testData/refactoring/copy/copyTopLevelProperty/copyTopLevelProperty.test create mode 100644 idea/testData/refactoring/copy/copyTopLevelPropertyWithRename/after/bar/x.kt create mode 100644 idea/testData/refactoring/copy/copyTopLevelPropertyWithRename/after/foo/test.kt create mode 100644 idea/testData/refactoring/copy/copyTopLevelPropertyWithRename/before/foo/test.kt create mode 100644 idea/testData/refactoring/copy/copyTopLevelPropertyWithRename/copyTopLevelPropertyWithRename.test diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 8610d5ed7c2..51c6f132827 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -398,7 +398,7 @@ language="kotlin" /> { - val classOrFile = parentsWithSelf.firstOrNull { it is KtFile || (it is KtClassOrObject && it.isTopLevel()) } - return when (classOrFile) { - is KtFile -> classOrFile.declarations.filterIsInstance() - is KtClassOrObject -> listOf(classOrFile) + private fun PsiElement.getElementsToCopy(): List { + val declarationOrFile = parentsWithSelf.firstOrNull { it is KtFile || (it is KtNamedDeclaration && it.parent is KtFile) } + return when (declarationOrFile) { + is KtFile -> declarationOrFile.declarations.filterIsInstance().ifEmpty { listOf(declarationOrFile) } + is KtNamedDeclaration -> listOf(declarationOrFile) else -> emptyList() } } } override fun canCopy(elements: Array, fromUpdate: Boolean): Boolean { - return elements.flatMap { it.getTopLevelClasses().ifEmpty { return false } }.distinctBy { it.containingFile }.size == 1 + return elements.flatMap { it.getElementsToCopy().ifEmpty { return false } }.distinctBy { it.containingFile }.size == 1 } enum class ExistingFilePolicy { @@ -135,32 +137,32 @@ class CopyKotlinClassesHandler : CopyHandlerDelegateBase() { } override fun doCopy(elements: Array, defaultTargetDirectory: PsiDirectory?) { - val classesToCopy = elements.flatMap { it.getTopLevelClasses() } - if (classesToCopy.isEmpty()) return + val elementsToCopy = elements.flatMap { it.getElementsToCopy() } + if (elementsToCopy.isEmpty()) return - val singleClassToCopy = classesToCopy.singleOrNull() + val singleElementToCopy = elementsToCopy.singleOrNull() - val originalFile = classesToCopy.first().containingKtFile + val originalFile = elementsToCopy.first().containingFile as KtFile val initialTargetDirectory = defaultTargetDirectory ?: originalFile.containingDirectory ?: return val project = initialTargetDirectory.project if (ProjectRootManager.getInstance(project).fileIndex.getSourceRootForFile(initialTargetDirectory.virtualFile) == null) return - val commandName = RefactoringBundle.message("copy.handler.copy.class") + val commandName = "Copy Declarations" var openInEditor = false - var newName: String? = singleClassToCopy?.name ?: originalFile.name + var newName: String? = singleElementToCopy?.name ?: originalFile.name var targetDirWrapper: AutocreatingPsiDirectoryWrapper = initialTargetDirectory.toDirectoryWrapper() if (!ApplicationManager.getApplication().isUnitTestMode) { - if (singleClassToCopy != null) { - val dialog = CopyKotlinClassDialog(singleClassToCopy, initialTargetDirectory, project) + if (singleElementToCopy != null && singleElementToCopy is KtNamedDeclaration) { + val dialog = CopyKotlinDeclarationDialog(singleElementToCopy, initialTargetDirectory, project) dialog.title = commandName if (!dialog.showAndGet()) return openInEditor = dialog.openInEditor - newName = dialog.className ?: singleClassToCopy.name + newName = dialog.newName ?: singleElementToCopy.name targetDirWrapper = dialog.targetDirectory?.toDirectoryWrapper() ?: return } else { @@ -175,7 +177,7 @@ class CopyKotlinClassesHandler : CopyHandlerDelegateBase() { project.newName?.let { newName = it } } - if (singleClassToCopy != null && newName.isNullOrEmpty()) return + if (singleElementToCopy != null && newName.isNullOrEmpty()) return val internalUsages = runReadAction { val targetPackageName = targetDirWrapper.getPackageName() @@ -183,10 +185,10 @@ class CopyKotlinClassesHandler : CopyHandlerDelegateBase() { ContainerInfo.Package(originalFile.packageFqName), ContainerInfo.Package(FqName(targetPackageName)) ) - classesToCopy.flatMap { classToCopy -> - classToCopy.getInternalReferencesToUpdateOnPackageNameChange(changeInfo).filter { + elementsToCopy.flatMap { elementToCopy -> + (elementToCopy as KtElement).getInternalReferencesToUpdateOnPackageNameChange(changeInfo).filter { val referencedElement = (it as? MoveRenameUsageInfo)?.referencedElement - referencedElement == null || !classToCopy.isAncestor(referencedElement) + referencedElement == null || !elementToCopy.isAncestor(referencedElement) } } } @@ -199,23 +201,30 @@ class CopyKotlinClassesHandler : CopyHandlerDelegateBase() { val targetDirectory = runWriteAction { targetDirWrapper.getOrCreateDirectory(initialTargetDirectory) } val targetFileName = if (newName?.contains(".") ?: false) newName!! else newName + "." + originalFile.virtualFile.extension - val targetFile = getOrCreateTargetFile(originalFile, targetDirectory, targetFileName, commandName) ?: return@executeCommand + val oldToNewElementsMapping = HashMap() - val newClasses = runWriteAction { - val newClasses = classesToCopy.map { targetFile.add(it.copy()) as KtClassOrObject } - val oldToNewElementsMapping = classesToCopy.zip(newClasses).toMap() + val targetFile: KtFile + if (singleElementToCopy is KtFile) { + targetFile = runWriteAction { targetDirectory.copyFileFrom(targetFileName, singleElementToCopy) as KtFile } + } + else { + targetFile = getOrCreateTargetFile(originalFile, targetDirectory, targetFileName, commandName) ?: return@executeCommand + runWriteAction { + val newElements = elementsToCopy.map { targetFile.add(it.copy()) as KtNamedDeclaration } + elementsToCopy.zip(newElements).toMap(oldToNewElementsMapping) + } + } - for (newClass in newClasses) { - restoredInternalUsages += restoreInternalUsages(newClass, oldToNewElementsMapping, true) + runWriteAction { + for (newElement in oldToNewElementsMapping.values) { + restoredInternalUsages += restoreInternalUsages(newElement as KtElement, oldToNewElementsMapping, true) postProcessMoveUsages(restoredInternalUsages, oldToNewElementsMapping) } performDelayedRefactoringRequests(project) - - newClasses } - newClasses.singleOrNull()?.let { + oldToNewElementsMapping.values.singleOrNull()?.let { RenameProcessor(project, it, newName!!.quoteIfNeeded(), false, false).run() } diff --git a/idea/testData/refactoring/copy/copyLocalClass/after/bar/test.kt b/idea/testData/refactoring/copy/copyLocalClass/after/bar/test.kt new file mode 100644 index 00000000000..bc2a7fd49a1 --- /dev/null +++ b/idea/testData/refactoring/copy/copyLocalClass/after/bar/test.kt @@ -0,0 +1,5 @@ +package bar + +fun test() { + class A +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyLocalClass/after/foo/test.kt b/idea/testData/refactoring/copy/copyLocalClass/after/foo/test.kt new file mode 100644 index 00000000000..ca3624e9011 --- /dev/null +++ b/idea/testData/refactoring/copy/copyLocalClass/after/foo/test.kt @@ -0,0 +1,5 @@ +package foo + +fun test() { + class A +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyLocalClass/before/foo/test.kt b/idea/testData/refactoring/copy/copyLocalClass/before/foo/test.kt new file mode 100644 index 00000000000..314c10f1989 --- /dev/null +++ b/idea/testData/refactoring/copy/copyLocalClass/before/foo/test.kt @@ -0,0 +1,5 @@ +package foo + +fun test() { + class A +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyLocalClass/copyLocalClass.test b/idea/testData/refactoring/copy/copyLocalClass/copyLocalClass.test new file mode 100644 index 00000000000..f169eabdfa3 --- /dev/null +++ b/idea/testData/refactoring/copy/copyLocalClass/copyLocalClass.test @@ -0,0 +1,4 @@ +{ + "mainFile": "foo/test.kt", + "targetPackage": "bar" +} diff --git a/idea/testData/refactoring/copy/copyLocalFunction/after/bar/a.kt b/idea/testData/refactoring/copy/copyLocalFunction/after/bar/a.kt new file mode 100644 index 00000000000..b464840c6d6 --- /dev/null +++ b/idea/testData/refactoring/copy/copyLocalFunction/after/bar/a.kt @@ -0,0 +1,8 @@ +package bar + +fun a() { + fun b() { + + } + b() +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyLocalFunction/after/foo/test.kt b/idea/testData/refactoring/copy/copyLocalFunction/after/foo/test.kt new file mode 100644 index 00000000000..bb59d9ed055 --- /dev/null +++ b/idea/testData/refactoring/copy/copyLocalFunction/after/foo/test.kt @@ -0,0 +1,8 @@ +package foo + +fun a() { + fun b() { + + } + b() +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyLocalFunction/before/foo/test.kt b/idea/testData/refactoring/copy/copyLocalFunction/before/foo/test.kt new file mode 100644 index 00000000000..e677aef2109 --- /dev/null +++ b/idea/testData/refactoring/copy/copyLocalFunction/before/foo/test.kt @@ -0,0 +1,8 @@ +package foo + +fun a() { + fun b() { + + } + b() +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyLocalFunction/copyLocalFunction.test b/idea/testData/refactoring/copy/copyLocalFunction/copyLocalFunction.test new file mode 100644 index 00000000000..f169eabdfa3 --- /dev/null +++ b/idea/testData/refactoring/copy/copyLocalFunction/copyLocalFunction.test @@ -0,0 +1,4 @@ +{ + "mainFile": "foo/test.kt", + "targetPackage": "bar" +} diff --git a/idea/testData/refactoring/copy/copyLocalVariable/after/bar/a.kt b/idea/testData/refactoring/copy/copyLocalVariable/after/bar/a.kt new file mode 100644 index 00000000000..74abda87ba0 --- /dev/null +++ b/idea/testData/refactoring/copy/copyLocalVariable/after/bar/a.kt @@ -0,0 +1,5 @@ +package bar + +fun a() { + val x = 1 +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyLocalVariable/after/foo/test.kt b/idea/testData/refactoring/copy/copyLocalVariable/after/foo/test.kt new file mode 100644 index 00000000000..2e22c03db2c --- /dev/null +++ b/idea/testData/refactoring/copy/copyLocalVariable/after/foo/test.kt @@ -0,0 +1,5 @@ +package foo + +fun a() { + val x = 1 +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyLocalVariable/before/foo/test.kt b/idea/testData/refactoring/copy/copyLocalVariable/before/foo/test.kt new file mode 100644 index 00000000000..5455b8df736 --- /dev/null +++ b/idea/testData/refactoring/copy/copyLocalVariable/before/foo/test.kt @@ -0,0 +1,5 @@ +package foo + +fun a() { + val x = 1 +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyLocalVariable/copyLocalVariable.test b/idea/testData/refactoring/copy/copyLocalVariable/copyLocalVariable.test new file mode 100644 index 00000000000..f169eabdfa3 --- /dev/null +++ b/idea/testData/refactoring/copy/copyLocalVariable/copyLocalVariable.test @@ -0,0 +1,4 @@ +{ + "mainFile": "foo/test.kt", + "targetPackage": "bar" +} diff --git a/idea/testData/refactoring/copy/copyMemberFunction/after/bar/A.kt b/idea/testData/refactoring/copy/copyMemberFunction/after/bar/A.kt new file mode 100644 index 00000000000..6c2f076789e --- /dev/null +++ b/idea/testData/refactoring/copy/copyMemberFunction/after/bar/A.kt @@ -0,0 +1,11 @@ +package bar + +class A { + fun b() { + + } + + init { + b() + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyMemberFunction/after/foo/test.kt b/idea/testData/refactoring/copy/copyMemberFunction/after/foo/test.kt new file mode 100644 index 00000000000..080557a48d5 --- /dev/null +++ b/idea/testData/refactoring/copy/copyMemberFunction/after/foo/test.kt @@ -0,0 +1,11 @@ +package foo + +class A { + fun b() { + + } + + init { + b() + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyMemberFunction/before/foo/test.kt b/idea/testData/refactoring/copy/copyMemberFunction/before/foo/test.kt new file mode 100644 index 00000000000..30c6a6d413d --- /dev/null +++ b/idea/testData/refactoring/copy/copyMemberFunction/before/foo/test.kt @@ -0,0 +1,11 @@ +package foo + +class A { + fun b() { + + } + + init { + b() + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyMemberFunction/copyMemberFunction.test b/idea/testData/refactoring/copy/copyMemberFunction/copyMemberFunction.test new file mode 100644 index 00000000000..f169eabdfa3 --- /dev/null +++ b/idea/testData/refactoring/copy/copyMemberFunction/copyMemberFunction.test @@ -0,0 +1,4 @@ +{ + "mainFile": "foo/test.kt", + "targetPackage": "bar" +} diff --git a/idea/testData/refactoring/copy/copyMemberProperty/after/bar/A.kt b/idea/testData/refactoring/copy/copyMemberProperty/after/bar/A.kt new file mode 100644 index 00000000000..f8693b7099c --- /dev/null +++ b/idea/testData/refactoring/copy/copyMemberProperty/after/bar/A.kt @@ -0,0 +1,6 @@ +package bar + +class A { + val x = 1 + val y = x +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyMemberProperty/after/foo/test.kt b/idea/testData/refactoring/copy/copyMemberProperty/after/foo/test.kt new file mode 100644 index 00000000000..139870c0da0 --- /dev/null +++ b/idea/testData/refactoring/copy/copyMemberProperty/after/foo/test.kt @@ -0,0 +1,6 @@ +package foo + +class A { + val x = 1 + val y = x +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyMemberProperty/before/foo/test.kt b/idea/testData/refactoring/copy/copyMemberProperty/before/foo/test.kt new file mode 100644 index 00000000000..d345b7ca888 --- /dev/null +++ b/idea/testData/refactoring/copy/copyMemberProperty/before/foo/test.kt @@ -0,0 +1,6 @@ +package foo + +class A { + val x = 1 + val y = x +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyMemberProperty/copyMemberProperty.test b/idea/testData/refactoring/copy/copyMemberProperty/copyMemberProperty.test new file mode 100644 index 00000000000..f169eabdfa3 --- /dev/null +++ b/idea/testData/refactoring/copy/copyMemberProperty/copyMemberProperty.test @@ -0,0 +1,4 @@ +{ + "mainFile": "foo/test.kt", + "targetPackage": "bar" +} diff --git a/idea/testData/refactoring/copy/copyMultipleDeclarations/after/bar/test.kt b/idea/testData/refactoring/copy/copyMultipleDeclarations/after/bar/test.kt new file mode 100644 index 00000000000..9a54de642ac --- /dev/null +++ b/idea/testData/refactoring/copy/copyMultipleDeclarations/after/bar/test.kt @@ -0,0 +1,26 @@ +package bar + +import foo.X + +class A { + init { + val a: A = A() + val x: X = X() + b() + c + } +} + +fun b() { + val a: A = A() + val x: X = X() + b() + c +} + +val c: Int get() { + val a: A = A() + val x: X = X() + b() + c +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyMultipleDeclarations/after/foo/test.kt b/idea/testData/refactoring/copy/copyMultipleDeclarations/after/foo/test.kt new file mode 100644 index 00000000000..ed2bf96d25d --- /dev/null +++ b/idea/testData/refactoring/copy/copyMultipleDeclarations/after/foo/test.kt @@ -0,0 +1,33 @@ +package foo + +class A { + init { + val a: A = A() + val x: X = X() + b() + c + } +} + +class X { + init { + val a: A = A() + val x: X = X() + b() + c + } +} + +fun b() { + val a: A = A() + val x: X = X() + b() + c +} + +val c: Int get() { + val a: A = A() + val x: X = X() + b() + c +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyMultipleDeclarations/before/foo/test.kt b/idea/testData/refactoring/copy/copyMultipleDeclarations/before/foo/test.kt new file mode 100644 index 00000000000..395f7279eb0 --- /dev/null +++ b/idea/testData/refactoring/copy/copyMultipleDeclarations/before/foo/test.kt @@ -0,0 +1,33 @@ +package foo + +class A { + init { + val a: A = A() + val x: X = X() + b() + c + } +} + +class X { + init { + val a: A = A() + val x: X = X() + b() + c + } +} + +fun b() { + val a: A = A() + val x: X = X() + b() + c +} + +val c: Int get() { + val a: A = A() + val x: X = X() + b() + c +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyMultipleDeclarations/copyMultipleDeclarations.test b/idea/testData/refactoring/copy/copyMultipleDeclarations/copyMultipleDeclarations.test new file mode 100644 index 00000000000..f169eabdfa3 --- /dev/null +++ b/idea/testData/refactoring/copy/copyMultipleDeclarations/copyMultipleDeclarations.test @@ -0,0 +1,4 @@ +{ + "mainFile": "foo/test.kt", + "targetPackage": "bar" +} diff --git a/idea/testData/refactoring/copy/copyTopLevelFunction/after/bar/a.kt b/idea/testData/refactoring/copy/copyTopLevelFunction/after/bar/a.kt new file mode 100644 index 00000000000..16b0d79fe61 --- /dev/null +++ b/idea/testData/refactoring/copy/copyTopLevelFunction/after/bar/a.kt @@ -0,0 +1,8 @@ +package bar + +import foo.B + +fun a() { + a() + val b: B = B() +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyTopLevelFunction/after/foo/test.kt b/idea/testData/refactoring/copy/copyTopLevelFunction/after/foo/test.kt new file mode 100644 index 00000000000..22edcf7bdb0 --- /dev/null +++ b/idea/testData/refactoring/copy/copyTopLevelFunction/after/foo/test.kt @@ -0,0 +1,11 @@ +package foo + +fun a() { + a() + val b: B = B() +} + +class B { + val a: A = A() + val b: B = B() +} diff --git a/idea/testData/refactoring/copy/copyTopLevelFunction/before/foo/test.kt b/idea/testData/refactoring/copy/copyTopLevelFunction/before/foo/test.kt new file mode 100644 index 00000000000..d411a4eb614 --- /dev/null +++ b/idea/testData/refactoring/copy/copyTopLevelFunction/before/foo/test.kt @@ -0,0 +1,11 @@ +package foo + +fun a() { + a() + val b: B = B() +} + +class B { + val a: A = A() + val b: B = B() +} diff --git a/idea/testData/refactoring/copy/copyTopLevelFunction/copyTopLevelFunction.test b/idea/testData/refactoring/copy/copyTopLevelFunction/copyTopLevelFunction.test new file mode 100644 index 00000000000..f169eabdfa3 --- /dev/null +++ b/idea/testData/refactoring/copy/copyTopLevelFunction/copyTopLevelFunction.test @@ -0,0 +1,4 @@ +{ + "mainFile": "foo/test.kt", + "targetPackage": "bar" +} diff --git a/idea/testData/refactoring/copy/copyTopLevelFunctionWithRename/after/bar/x.kt b/idea/testData/refactoring/copy/copyTopLevelFunctionWithRename/after/bar/x.kt new file mode 100644 index 00000000000..ee021519f93 --- /dev/null +++ b/idea/testData/refactoring/copy/copyTopLevelFunctionWithRename/after/bar/x.kt @@ -0,0 +1,8 @@ +package bar + +import foo.B + +fun x() { + x() + val b: B = B() +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyTopLevelFunctionWithRename/after/foo/test.kt b/idea/testData/refactoring/copy/copyTopLevelFunctionWithRename/after/foo/test.kt new file mode 100644 index 00000000000..22edcf7bdb0 --- /dev/null +++ b/idea/testData/refactoring/copy/copyTopLevelFunctionWithRename/after/foo/test.kt @@ -0,0 +1,11 @@ +package foo + +fun a() { + a() + val b: B = B() +} + +class B { + val a: A = A() + val b: B = B() +} diff --git a/idea/testData/refactoring/copy/copyTopLevelFunctionWithRename/before/foo/test.kt b/idea/testData/refactoring/copy/copyTopLevelFunctionWithRename/before/foo/test.kt new file mode 100644 index 00000000000..d411a4eb614 --- /dev/null +++ b/idea/testData/refactoring/copy/copyTopLevelFunctionWithRename/before/foo/test.kt @@ -0,0 +1,11 @@ +package foo + +fun a() { + a() + val b: B = B() +} + +class B { + val a: A = A() + val b: B = B() +} diff --git a/idea/testData/refactoring/copy/copyTopLevelFunctionWithRename/copyTopLevelFunctionWithRename.test b/idea/testData/refactoring/copy/copyTopLevelFunctionWithRename/copyTopLevelFunctionWithRename.test new file mode 100644 index 00000000000..7070ad015a0 --- /dev/null +++ b/idea/testData/refactoring/copy/copyTopLevelFunctionWithRename/copyTopLevelFunctionWithRename.test @@ -0,0 +1,5 @@ +{ + "mainFile": "foo/test.kt", + "targetPackage": "bar", + "newName": "x" +} diff --git a/idea/testData/refactoring/copy/copyTopLevelProperty/after/bar/a.kt b/idea/testData/refactoring/copy/copyTopLevelProperty/after/bar/a.kt new file mode 100644 index 00000000000..0d67f047540 --- /dev/null +++ b/idea/testData/refactoring/copy/copyTopLevelProperty/after/bar/a.kt @@ -0,0 +1,9 @@ +package bar + +import foo.B + +val a: Int get() { + a + val b: B = B() + return 0 +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyTopLevelProperty/after/foo/test.kt b/idea/testData/refactoring/copy/copyTopLevelProperty/after/foo/test.kt new file mode 100644 index 00000000000..45273bb6ddc --- /dev/null +++ b/idea/testData/refactoring/copy/copyTopLevelProperty/after/foo/test.kt @@ -0,0 +1,12 @@ +package foo + +val a: Int get() { + a + val b: B = B() + return 0 +} + +class B { + val a: A = A() + val b: B = B() +} diff --git a/idea/testData/refactoring/copy/copyTopLevelProperty/before/foo/test.kt b/idea/testData/refactoring/copy/copyTopLevelProperty/before/foo/test.kt new file mode 100644 index 00000000000..d0a86aea548 --- /dev/null +++ b/idea/testData/refactoring/copy/copyTopLevelProperty/before/foo/test.kt @@ -0,0 +1,12 @@ +package foo + +val a: Int get() { + a + val b: B = B() + return 0 +} + +class B { + val a: A = A() + val b: B = B() +} diff --git a/idea/testData/refactoring/copy/copyTopLevelProperty/copyTopLevelProperty.test b/idea/testData/refactoring/copy/copyTopLevelProperty/copyTopLevelProperty.test new file mode 100644 index 00000000000..f169eabdfa3 --- /dev/null +++ b/idea/testData/refactoring/copy/copyTopLevelProperty/copyTopLevelProperty.test @@ -0,0 +1,4 @@ +{ + "mainFile": "foo/test.kt", + "targetPackage": "bar" +} diff --git a/idea/testData/refactoring/copy/copyTopLevelPropertyWithRename/after/bar/x.kt b/idea/testData/refactoring/copy/copyTopLevelPropertyWithRename/after/bar/x.kt new file mode 100644 index 00000000000..4d69e92059a --- /dev/null +++ b/idea/testData/refactoring/copy/copyTopLevelPropertyWithRename/after/bar/x.kt @@ -0,0 +1,9 @@ +package bar + +import foo.B + +val x: Int get() { + x + val b: B = B() + return 0 +} \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyTopLevelPropertyWithRename/after/foo/test.kt b/idea/testData/refactoring/copy/copyTopLevelPropertyWithRename/after/foo/test.kt new file mode 100644 index 00000000000..45273bb6ddc --- /dev/null +++ b/idea/testData/refactoring/copy/copyTopLevelPropertyWithRename/after/foo/test.kt @@ -0,0 +1,12 @@ +package foo + +val a: Int get() { + a + val b: B = B() + return 0 +} + +class B { + val a: A = A() + val b: B = B() +} diff --git a/idea/testData/refactoring/copy/copyTopLevelPropertyWithRename/before/foo/test.kt b/idea/testData/refactoring/copy/copyTopLevelPropertyWithRename/before/foo/test.kt new file mode 100644 index 00000000000..d0a86aea548 --- /dev/null +++ b/idea/testData/refactoring/copy/copyTopLevelPropertyWithRename/before/foo/test.kt @@ -0,0 +1,12 @@ +package foo + +val a: Int get() { + a + val b: B = B() + return 0 +} + +class B { + val a: A = A() + val b: B = B() +} diff --git a/idea/testData/refactoring/copy/copyTopLevelPropertyWithRename/copyTopLevelPropertyWithRename.test b/idea/testData/refactoring/copy/copyTopLevelPropertyWithRename/copyTopLevelPropertyWithRename.test new file mode 100644 index 00000000000..7070ad015a0 --- /dev/null +++ b/idea/testData/refactoring/copy/copyTopLevelPropertyWithRename/copyTopLevelPropertyWithRename.test @@ -0,0 +1,5 @@ +{ + "mainFile": "foo/test.kt", + "targetPackage": "bar", + "newName": "x" +} 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 9893fa35f96..aedd59ed752 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/copy/AbstractCopyTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/copy/AbstractCopyTest.kt @@ -27,7 +27,7 @@ import com.intellij.refactoring.move.moveClassesOrPackages.MultipleRootsMoveDest import org.jetbrains.kotlin.idea.jsonUtils.getNullableString import org.jetbrains.kotlin.idea.jsonUtils.getString import org.jetbrains.kotlin.idea.refactoring.AbstractMultifileRefactoringTest -import org.jetbrains.kotlin.idea.refactoring.copy.CopyKotlinClassesHandler.Companion.newName +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.utils.ifEmpty 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 215a778b97d..5470a54df17 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/copy/CopyTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/copy/CopyTestGenerated.java @@ -66,6 +66,36 @@ public class CopyTestGenerated extends AbstractCopyTest { doTest(fileName); } + @TestMetadata("copyLocalClass/copyLocalClass.test") + public void testCopyLocalClass_CopyLocalClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copy/copyLocalClass/copyLocalClass.test"); + doTest(fileName); + } + + @TestMetadata("copyLocalFunction/copyLocalFunction.test") + public void testCopyLocalFunction_CopyLocalFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copy/copyLocalFunction/copyLocalFunction.test"); + doTest(fileName); + } + + @TestMetadata("copyLocalVariable/copyLocalVariable.test") + public void testCopyLocalVariable_CopyLocalVariable() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copy/copyLocalVariable/copyLocalVariable.test"); + doTest(fileName); + } + + @TestMetadata("copyMemberFunction/copyMemberFunction.test") + public void testCopyMemberFunction_CopyMemberFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copy/copyMemberFunction/copyMemberFunction.test"); + doTest(fileName); + } + + @TestMetadata("copyMemberProperty/copyMemberProperty.test") + public void testCopyMemberProperty_CopyMemberProperty() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copy/copyMemberProperty/copyMemberProperty.test"); + doTest(fileName); + } + @TestMetadata("copyMultiClassFile/copyMultiClassFile.test") public void testCopyMultiClassFile_CopyMultiClassFile() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copy/copyMultiClassFile/copyMultiClassFile.test"); @@ -84,6 +114,12 @@ public class CopyTestGenerated extends AbstractCopyTest { doTest(fileName); } + @TestMetadata("copyMultipleDeclarations/copyMultipleDeclarations.test") + public void testCopyMultipleDeclarations_CopyMultipleDeclarations() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copy/copyMultipleDeclarations/copyMultipleDeclarations.test"); + doTest(fileName); + } + @TestMetadata("copyNestedClass/copyNestedClass.test") public void testCopyNestedClass_CopyNestedClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copy/copyNestedClass/copyNestedClass.test"); @@ -101,4 +137,28 @@ public class CopyTestGenerated extends AbstractCopyTest { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copy/copySingleClassFile/copySingleClassFile.test"); doTest(fileName); } + + @TestMetadata("copyTopLevelFunction/copyTopLevelFunction.test") + public void testCopyTopLevelFunction_CopyTopLevelFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copy/copyTopLevelFunction/copyTopLevelFunction.test"); + doTest(fileName); + } + + @TestMetadata("copyTopLevelFunctionWithRename/copyTopLevelFunctionWithRename.test") + public void testCopyTopLevelFunctionWithRename_CopyTopLevelFunctionWithRename() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copy/copyTopLevelFunctionWithRename/copyTopLevelFunctionWithRename.test"); + doTest(fileName); + } + + @TestMetadata("copyTopLevelProperty/copyTopLevelProperty.test") + public void testCopyTopLevelProperty_CopyTopLevelProperty() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copy/copyTopLevelProperty/copyTopLevelProperty.test"); + doTest(fileName); + } + + @TestMetadata("copyTopLevelPropertyWithRename/copyTopLevelPropertyWithRename.test") + public void testCopyTopLevelPropertyWithRename_CopyTopLevelPropertyWithRename() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copy/copyTopLevelPropertyWithRename/copyTopLevelPropertyWithRename.test"); + doTest(fileName); + } }