diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetPackageDirective.java b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetPackageDirective.java index f300fbd090e..c471010cf73 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetPackageDirective.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetPackageDirective.java @@ -21,17 +21,20 @@ import com.intellij.psi.PsiElement; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.psi.psiUtil.PsiUtilPackage; -import org.jetbrains.kotlin.psi.stubs.KotlinPlaceHolderStub; -import org.jetbrains.kotlin.psi.stubs.elements.JetStubElementTypes; +import org.jetbrains.kotlin.lexer.JetTokens; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.name.SpecialNames; +import org.jetbrains.kotlin.psi.psiUtil.PsiUtilPackage; +import org.jetbrains.kotlin.psi.stubs.KotlinPlaceHolderStub; +import org.jetbrains.kotlin.psi.stubs.elements.JetStubElementTypes; import java.util.Collections; import java.util.List; -public class JetPackageDirective extends JetModifierListOwnerStub> implements JetReferenceExpression { +public class JetPackageDirective + extends JetModifierListOwnerStub> + implements JetReferenceExpression { private String qualifiedNameCache = null; public JetPackageDirective(@NotNull ASTNode node) { @@ -116,6 +119,29 @@ public class JetPackageDirective extends JetModifierListOwnerStub? public var Project.ensureElementsToShortenIsEmptyBeforeRefactoring: Boolean by NotNullableUserDataProperty(Key.create("ENSURE_ELEMENTS_TO_SHORTEN_IS_EMPTY"), true) +public fun Project.runWithElementsToShortenIsEmptyIgnored(action: () -> Unit) { + val ensureElementsToShortenIsEmpty = ensureElementsToShortenIsEmptyBeforeRefactoring + + try { + ensureElementsToShortenIsEmptyBeforeRefactoring = false + action() + } finally { + ensureElementsToShortenIsEmptyBeforeRefactoring = ensureElementsToShortenIsEmpty + } +} + private fun Project.getOrCreateElementsToShorten(): MutableSet { var elements = elementsToShorten if (elements == null) { diff --git a/idea/resources/intentionDescriptions/ChangePackageIntention/after.kt.template b/idea/resources/intentionDescriptions/ChangePackageIntention/after.kt.template new file mode 100644 index 00000000000..80b01b80666 --- /dev/null +++ b/idea/resources/intentionDescriptions/ChangePackageIntention/after.kt.template @@ -0,0 +1,7 @@ +package bar.foo + +class MyClass: OtherClass { + fun myFun() { + + } +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/ChangePackageIntention/before.kt.template b/idea/resources/intentionDescriptions/ChangePackageIntention/before.kt.template new file mode 100644 index 00000000000..49dc58f2a24 --- /dev/null +++ b/idea/resources/intentionDescriptions/ChangePackageIntention/before.kt.template @@ -0,0 +1,9 @@ +package foo.bar + +import bar.foo.OtherClass + +class MyClass: OtherClass { + fun myFun() { + + } +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/ChangePackageIntention/description.html b/idea/resources/intentionDescriptions/ChangePackageIntention/description.html new file mode 100644 index 00000000000..05220f6e049 --- /dev/null +++ b/idea/resources/intentionDescriptions/ChangePackageIntention/description.html @@ -0,0 +1,6 @@ + + +This intention changes qualified package name of the current file without moving the file itself. +All references and import directives are updated accordingly. + + \ No newline at end of file diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 800fcb9670a..24612b1996a 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -848,6 +848,11 @@ Kotlin + + org.jetbrains.kotlin.idea.refactoring.move.changePackage.ChangePackageIntention + Kotlin + + (javaClass(), "Change package") { + override fun isApplicableTo(element: JetPackageDirective) = element.getPackageNameExpression() != null + + override fun applyTo(element: JetPackageDirective, editor: Editor) { + if (ApplicationManager.getApplication().isUnitTestMode()) { + throw UnsupportedOperationException("Do not call applyTo() in the test mode") + } + + val file = element.getContainingJetFile() + val project = file.getProject() + + val nameExpression = element.getPackageNameExpression()!! + val currentName = element.getQualifiedName() + + val builder = TemplateBuilderImpl(file) + builder.replaceElement( + nameExpression, + object: Expression() { + override fun calculateQuickResult(context: ExpressionContext?) = TextResult(currentName) + override fun calculateResult(context: ExpressionContext?) = TextResult(currentName) + override fun calculateLookupItems(context: ExpressionContext?) = arrayOf(LookupElementBuilder.create(currentName)) + } + ) + editor.getCaretModel().moveToOffset(0) + TemplateManager.getInstance(project).startTemplate( + editor, + builder.buildInlineTemplate(), + object: TemplateEditingAdapter() { + override fun templateFinished(template: Template?, brokenOff: Boolean) { + if (!brokenOff) { + // Restore original name and run refactoring + val packageDirective = file.getPackageDirective()!! + val newFqName = packageDirective.getFqName() + packageDirective.setFqName(FqName(currentName)) + KotlinChangePackageRefactoring(file).run(newFqName) + } + } + } + ) + } +} diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/changePackage/KotlinChangePackageRefactoring.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/changePackage/KotlinChangePackageRefactoring.kt new file mode 100644 index 00000000000..1d95b095668 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/changePackage/KotlinChangePackageRefactoring.kt @@ -0,0 +1,69 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.idea.refactoring.move.changePackage + +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiFile +import com.intellij.refactoring.PackageWrapper +import org.jetbrains.kotlin.idea.codeInsight.shorten.runWithElementsToShortenIsEmptyIgnored +import org.jetbrains.kotlin.idea.refactoring.move.PackageNameInfo +import org.jetbrains.kotlin.idea.refactoring.move.getInternalReferencesToUpdateOnPackageNameChange +import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.KotlinMoveTarget +import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.MoveKotlinTopLevelDeclarationsOptions +import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.MoveKotlinTopLevelDeclarationsProcessor +import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.Mover +import org.jetbrains.kotlin.idea.refactoring.move.postProcessMoveUsages +import org.jetbrains.kotlin.idea.util.application.executeWriteCommand +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.JetFile +import org.jetbrains.kotlin.psi.JetNamedDeclaration + +public class KotlinChangePackageRefactoring(val file: JetFile) { + private val project = file.getProject() + + fun run(newFqName: FqName) { + val packageDirective = file.getPackageDirective() ?: return + val currentFqName = packageDirective.getFqName() + + val declarationProcessor = MoveKotlinTopLevelDeclarationsProcessor( + project, + MoveKotlinTopLevelDeclarationsOptions( + elementsToMove = file.getDeclarations().filterIsInstance(), + moveTarget = object: KotlinMoveTarget { + override val packageWrapper = PackageWrapper(file.getManager(), newFqName.asString()) + + override fun getOrCreateTargetPsi(originalPsi: PsiElement) = originalPsi.getContainingFile() + + override fun getTargetPsiIfExists(originalPsi: PsiElement) = null + + override fun verify(file: PsiFile) = null + }, + updateInternalReferences = false + ), + Mover.Idle // we don't need to move any declarations physically + ) + + val declarationUsages = declarationProcessor.findUsages().toList() + val internalUsages = file.getInternalReferencesToUpdateOnPackageNameChange(PackageNameInfo(currentFqName, newFqName)) + + project.executeWriteCommand("Change file's package to '${newFqName.asString()}'") { + postProcessMoveUsages(internalUsages) + packageDirective.setFqName(newFqName) + project.runWithElementsToShortenIsEmptyIgnored { declarationProcessor.execute(declarationUsages) } + } + } +} diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/MoveKotlinFileHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/MoveKotlinFileHandler.kt index d71c9553c7c..c658a644512 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/MoveKotlinFileHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/MoveKotlinFileHandler.kt @@ -16,27 +16,26 @@ package org.jetbrains.kotlin.idea.refactoring.move.moveFilesOrDirectories -import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFileHandler -import com.intellij.psi.PsiFile -import com.intellij.psi.PsiDirectory -import com.intellij.psi.PsiElement -import com.intellij.usageView.UsageInfo import com.intellij.openapi.roots.JavaProjectRootsUtil import com.intellij.psi.PsiCompiledElement -import org.jetbrains.kotlin.psi.JetFile -import org.jetbrains.kotlin.psi.JetNamedDeclaration -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.idea.references.JetSimpleNameReference -import org.jetbrains.kotlin.psi.psiUtil.getPackage +import com.intellij.psi.PsiDirectory +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiFile +import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFileHandler +import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil +import com.intellij.usageView.UsageInfo +import org.jetbrains.kotlin.idea.codeInsight.shorten.runWithElementsToShortenIsEmptyIgnored import org.jetbrains.kotlin.idea.refactoring.move.PackageNameInfo import org.jetbrains.kotlin.idea.refactoring.move.getInternalReferencesToUpdateOnPackageNameChange -import org.jetbrains.kotlin.idea.refactoring.move.postProcessMoveUsages -import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.MoveKotlinTopLevelDeclarationsProcessor -import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.MoveKotlinTopLevelDeclarationsOptions -import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.DeferredJetFileKotlinMoveTarget +import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.MoveKotlinTopLevelDeclarationsOptions +import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.MoveKotlinTopLevelDeclarationsProcessor import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.Mover -import org.jetbrains.kotlin.idea.codeInsight.shorten.ensureElementsToShortenIsEmptyBeforeRefactoring +import org.jetbrains.kotlin.idea.refactoring.move.postProcessMoveUsages +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.JetFile +import org.jetbrains.kotlin.psi.JetNamedDeclaration +import org.jetbrains.kotlin.psi.psiUtil.getPackage public class MoveKotlinFileHandler : MoveFileHandler() { private var packageNameInfo: PackageNameInfo? = null @@ -82,10 +81,7 @@ public class MoveKotlinFileHandler : MoveFileHandler() { }, updateInternalReferences = false ), - object: Mover { - [suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")] - override fun invoke(originalElement: JetNamedDeclaration, targetFile: JetFile): JetNamedDeclaration = originalElement - } + Mover.Idle ) this.packageNameInfo = packageNameInfo @@ -100,29 +96,20 @@ public class MoveKotlinFileHandler : MoveFileHandler() { override fun updateMovedFile(file: PsiFile) { if (file !is JetFile) return + val packageNameInfo = packageNameInfo ?: return - val packageNameInfo = packageNameInfo - if (packageNameInfo == null) return - - val usages = file.getInternalReferencesToUpdateOnPackageNameChange(packageNameInfo) - postProcessMoveUsages(usages) - - val packageRef = file.getPackageDirective()?.getLastReferenceExpression()?.getReference() as? JetSimpleNameReference - packageRef?.bindToFqName(packageNameInfo.newPackageName) + postProcessMoveUsages(file.getInternalReferencesToUpdateOnPackageNameChange(packageNameInfo)) + file.getPackageDirective()?.setFqName(packageNameInfo.newPackageName) } override fun retargetUsages(usageInfos: List?, oldToNewMap: Map?) { val processor = declarationMoveProcessor ?: return - - val project = processor.project - val ensureElementsToShortenIsEmpty = project.ensureElementsToShortenIsEmptyBeforeRefactoring - - try { - project.ensureElementsToShortenIsEmptyBeforeRefactoring = false - usageInfos?.let { processor.execute(it) } - } finally { - project.ensureElementsToShortenIsEmptyBeforeRefactoring = ensureElementsToShortenIsEmpty - clearState() + processor.project.runWithElementsToShortenIsEmptyIgnored { + try { + usageInfos?.let { processor.execute(it) } + } finally { + clearState() + } } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/MoveKotlinTopLevelDeclarationsProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/MoveKotlinTopLevelDeclarationsProcessor.kt index 547b83b0acb..77d296625c3 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/MoveKotlinTopLevelDeclarationsProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/MoveKotlinTopLevelDeclarationsProcessor.kt @@ -72,6 +72,11 @@ trait Mover: (originalElement: JetNamedDeclaration, targetFile: JetFile) -> JetN return newElement } } + + object Idle: Mover { + [suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")] + override fun invoke(originalElement: JetNamedDeclaration, targetFile: JetFile) = originalElement + } } public class MoveKotlinTopLevelDeclarationsOptions( diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/after/source/test.kt b/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/after/source/test.kt new file mode 100644 index 00000000000..57850e7213b --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/after/source/test.kt @@ -0,0 +1,5 @@ +class Foo + +fun foo() { + +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/after/usagesWithFqNames.java b/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/after/usagesWithFqNames.java new file mode 100644 index 00000000000..4eed85888e6 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/after/usagesWithFqNames.java @@ -0,0 +1,6 @@ +class Test { + static void test() { + new Foo(); + _DefaultPackage.foo(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/after/usagesWithFqNames.kt b/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/after/usagesWithFqNames.kt new file mode 100644 index 00000000000..bf2b7529d08 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/after/usagesWithFqNames.kt @@ -0,0 +1,4 @@ +fun test() { + Foo() + foo() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/after/usagesWithImports.java b/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/after/usagesWithImports.java new file mode 100644 index 00000000000..852ffc06cc5 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/after/usagesWithImports.java @@ -0,0 +1,8 @@ +import static _DefaultPackage.foo; + +class Test { + static void test() { + new Foo(); + foo(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/after/usagesWithImports.kt b/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/after/usagesWithImports.kt new file mode 100644 index 00000000000..b79e12ef3cb --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/after/usagesWithImports.kt @@ -0,0 +1,7 @@ +import Foo +import foo + +fun test() { + Foo() + foo() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/before/source/test.kt b/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/before/source/test.kt new file mode 100644 index 00000000000..ac325ba6ffd --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/before/source/test.kt @@ -0,0 +1,7 @@ +package source + +class Foo + +fun foo() { + +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/before/usagesWithFqNames.java b/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/before/usagesWithFqNames.java new file mode 100644 index 00000000000..3e30c6c2267 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/before/usagesWithFqNames.java @@ -0,0 +1,6 @@ +class Test { + static void test() { + new source.Foo(); + source.SourcePackage.foo(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/before/usagesWithFqNames.kt b/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/before/usagesWithFqNames.kt new file mode 100644 index 00000000000..245db339714 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/before/usagesWithFqNames.kt @@ -0,0 +1,4 @@ +fun test() { + source.Foo() + source.foo() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/before/usagesWithImports.java b/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/before/usagesWithImports.java new file mode 100644 index 00000000000..e1ff38b1908 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/before/usagesWithImports.java @@ -0,0 +1,9 @@ +import source.Foo; +import static source.SourcePackage.foo; + +class Test { + static void test() { + new Foo(); + foo(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/before/usagesWithImports.kt b/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/before/usagesWithImports.kt new file mode 100644 index 00000000000..f1d046d8c9c --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/before/usagesWithImports.kt @@ -0,0 +1,7 @@ +import source.Foo +import source.foo + +fun test() { + Foo() + foo() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/changeToDefaultPackage.test b/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/changeToDefaultPackage.test new file mode 100644 index 00000000000..9815edd1399 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/changeToDefaultPackage.test @@ -0,0 +1,5 @@ +{ + "mainFile": "source/test.kt", + "type": "CHANGE_PACKAGE_DIRECTIVE", + "newPackageName": "" +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/source/test.kt b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/source/test.kt new file mode 100644 index 00000000000..0c71841bbb9 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/source/test.kt @@ -0,0 +1,7 @@ +package target + +class Foo + +fun foo() { + +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/target/usagesWithFqNames.java b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/target/usagesWithFqNames.java new file mode 100644 index 00000000000..42a5fe007f3 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/target/usagesWithFqNames.java @@ -0,0 +1,8 @@ +package target; + +class Test { + static void test() { + new Foo(); + TargetPackage.foo(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/target/usagesWithFqNames.kt b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/target/usagesWithFqNames.kt new file mode 100644 index 00000000000..a14e5ef3203 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/target/usagesWithFqNames.kt @@ -0,0 +1,6 @@ +package target + +fun test() { + Foo() + foo() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/target/usagesWithImports.java b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/target/usagesWithImports.java new file mode 100644 index 00000000000..0e07fe87e3a --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/target/usagesWithImports.java @@ -0,0 +1,10 @@ +package target; + +import static target.TargetPackage.foo; + +class Test { + static void test() { + new Foo(); + foo(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/target/usagesWithImports.kt b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/target/usagesWithImports.kt new file mode 100644 index 00000000000..147a343d79d --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/target/usagesWithImports.kt @@ -0,0 +1,9 @@ +package target + +import target.Foo +import target.foo + +fun test() { + Foo() + foo() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/usages/usagesWithFqNames.java b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/usages/usagesWithFqNames.java new file mode 100644 index 00000000000..201ecd0a871 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/usages/usagesWithFqNames.java @@ -0,0 +1,11 @@ +package usages; + +import target.Foo; +import target.TargetPackage; + +class Test { + static void test() { + new Foo(); + TargetPackage.foo(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/usages/usagesWithFqNames.kt b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/usages/usagesWithFqNames.kt new file mode 100644 index 00000000000..fa179846ece --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/usages/usagesWithFqNames.kt @@ -0,0 +1,9 @@ +package usages + +import target.Foo +import target.foo + +fun test() { + Foo() + foo() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/usages/usagesWithImports.java b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/usages/usagesWithImports.java new file mode 100644 index 00000000000..4301144239c --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/usages/usagesWithImports.java @@ -0,0 +1,11 @@ +package usages; + +import target.Foo; +import static target.TargetPackage.foo; + +class Test { + static void test() { + new Foo(); + foo(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/usages/usagesWithImports.kt b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/usages/usagesWithImports.kt new file mode 100644 index 00000000000..fa179846ece --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/after/usages/usagesWithImports.kt @@ -0,0 +1,9 @@ +package usages + +import target.Foo +import target.foo + +fun test() { + Foo() + foo() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/source/test.kt b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/source/test.kt new file mode 100644 index 00000000000..ac325ba6ffd --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/source/test.kt @@ -0,0 +1,7 @@ +package source + +class Foo + +fun foo() { + +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/target/usagesWithFqNames.java b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/target/usagesWithFqNames.java new file mode 100644 index 00000000000..52c2498143c --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/target/usagesWithFqNames.java @@ -0,0 +1,8 @@ +package target; + +class Test { + static void test() { + new source.Foo(); + source.SourcePackage.foo(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/target/usagesWithFqNames.kt b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/target/usagesWithFqNames.kt new file mode 100644 index 00000000000..2724bbff099 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/target/usagesWithFqNames.kt @@ -0,0 +1,6 @@ +package target + +fun test() { + source.Foo() + source.foo() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/target/usagesWithImports.java b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/target/usagesWithImports.java new file mode 100644 index 00000000000..f83a0941af6 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/target/usagesWithImports.java @@ -0,0 +1,11 @@ +package target; + +import source.Foo; +import static source.SourcePackage.foo; + +class Test { + static void test() { + new Foo(); + foo(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/target/usagesWithImports.kt b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/target/usagesWithImports.kt new file mode 100644 index 00000000000..55d3cd2f88e --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/target/usagesWithImports.kt @@ -0,0 +1,9 @@ +package target + +import source.Foo +import source.foo + +fun test() { + Foo() + foo() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/usages/usagesWithFqNames.java b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/usages/usagesWithFqNames.java new file mode 100644 index 00000000000..41b1a04ff7d --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/usages/usagesWithFqNames.java @@ -0,0 +1,8 @@ +package usages; + +class Test { + static void test() { + new source.Foo(); + source.SourcePackage.foo(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/usages/usagesWithFqNames.kt b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/usages/usagesWithFqNames.kt new file mode 100644 index 00000000000..035fec4a1ae --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/usages/usagesWithFqNames.kt @@ -0,0 +1,6 @@ +package usages + +fun test() { + source.Foo() + source.foo() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/usages/usagesWithImports.java b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/usages/usagesWithImports.java new file mode 100644 index 00000000000..59cb604e2c3 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/usages/usagesWithImports.java @@ -0,0 +1,11 @@ +package usages; + +import source.Foo; +import static source.SourcePackage.foo; + +class Test { + static void test() { + new Foo(); + foo(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/usages/usagesWithImports.kt b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/usages/usagesWithImports.kt new file mode 100644 index 00000000000..e8c4f95a9ac --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/before/usages/usagesWithImports.kt @@ -0,0 +1,9 @@ +package usages + +import source.Foo +import source.foo + +fun test() { + Foo() + foo() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/changeToNonDefaultPackage.test b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/changeToNonDefaultPackage.test new file mode 100644 index 00000000000..4815ed12467 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/changeToNonDefaultPackage.test @@ -0,0 +1,5 @@ +{ + "mainFile": "source/test.kt", + "type": "CHANGE_PACKAGE_DIRECTIVE", + "newPackageName": "target" +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/AbstractJetMoveTest.kt b/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/AbstractJetMoveTest.kt index 2861c7ff8f7..d631bee5be1 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/AbstractJetMoveTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/AbstractJetMoveTest.kt @@ -37,6 +37,7 @@ import com.intellij.refactoring.move.moveInner.MoveInnerProcessor import com.intellij.refactoring.move.moveMembers.MockMoveMembersOptions import com.intellij.refactoring.move.moveMembers.MoveMembersProcessor import com.intellij.util.ActionRunner +import org.jetbrains.kotlin.idea.refactoring.move.changePackage.KotlinChangePackageRefactoring import org.jetbrains.kotlin.idea.test.KotlinMultiFileTestCase import org.jetbrains.kotlin.idea.test.PluginTestCaseBase import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.JetFileKotlinMoveTarget @@ -49,6 +50,7 @@ import org.jetbrains.kotlin.psi.JetFile import org.jetbrains.kotlin.psi.JetNamedDeclaration import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil +import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.test.JetTestUtils import java.io.File @@ -269,5 +271,11 @@ enum class MoveAction { } } + CHANGE_PACKAGE_DIRECTIVE { + override fun runRefactoring(rootDir: VirtualFile, mainFile: PsiFile, elementAtCaret: PsiElement?, config: JsonObject) { + KotlinChangePackageRefactoring(mainFile as JetFile).run(FqName(config.getString("newPackageName"))) + } + } + abstract fun runRefactoring(rootDir: VirtualFile, mainFile: PsiFile, elementAtCaret: PsiElement?, config: JsonObject) } diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/JetMoveTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/JetMoveTestGenerated.java index 12201868c01..e202a57b810 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/JetMoveTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/JetMoveTestGenerated.java @@ -209,6 +209,18 @@ public class JetMoveTestGenerated extends AbstractJetMoveTest { doTest(fileName); } + @TestMetadata("kotlin/changePackage/changeToDefaultPackage/changeToDefaultPackage.test") + public void testKotlin_changePackage_changeToDefaultPackage_ChangeToDefaultPackage() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/changePackage/changeToDefaultPackage/changeToDefaultPackage.test"); + doTest(fileName); + } + + @TestMetadata("kotlin/changePackage/changeToNonDefaultPackage/changeToNonDefaultPackage.test") + public void testKotlin_changePackage_changeToNonDefaultPackage_ChangeToNonDefaultPackage() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/changePackage/changeToNonDefaultPackage/changeToNonDefaultPackage.test"); + doTest(fileName); + } + @TestMetadata("kotlin/moveFile/internalReferences/internalReferences.test") public void testKotlin_moveFile_internalReferences_InternalReferences() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveFile/internalReferences/internalReferences.test");