diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/KtFile.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/KtFile.kt index bada78df856..d8c6271c43d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/KtFile.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/KtFile.kt @@ -76,8 +76,18 @@ open class KtFile(viewProvider: FileViewProvider, val isCompiled: Boolean) : return if (ast != null) ast.psi as KtPackageDirective else null } - val packageFqName: FqName + var packageFqName: FqName get() = stub?.getPackageFqName() ?: packageFqNameByTree + set(value) { + val packageDirective = packageDirective + if (packageDirective != null) { + packageDirective.fqName = value + } + else { + val newPackageDirective = KtPsiFactory(this).createPackageDirectiveIfNeeded(value) ?: return + addAfter(newPackageDirective, null) + } + } val packageFqNameByTree: FqName get() = packageDirectiveByTree?.fqName ?: FqName.ROOT 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 683cf6101e9..1fe0ac262bc 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationsHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationsHandler.kt @@ -39,6 +39,8 @@ import com.intellij.util.IncorrectOperationException import com.intellij.util.containers.MultiMap import org.jetbrains.annotations.TestOnly import org.jetbrains.kotlin.idea.codeInsight.shorten.performDelayedRefactoringRequests +import org.jetbrains.kotlin.idea.core.getPackage +import org.jetbrains.kotlin.idea.core.packageMatchesDirectory import org.jetbrains.kotlin.idea.refactoring.checkConflictsInteractively import org.jetbrains.kotlin.idea.refactoring.createKotlinFile import org.jetbrains.kotlin.idea.refactoring.move.* @@ -63,8 +65,11 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() { @set:TestOnly var Project.newName: String? by UserDataProperty(Key.create("NEW_NAME")) - private fun PsiElement.getElementsToCopy(): List { - val declarationOrFile = parentsWithSelf.firstOrNull { it is KtFile || (it is KtNamedDeclaration && it.parent is KtFile) } + private fun PsiElement.getCopyableElement() = + parentsWithSelf.firstOrNull { it is KtFile || (it is KtNamedDeclaration && it.parent is KtFile) } as? KtElement + + private fun PsiElement.getDeclarationsToCopy(): List { + val declarationOrFile = getCopyableElement() return when (declarationOrFile) { is KtFile -> declarationOrFile.declarations.filterIsInstance().ifEmpty { listOf(declarationOrFile) } is KtNamedDeclaration -> listOf(declarationOrFile) @@ -90,7 +95,7 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() { private fun canCopyDeclarations(elements: Array): Boolean { val containingFile = elements - .flatMap { it.getElementsToCopy().ifEmpty { return false } } + .flatMap { it.getDeclarationsToCopy().ifEmpty { return false } } .distinctBy { it.containingFile } .singleOrNull() ?.containingFile ?: return false @@ -174,7 +179,7 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() { return copyFilesHandler.doCopy(sourceFiles, defaultTargetDirectory) } - val elementsToCopy = elements.flatMap { it.getElementsToCopy() } + val elementsToCopy = elements.mapNotNull { it.getCopyableElement() } if (elementsToCopy.isEmpty()) return val singleElementToCopy = elementsToCopy.singleOrNull() @@ -248,6 +253,9 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() { if (singleElementToCopy is KtFile) { targetFile = runWriteAction { val copiedFile = targetDirectory.copyFileFrom(targetFileName, singleElementToCopy) as KtFile + if (singleElementToCopy.packageMatchesDirectory()) { + targetDirectory.getPackage()?.qualifiedName?.let { copiedFile.packageFqName = FqName(it) } + } performDelayedRefactoringRequests(project) copiedFile } diff --git a/idea/testData/refactoring/copy/copyFIleFromDefaultPackage/after/bar/test.kt b/idea/testData/refactoring/copy/copyFIleFromDefaultPackage/after/bar/test.kt new file mode 100644 index 00000000000..c299dd73002 --- /dev/null +++ b/idea/testData/refactoring/copy/copyFIleFromDefaultPackage/after/bar/test.kt @@ -0,0 +1,8 @@ +package bar + +val a = 42 + +// comment + +// some other comment +val s = "" \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyFIleFromDefaultPackage/after/test.kt b/idea/testData/refactoring/copy/copyFIleFromDefaultPackage/after/test.kt new file mode 100644 index 00000000000..71d1b354d30 --- /dev/null +++ b/idea/testData/refactoring/copy/copyFIleFromDefaultPackage/after/test.kt @@ -0,0 +1,6 @@ +val a = 42 + +// comment + +// some other comment +val s = "" \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyFIleFromDefaultPackage/before/test.kt b/idea/testData/refactoring/copy/copyFIleFromDefaultPackage/before/test.kt new file mode 100644 index 00000000000..71d1b354d30 --- /dev/null +++ b/idea/testData/refactoring/copy/copyFIleFromDefaultPackage/before/test.kt @@ -0,0 +1,6 @@ +val a = 42 + +// comment + +// some other comment +val s = "" \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyFIleFromDefaultPackage/copyFIleFromDefaultPackage.test b/idea/testData/refactoring/copy/copyFIleFromDefaultPackage/copyFIleFromDefaultPackage.test new file mode 100644 index 00000000000..a72ed185f0b --- /dev/null +++ b/idea/testData/refactoring/copy/copyFIleFromDefaultPackage/copyFIleFromDefaultPackage.test @@ -0,0 +1,4 @@ +{ + "mainFile": "test.kt", + "targetPackage": "bar" +} diff --git a/idea/testData/refactoring/copy/copyFIleRetainContent/after/bar/test.kt b/idea/testData/refactoring/copy/copyFIleRetainContent/after/bar/test.kt new file mode 100644 index 00000000000..c299dd73002 --- /dev/null +++ b/idea/testData/refactoring/copy/copyFIleRetainContent/after/bar/test.kt @@ -0,0 +1,8 @@ +package bar + +val a = 42 + +// comment + +// some other comment +val s = "" \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyFIleRetainContent/after/foo/test.kt b/idea/testData/refactoring/copy/copyFIleRetainContent/after/foo/test.kt new file mode 100644 index 00000000000..6cd7df7764e --- /dev/null +++ b/idea/testData/refactoring/copy/copyFIleRetainContent/after/foo/test.kt @@ -0,0 +1,8 @@ +package foo + +val a = 42 + +// comment + +// some other comment +val s = "" \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyFIleRetainContent/before/foo/test.kt b/idea/testData/refactoring/copy/copyFIleRetainContent/before/foo/test.kt new file mode 100644 index 00000000000..6cd7df7764e --- /dev/null +++ b/idea/testData/refactoring/copy/copyFIleRetainContent/before/foo/test.kt @@ -0,0 +1,8 @@ +package foo + +val a = 42 + +// comment + +// some other comment +val s = "" \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyFIleRetainContent/copyFIleRetainContent.test b/idea/testData/refactoring/copy/copyFIleRetainContent/copyFIleRetainContent.test new file mode 100644 index 00000000000..f169eabdfa3 --- /dev/null +++ b/idea/testData/refactoring/copy/copyFIleRetainContent/copyFIleRetainContent.test @@ -0,0 +1,4 @@ +{ + "mainFile": "foo/test.kt", + "targetPackage": "bar" +} diff --git a/idea/testData/refactoring/copy/copyFIleToDefaultPackage/after/foo/test.kt b/idea/testData/refactoring/copy/copyFIleToDefaultPackage/after/foo/test.kt new file mode 100644 index 00000000000..6cd7df7764e --- /dev/null +++ b/idea/testData/refactoring/copy/copyFIleToDefaultPackage/after/foo/test.kt @@ -0,0 +1,8 @@ +package foo + +val a = 42 + +// comment + +// some other comment +val s = "" \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyFIleToDefaultPackage/after/test.kt b/idea/testData/refactoring/copy/copyFIleToDefaultPackage/after/test.kt new file mode 100644 index 00000000000..71d1b354d30 --- /dev/null +++ b/idea/testData/refactoring/copy/copyFIleToDefaultPackage/after/test.kt @@ -0,0 +1,6 @@ +val a = 42 + +// comment + +// some other comment +val s = "" \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyFIleToDefaultPackage/before/foo/test.kt b/idea/testData/refactoring/copy/copyFIleToDefaultPackage/before/foo/test.kt new file mode 100644 index 00000000000..6cd7df7764e --- /dev/null +++ b/idea/testData/refactoring/copy/copyFIleToDefaultPackage/before/foo/test.kt @@ -0,0 +1,8 @@ +package foo + +val a = 42 + +// comment + +// some other comment +val s = "" \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyFIleToDefaultPackage/copyFIleToDefaultPackage.test b/idea/testData/refactoring/copy/copyFIleToDefaultPackage/copyFIleToDefaultPackage.test new file mode 100644 index 00000000000..49d37a24bfd --- /dev/null +++ b/idea/testData/refactoring/copy/copyFIleToDefaultPackage/copyFIleToDefaultPackage.test @@ -0,0 +1,4 @@ +{ + "mainFile": "foo/test.kt", + "targetPackage": "" +} diff --git a/idea/testData/refactoring/copy/copyFIleWithPackageAndDirUnmatched/after/bar/test.kt b/idea/testData/refactoring/copy/copyFIleWithPackageAndDirUnmatched/after/bar/test.kt new file mode 100644 index 00000000000..496b0552e62 --- /dev/null +++ b/idea/testData/refactoring/copy/copyFIleWithPackageAndDirUnmatched/after/bar/test.kt @@ -0,0 +1,8 @@ +package baz + +val a = 42 + +// comment + +// some other comment +val s = "" \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyFIleWithPackageAndDirUnmatched/after/foo/test.kt b/idea/testData/refactoring/copy/copyFIleWithPackageAndDirUnmatched/after/foo/test.kt new file mode 100644 index 00000000000..496b0552e62 --- /dev/null +++ b/idea/testData/refactoring/copy/copyFIleWithPackageAndDirUnmatched/after/foo/test.kt @@ -0,0 +1,8 @@ +package baz + +val a = 42 + +// comment + +// some other comment +val s = "" \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyFIleWithPackageAndDirUnmatched/before/foo/test.kt b/idea/testData/refactoring/copy/copyFIleWithPackageAndDirUnmatched/before/foo/test.kt new file mode 100644 index 00000000000..496b0552e62 --- /dev/null +++ b/idea/testData/refactoring/copy/copyFIleWithPackageAndDirUnmatched/before/foo/test.kt @@ -0,0 +1,8 @@ +package baz + +val a = 42 + +// comment + +// some other comment +val s = "" \ No newline at end of file diff --git a/idea/testData/refactoring/copy/copyFIleWithPackageAndDirUnmatched/copyFIleWithPackageAndDirUnmatched.test b/idea/testData/refactoring/copy/copyFIleWithPackageAndDirUnmatched/copyFIleWithPackageAndDirUnmatched.test new file mode 100644 index 00000000000..f169eabdfa3 --- /dev/null +++ b/idea/testData/refactoring/copy/copyFIleWithPackageAndDirUnmatched/copyFIleWithPackageAndDirUnmatched.test @@ -0,0 +1,4 @@ +{ + "mainFile": "foo/test.kt", + "targetPackage": "bar" +} diff --git a/idea/testData/refactoring/copy/copyMultiClassFile/after/bar/test.kt b/idea/testData/refactoring/copy/copyMultiClassFile/after/bar/test.kt index c52f950b8cf..958cf968c3d 100644 --- a/idea/testData/refactoring/copy/copyMultiClassFile/after/bar/test.kt +++ b/idea/testData/refactoring/copy/copyMultiClassFile/after/bar/test.kt @@ -8,4 +8,4 @@ class A { class B { val a: A = A() val b: B = B() -} \ No newline at end of file +} diff --git a/idea/testData/refactoring/copy/copySingleClassFile/after/bar/A.kt b/idea/testData/refactoring/copy/copySingleClassFile/after/bar/test.kt similarity index 100% rename from idea/testData/refactoring/copy/copySingleClassFile/after/bar/A.kt rename to idea/testData/refactoring/copy/copySingleClassFile/after/bar/test.kt diff --git a/idea/testData/refactoring/copy/kt18149/after/refactor/copy2/test.kt b/idea/testData/refactoring/copy/kt18149/after/refactor/copy2/test.kt index 1d1b84c733c..b2b214584a3 100644 --- a/idea/testData/refactoring/copy/kt18149/after/refactor/copy2/test.kt +++ b/idea/testData/refactoring/copy/kt18149/after/refactor/copy2/test.kt @@ -1,15 +1,14 @@ package refactor.copy2 import refactor.ParentJava -import refactor.copy.Company import kotlin.properties.Delegates enum class Possible { NO, YES } - data class Potable(val p1: String) class Insider(val peace: String) + class Init { fun referred() = 0 fun moved() = referred() @@ -28,6 +27,7 @@ class Simple { } annotation class MemAnn + class Variety { // object object ExtractedObject {} @@ -42,8 +42,7 @@ class Variety { private fun privateFun() = 0 fun genFunB(p: T): T = p fun genFunC(p: T): C where T : C = p - @MemAnn - fun annotatedFun() = 0 + @MemAnn fun annotatedFun() = 0 final fun finalFun() = 0 // property var publicProp = 0 @@ -56,8 +55,7 @@ class Variety { var List.genVarL: T where T : C get() = last() set(p) {} - @MemAnn - val annotatedVal = 0 + @MemAnn val annotatedVal = 0 var byVar by Delegates.notNull() lateinit var lateVal: String final val finalVal = 0 @@ -146,9 +144,9 @@ class CtorParameterChild(val pvc: String, var prc: String) : CtorParameter(pvc, class CtorParameterChild2: CtorParameter { constructor() : super("", "", "") } - class CtorParameterChild3(override val pv: String, override var pr: String) : CtorParameter(pv, pv, pr) data class CtorData(val pv: String, var pr: String) {} + class Company { companion object { val companyVal = 0 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 f4cb8bba240..2c18659e721 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/copy/CopyTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/copy/CopyTestGenerated.java @@ -72,6 +72,30 @@ public class CopyTestGenerated extends AbstractCopyTest { doTest(fileName); } + @TestMetadata("copyFIleFromDefaultPackage/copyFIleFromDefaultPackage.test") + public void testCopyFIleFromDefaultPackage_CopyFIleFromDefaultPackage() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copy/copyFIleFromDefaultPackage/copyFIleFromDefaultPackage.test"); + doTest(fileName); + } + + @TestMetadata("copyFIleRetainContent/copyFIleRetainContent.test") + public void testCopyFIleRetainContent_CopyFIleRetainContent() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copy/copyFIleRetainContent/copyFIleRetainContent.test"); + doTest(fileName); + } + + @TestMetadata("copyFIleToDefaultPackage/copyFIleToDefaultPackage.test") + public void testCopyFIleToDefaultPackage_CopyFIleToDefaultPackage() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copy/copyFIleToDefaultPackage/copyFIleToDefaultPackage.test"); + doTest(fileName); + } + + @TestMetadata("copyFIleWithPackageAndDirUnmatched/copyFIleWithPackageAndDirUnmatched.test") + public void testCopyFIleWithPackageAndDirUnmatched_CopyFIleWithPackageAndDirUnmatched() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copy/copyFIleWithPackageAndDirUnmatched/copyFIleWithPackageAndDirUnmatched.test"); + doTest(fileName); + } + @TestMetadata("copyFunCallQualificationWithParentheses/copyFunCallQualificationWithParentheses.test") public void testCopyFunCallQualificationWithParentheses_CopyFunCallQualificationWithParentheses() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/copy/copyFunCallQualificationWithParentheses/copyFunCallQualificationWithParentheses.test");