diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 032558b8f6b..e53a772908a 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -330,7 +330,7 @@ order="before moveJavaFileOrDir"/> - org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.MoveDeclarationToSeparateFileIntention + org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.MoveDeclarationToSeparateFileIntention Kotlin diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineValHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineValHandler.kt index 27c7d005ac8..6fb495f4f4b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineValHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineValHandler.kt @@ -45,7 +45,8 @@ import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.idea.refactoring.addTypeArgumentsIfNeeded import org.jetbrains.kotlin.idea.refactoring.checkConflictsInteractively import org.jetbrains.kotlin.idea.refactoring.getQualifiedTypeArgumentList -import org.jetbrains.kotlin.idea.refactoring.move.PackageNameInfo +import org.jetbrains.kotlin.idea.refactoring.move.ContainerChangeInfo +import org.jetbrains.kotlin.idea.refactoring.move.ContainerInfo import org.jetbrains.kotlin.idea.refactoring.move.lazilyProcessInternalReferencesToUpdateOnPackageNameChange import org.jetbrains.kotlin.idea.refactoring.move.postProcessMoveUsages import org.jetbrains.kotlin.idea.references.mainReference @@ -167,7 +168,7 @@ class KotlinInlineValHandler : InlineActionHandler() { val targetPackages = referenceExpressions.mapNotNullTo(LinkedHashSet()) { (it.containingFile as? KtFile)?.packageFqName } for (targetPackage in targetPackages) { if (targetPackage == file.packageFqName) continue - val packageNameInfo = PackageNameInfo(file.packageFqName, targetPackage.toUnsafe()) + val packageNameInfo = ContainerChangeInfo(ContainerInfo.Package(file.packageFqName), ContainerInfo.Package(targetPackage)) initializer.lazilyProcessInternalReferencesToUpdateOnPackageNameChange(packageNameInfo) { expr, factory -> val infos = expr.internalUsageInfos ?: LinkedHashMap UsageInfo?>() diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/MoveJavaInnerClassKotlinUsagesHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/MoveJavaInnerClassKotlinUsagesHandler.kt index 40d3504eb0f..b23654cf847 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/MoveJavaInnerClassKotlinUsagesHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/MoveJavaInnerClassKotlinUsagesHandler.kt @@ -16,47 +16,47 @@ package org.jetbrains.kotlin.idea.refactoring.move +import com.intellij.psi.PsiClass +import com.intellij.psi.PsiWhiteSpace +import com.intellij.psi.util.PsiTreeUtil import com.intellij.refactoring.move.moveInner.MoveInnerClassUsagesHandler import com.intellij.usageView.UsageInfo -import com.intellij.psi.PsiClass -import org.jetbrains.kotlin.psi.KtQualifiedExpression -import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector +import org.jetbrains.kotlin.idea.references.mainReference +import org.jetbrains.kotlin.idea.references.matchesTarget import org.jetbrains.kotlin.psi.KtCallExpression import org.jetbrains.kotlin.psi.KtPsiFactory -import java.util.ArrayList +import org.jetbrains.kotlin.psi.KtQualifiedExpression import org.jetbrains.kotlin.psi.KtSimpleNameExpression -import com.intellij.psi.util.PsiTreeUtil -import com.intellij.psi.PsiWhiteSpace -import org.jetbrains.kotlin.idea.references.mainReference +import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector +import java.util.* class MoveJavaInnerClassKotlinUsagesHandler: MoveInnerClassUsagesHandler { override fun correctInnerClassUsage(usage: UsageInfo, outerClass: PsiClass) { val innerCall = usage.element?.parent as? KtCallExpression ?: return - val receiver = (innerCall.parent as? KtQualifiedExpression)?.receiverExpression - val outerClassRef = when (receiver) { + val receiver = (innerCall.parent as? KtQualifiedExpression)?.receiverExpression ?: return + val outerClassRefExpr = when (receiver) { is KtCallExpression -> receiver.calleeExpression is KtQualifiedExpression -> receiver.getQualifiedElementSelector() else -> null } as? KtSimpleNameExpression - if (outerClassRef?.mainReference?.resolve() != outerClass) return - - val outerCall = outerClassRef!!.parent as? KtCallExpression ?: return + val outerClassRef = outerClassRefExpr?.mainReference ?: return + if (!outerClassRef.matchesTarget(outerClass)) return val psiFactory = KtPsiFactory(usage.project) val argumentList = innerCall.valueArgumentList if (argumentList != null) { val newArguments = ArrayList() - newArguments.add(outerCall.text!!) + newArguments.add(receiver.text!!) argumentList.arguments.mapTo(newArguments) { it.text!! } argumentList.replace(psiFactory.createCallArguments(newArguments.joinToString(prefix = "(", postfix = ")"))) } else { innerCall.lambdaArguments.firstOrNull()?.let { lambdaArg -> val anchor = PsiTreeUtil.skipSiblingsBackward(lambdaArg, PsiWhiteSpace::class.java) - innerCall.addAfter(psiFactory.createCallArguments("(${outerCall.text})"), anchor) + innerCall.addAfter(psiFactory.createCallArguments("(${receiver.text})"), anchor) } } } -} +} \ No newline at end of file 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 index 0416dfaf4b0..218d4fc8a2b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/changePackage/KotlinChangePackageRefactoring.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/changePackage/KotlinChangePackageRefactoring.kt @@ -18,14 +18,11 @@ 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.ContainerChangeInfo +import org.jetbrains.kotlin.idea.refactoring.move.ContainerInfo 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.moveDeclarations.* import org.jetbrains.kotlin.idea.refactoring.move.postProcessMoveUsages import org.jetbrains.kotlin.idea.util.application.executeWriteCommand import org.jetbrains.kotlin.name.FqName @@ -39,26 +36,28 @@ class KotlinChangePackageRefactoring(val file: KtFile) { val packageDirective = file.packageDirective ?: return val currentFqName = packageDirective.fqName - val declarationProcessor = MoveKotlinTopLevelDeclarationsProcessor( + val declarationProcessor = MoveKotlinDeclarationsProcessor( project, - MoveKotlinTopLevelDeclarationsOptions( + MoveDeclarationsDescriptor( elementsToMove = file.declarations.filterIsInstance(), moveTarget = object: KotlinMoveTarget { - override val packageWrapper = PackageWrapper(file.manager, newFqName.asString()) + override val targetContainerFqName = newFqName - override fun getOrCreateTargetPsi(originalPsi: PsiElement) = originalPsi.containingFile + override fun getOrCreateTargetPsi(originalPsi: PsiElement) = originalPsi.containingFile as? KtFile override fun getTargetPsiIfExists(originalPsi: PsiElement) = null override fun verify(file: PsiFile) = null }, + delegate = MoveDeclarationsDelegate.TopLevel, 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.toUnsafe())) + val changeInfo = ContainerChangeInfo(ContainerInfo.Package(currentFqName), ContainerInfo.Package(newFqName)) + val internalUsages = file.getInternalReferencesToUpdateOnPackageNameChange(changeInfo) project.executeWriteCommand("Change file's package to '${newFqName.asString()}'") { packageDirective.fqName = newFqName diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/KotlinMoveTarget.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/KotlinMoveTarget.kt similarity index 65% rename from idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/KotlinMoveTarget.kt rename to idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/KotlinMoveTarget.kt index 5ecea800b5e..b1649e936e5 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/KotlinMoveTarget.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/KotlinMoveTarget.kt @@ -14,56 +14,50 @@ * limitations under the License. */ -package org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations +package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations -import com.intellij.openapi.project.Project import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile -import com.intellij.psi.PsiManager -import com.intellij.refactoring.PackageWrapper import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.utils.getOrPutNullable -import java.util.HashMap +import java.util.* interface KotlinMoveTarget { - val packageWrapper: PackageWrapper? - fun getOrCreateTargetPsi(originalPsi: PsiElement): PsiFile? - fun getTargetPsiIfExists(originalPsi: PsiElement): PsiFile? + val targetContainerFqName: FqName? + fun getOrCreateTargetPsi(originalPsi: PsiElement): KtElement? + fun getTargetPsiIfExists(originalPsi: PsiElement): KtElement? // Check possible errors and return corresponding message, or null if no errors are detected fun verify(file: PsiFile): String? } object EmptyKotlinMoveTarget: KotlinMoveTarget { - override val packageWrapper: PackageWrapper? get() = null + override val targetContainerFqName = null override fun getOrCreateTargetPsi(originalPsi: PsiElement) = null override fun getTargetPsiIfExists(originalPsi: PsiElement) = null override fun verify(file: PsiFile) = null } -class KotlinMoveTargetForExistingFile(val targetFile: KtFile): KotlinMoveTarget { - override val packageWrapper: PackageWrapper? = targetFile.packageFqName.asString().let { packageName -> - PackageWrapper(PsiManager.getInstance(targetFile.project), packageName) - } +class KotlinMoveTargetForExistingElement(val targetElement: KtElement): KotlinMoveTarget { + override val targetContainerFqName = targetElement.getContainingKtFile().packageFqName - override fun getOrCreateTargetPsi(originalPsi: PsiElement) = targetFile + override fun getOrCreateTargetPsi(originalPsi: PsiElement) = targetElement - override fun getTargetPsiIfExists(originalPsi: PsiElement) = targetFile + override fun getTargetPsiIfExists(originalPsi: PsiElement) = targetElement // No additional verification is needed override fun verify(file: PsiFile): String? = null } class KotlinMoveTargetForDeferredFile( - project: Project, - private val packageFqName: FqName, - private val createFile: (KtFile) -> KtFile?): KotlinMoveTarget { + override val targetContainerFqName: FqName, + private val createFile: (KtFile) -> KtFile? +): KotlinMoveTarget { private val createdFiles = HashMap() - override val packageWrapper: PackageWrapper = PackageWrapper(PsiManager.getInstance(project), packageFqName.asString()) - - override fun getOrCreateTargetPsi(originalPsi: PsiElement): PsiFile? { + override fun getOrCreateTargetPsi(originalPsi: PsiElement): KtElement? { val originalFile = originalPsi.containingFile as? KtFile ?: return null return createdFiles.getOrPutNullable(originalFile) { createFile(originalFile) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/MoveDeclarationToSeparateFileIntention.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveDeclarationToSeparateFileIntention.kt similarity index 91% rename from idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/MoveDeclarationToSeparateFileIntention.kt rename to idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveDeclarationToSeparateFileIntention.kt index 3665c972609..49ba4beec3a 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/MoveDeclarationToSeparateFileIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveDeclarationToSeparateFileIntention.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations +package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations import com.intellij.codeInsight.intention.LowPriorityAction import com.intellij.codeInsight.navigation.NavigationUtil @@ -27,7 +27,7 @@ import com.intellij.refactoring.util.CommonRefactoringUtil import org.jetbrains.kotlin.idea.intentions.SelfTargetingRangeIntention import org.jetbrains.kotlin.idea.quickfix.moveCaret import org.jetbrains.kotlin.idea.refactoring.createKotlinFile -import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.ui.MoveKotlinTopLevelDeclarationsDialog +import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui.MoveKotlinTopLevelDeclarationsDialog import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtClassOrObject @@ -86,12 +86,13 @@ class MoveDeclarationToSeparateFileIntention : } return } - val moveTarget = KotlinMoveTargetForDeferredFile(project, packageName) { + val moveTarget = KotlinMoveTargetForDeferredFile(packageName) { createKotlinFile(targetFileName, directory, packageName.asString()) } - val moveOptions = MoveKotlinTopLevelDeclarationsOptions( + val moveOptions = MoveDeclarationsDescriptor( elementsToMove = listOf(element), moveTarget = moveTarget, + delegate = MoveDeclarationsDelegate.TopLevel, searchInCommentsAndStrings = false, searchInNonCode = false, updateInternalReferences = true, @@ -102,6 +103,6 @@ class MoveDeclarationToSeparateFileIntention : FileEditorManager.getInstance(project).selectedTextEditor?.moveCaret(newDeclaration.startOffset + originalOffset) } ) - MoveKotlinTopLevelDeclarationsProcessor(project, moveOptions).run() + MoveKotlinDeclarationsProcessor(project, moveOptions).run() } } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveDeclarationsDelegate.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveDeclarationsDelegate.kt new file mode 100644 index 00000000000..c405b7443df --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveDeclarationsDelegate.kt @@ -0,0 +1,180 @@ +/* + * Copyright 2010-2016 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.moveDeclarations + +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiElement +import com.intellij.refactoring.move.moveInner.MoveInnerClassUsagesHandler +import com.intellij.refactoring.util.MoveRenameUsageInfo +import com.intellij.usageView.UsageInfo +import com.intellij.util.containers.MultiMap +import org.jetbrains.kotlin.asJava.toLightClass +import org.jetbrains.kotlin.asJava.unwrapped +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor +import org.jetbrains.kotlin.idea.refactoring.move.* +import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject +import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelector + +sealed class MoveDeclarationsDelegate { + abstract fun getOriginalContainerFqName(descriptor: MoveDeclarationsDescriptor, originalFile: KtFile): FqName + abstract fun getContainerChangeInfo(originalDeclaration: KtNamedDeclaration, moveTarget: KotlinMoveTarget): ContainerChangeInfo + abstract fun findUsages(descriptor: MoveDeclarationsDescriptor): List + abstract fun collectConflicts(usages: MutableList, conflicts: MultiMap) + abstract fun preprocessDeclaration(descriptor: MoveDeclarationsDescriptor, originalDeclaration: KtNamedDeclaration) + abstract fun preprocessUsages(project: Project, usages: List) + + object TopLevel : MoveDeclarationsDelegate() { + override fun getOriginalContainerFqName(descriptor: MoveDeclarationsDescriptor, originalFile: KtFile) = originalFile.packageFqName + + override fun getContainerChangeInfo(originalDeclaration: KtNamedDeclaration, moveTarget: KotlinMoveTarget): ContainerChangeInfo { + return ContainerChangeInfo(ContainerInfo.Package(originalDeclaration.getContainingKtFile().packageFqName), + ContainerInfo.Package(moveTarget.targetContainerFqName!!)) + } + + override fun findUsages(descriptor: MoveDeclarationsDescriptor): List = emptyList() + + override fun collectConflicts(usages: MutableList, conflicts: MultiMap) { + + } + + override fun preprocessDeclaration(descriptor: MoveDeclarationsDescriptor, originalDeclaration: KtNamedDeclaration) { + + } + + override fun preprocessUsages(project: Project, usages: List) { + + } + } + + class NestedClass( + val newClassName: String? = null, + val outerInstanceParameterName: String? = null + ) : MoveDeclarationsDelegate() { + override fun getOriginalContainerFqName(descriptor: MoveDeclarationsDescriptor, originalFile: KtFile): FqName { + return descriptor.elementsToMove.first().containingClassOrObject!!.fqName!! + } + + override fun getContainerChangeInfo(originalDeclaration: KtNamedDeclaration, moveTarget: KotlinMoveTarget): ContainerChangeInfo { + val originalInfo = ContainerInfo.Class(originalDeclaration.containingClassOrObject!!.fqName!!) + val movingToClass = (moveTarget as? KotlinMoveTargetForExistingElement)?.targetElement is KtClassOrObject + val newInfo = if (movingToClass) { + ContainerInfo.Class(moveTarget.targetContainerFqName!!) + } else { + ContainerInfo.Package(moveTarget.targetContainerFqName!!) + } + return ContainerChangeInfo(originalInfo, newInfo) + } + + override fun findUsages(descriptor: MoveDeclarationsDescriptor): List { + val classToMove = descriptor.elementsToMove.singleOrNull() as? KtClass ?: return emptyList() + return collectOuterInstanceReferences(classToMove) + } + + override fun collectConflicts(usages: MutableList, conflicts: MultiMap) { + val usageIterator = usages.iterator() + while (usageIterator.hasNext()) { + val usage = usageIterator.next(); + val element = usage.element ?: continue + + if (usage is ImplicitCompanionAsDispatchReceiverUsageInfo) { + conflicts.putValue(element, "Implicit companion object will be inaccessible: ${element.text}") + usageIterator.remove() + continue + } + + if (usage !is OuterInstanceReferenceUsageInfo) continue + + if (usage.isIndirectOuter) { + conflicts.putValue(element, "Indirect outer instances won't be extracted: ${element.text}") + usageIterator.remove() + } + + if (usage !is OuterInstanceReferenceUsageInfo.ImplicitReceiver) continue + + val fullCall = usage.callElement?.let { it.getQualifiedExpressionForSelector() ?: it } ?: continue + when { + fullCall is KtQualifiedExpression -> { + conflicts.putValue( + fullCall, + "Qualified call won't be processed: ${fullCall.text}" + ) + usageIterator.remove() + } + + usage.isDoubleReceiver -> { + conflicts.putValue( + fullCall, + "Call with two implicit receivers won't be processed: ${fullCall.text}" + ) + usageIterator.remove() + } + } + } + } + + override fun preprocessDeclaration(descriptor: MoveDeclarationsDescriptor, originalDeclaration: KtNamedDeclaration) { + with(originalDeclaration) { + newClassName?.let { setName(it) } + + if (this is KtClass) { + if ((descriptor.moveTarget as? KotlinMoveTargetForExistingElement)?.targetElement !is KtClassOrObject) { + if (hasModifier(KtTokens.INNER_KEYWORD)) removeModifier(KtTokens.INNER_KEYWORD) + if (hasModifier(KtTokens.PROTECTED_KEYWORD)) removeModifier(KtTokens.PROTECTED_KEYWORD) + } + + if (outerInstanceParameterName != null) { + val type = (containingClassOrObject!!.resolveToDescriptor() as ClassDescriptor).defaultType + val parameter = KtPsiFactory(project) + .createParameter("private val $outerInstanceParameterName: ${IdeDescriptorRenderers.SOURCE_CODE.renderType(type)}") + createPrimaryConstructorParameterListIfAbsent().addParameter(parameter) + } + } + } + } + + override fun preprocessUsages(project: Project, usages: List) { + if (outerInstanceParameterName == null) return + val psiFactory = KtPsiFactory(project) + val newOuterInstanceRef = psiFactory.createExpression(outerInstanceParameterName) + + for (usage in usages) { + val referencedNestedClass = (usage as? MoveRenameUsageInfo)?.referencedElement?.unwrapped as? KtClassOrObject + val outerClass = referencedNestedClass?.containingClassOrObject + val lightOuterClass = outerClass?.toLightClass() + if (lightOuterClass != null) { + MoveInnerClassUsagesHandler.EP_NAME + .forLanguage(usage.element!!.language) + ?.correctInnerClassUsage(usage, lightOuterClass) + } + + when (usage) { + is OuterInstanceReferenceUsageInfo.ExplicitThis -> { + usage.expression?.replace(newOuterInstanceRef) + } + is OuterInstanceReferenceUsageInfo.ImplicitReceiver -> { + usage.callElement?.let { it.replace(psiFactory.createExpressionByPattern("$0.$1", outerInstanceParameterName, it)) } + } + } + } + } + } +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/MoveKotlinTopLevelDeclarationsHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsHandler.kt similarity index 95% rename from idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/MoveKotlinTopLevelDeclarationsHandler.kt rename to idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsHandler.kt index 715b563c121..b41e9836b64 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/MoveKotlinTopLevelDeclarationsHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsHandler.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations +package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations import com.intellij.openapi.actionSystem.DataContext import com.intellij.openapi.actionSystem.LangDataKeys @@ -32,11 +32,11 @@ import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackages import com.intellij.refactoring.util.CommonRefactoringUtil import org.jetbrains.kotlin.idea.core.getPackage import org.jetbrains.kotlin.idea.refactoring.canRefactor -import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.ui.MoveKotlinTopLevelDeclarationsDialog +import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui.MoveKotlinTopLevelDeclarationsDialog import org.jetbrains.kotlin.psi.* import java.util.* -class MoveKotlinTopLevelDeclarationsHandler : MoveHandlerDelegate() { +class MoveKotlinDeclarationsHandler : MoveHandlerDelegate() { private fun getSourceDirectories(elements: Array) = elements.mapTo(LinkedHashSet()) { it.containingFile?.parent } private fun doMoveWithCheck( diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/MoveKotlinTopLevelDeclarationsProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsProcessor.kt similarity index 74% rename from idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/MoveKotlinTopLevelDeclarationsProcessor.kt rename to idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsProcessor.kt index 5722c3777fe..2104746a755 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/MoveKotlinTopLevelDeclarationsProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsProcessor.kt @@ -14,8 +14,9 @@ * limitations under the License. */ -package org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations +package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations +import com.intellij.ide.util.EditorHelper import com.intellij.openapi.project.Project import com.intellij.openapi.util.Ref import com.intellij.openapi.util.text.StringUtil @@ -25,16 +26,17 @@ import com.intellij.refactoring.BaseRefactoringProcessor import com.intellij.refactoring.move.MoveCallback import com.intellij.refactoring.move.MoveMultipleElementsViewDescriptor import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassHandler -import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesUtil import com.intellij.refactoring.rename.RenameUtil import com.intellij.refactoring.util.MoveRenameUsageInfo import com.intellij.refactoring.util.NonCodeUsageInfo import com.intellij.refactoring.util.RefactoringUIUtil import com.intellij.refactoring.util.TextOccurrencesUtil import com.intellij.usageView.UsageInfo +import com.intellij.usageView.UsageViewBundle import com.intellij.usageView.UsageViewDescriptor import com.intellij.usageView.UsageViewUtil import com.intellij.util.IncorrectOperationException +import com.intellij.util.SmartList import com.intellij.util.VisibilityUtil import com.intellij.util.containers.MultiMap import gnu.trove.THashMap @@ -54,9 +56,8 @@ import org.jetbrains.kotlin.idea.refactoring.move.* import org.jetbrains.kotlin.idea.refactoring.move.moveFilesOrDirectories.MoveKotlinClassHandler import org.jetbrains.kotlin.idea.references.KtSimpleNameReference.ShorteningMode import org.jetbrains.kotlin.idea.search.projectScope -import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi.KtModifierListOwner -import org.jetbrains.kotlin.psi.KtNamedDeclaration +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext import org.jetbrains.kotlin.psi.psiUtil.isAncestor import org.jetbrains.kotlin.psi.psiUtil.isInsideOf import org.jetbrains.kotlin.psi.psiUtil.isPrivate @@ -64,58 +65,64 @@ import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.utils.keysToMap import java.util.* -interface Mover: (KtNamedDeclaration, KtFile) -> KtNamedDeclaration { - object Default: Mover { - override fun invoke(originalElement: KtNamedDeclaration, targetFile: KtFile): KtNamedDeclaration { - val newElement = targetFile.add(originalElement) as KtNamedDeclaration - originalElement.deleteSingle() - return newElement +interface Mover: (KtNamedDeclaration, KtElement) -> KtNamedDeclaration { + object Default : Mover { + override fun invoke(originalElement: KtNamedDeclaration, targetContainer: KtElement): KtNamedDeclaration { + return when (targetContainer) { + is KtFile -> targetContainer.add(originalElement) as KtNamedDeclaration + is KtClassOrObject -> targetContainer.addDeclaration(originalElement) as KtNamedDeclaration + else -> error("Unexpected element: ${targetContainer.getElementTextWithContext()}") + }.apply { originalElement.deleteSingle() } } } - object Idle: Mover { - override fun invoke(originalElement: KtNamedDeclaration, targetFile: KtFile) = originalElement + object Idle : Mover { + override fun invoke(originalElement: KtNamedDeclaration, targetContainer: KtElement) = originalElement } } -class MoveKotlinTopLevelDeclarationsOptions( +class MoveDeclarationsDescriptor( val elementsToMove: Collection, val moveTarget: KotlinMoveTarget, + val delegate: MoveDeclarationsDelegate, val searchInCommentsAndStrings: Boolean = true, val searchInNonCode: Boolean = true, val updateInternalReferences: Boolean = true, val deleteSourceFiles: Boolean = false, - val moveCallback: MoveCallback? = null + val moveCallback: MoveCallback? = null, + val openInEditor: Boolean = false ) -class MoveKotlinTopLevelDeclarationsProcessor( +class MoveKotlinDeclarationsProcessor( val project: Project, - val options: MoveKotlinTopLevelDeclarationsOptions, + val descriptor: MoveDeclarationsDescriptor, val mover: Mover = Mover.Default) : BaseRefactoringProcessor(project) { companion object { private val REFACTORING_NAME: String = KotlinRefactoringBundle.message("refactoring.move.top.level.declarations") } private var nonCodeUsages: Array? = null - private val elementsToMove = options.elementsToMove.filter { e -> e.containingFile != options.moveTarget.getTargetPsiIfExists(e) } + private val elementsToMove = descriptor.elementsToMove.filter { e -> e.parent != descriptor.moveTarget.getTargetPsiIfExists(e) } private val kotlinToLightElementsBySourceFile = elementsToMove .groupBy { it.getContainingKtFile() } .mapValues { it.value.keysToMap { it.toLightElements() } } private val conflicts = MultiMap() override fun createUsageViewDescriptor(usages: Array): UsageViewDescriptor { - return MoveMultipleElementsViewDescriptor( - elementsToMove.toTypedArray(), - MoveClassesOrPackagesUtil.getPackageName(options.moveTarget.packageWrapper) - ) + val targetContainerFqName = descriptor.moveTarget.targetContainerFqName?.let { + if (it.isRoot) UsageViewBundle.message("default.package.presentable.name") else it.asString() + } + return MoveMultipleElementsViewDescriptor(elementsToMove.toTypedArray(), targetContainerFqName) } + private val usagesToProcessBeforeMove = SmartList() + public override fun findUsages(): Array { - val newPackageName = options.moveTarget.packageWrapper?.qualifiedName ?: "" + val newContainerName = descriptor.moveTarget.targetContainerFqName?.asString() ?: "" fun collectUsages(kotlinToLightElements: Map>, result: MutableList) { kotlinToLightElements.values.flatMap { it }.flatMapTo(result) { lightElement -> - val newFqName = StringUtil.getQualifiedName(newPackageName, lightElement.name) + val newFqName = StringUtil.getQualifiedName(newContainerName, lightElement.name) val foundReferences = HashSet() val projectScope = lightElement.project.projectScope() @@ -133,8 +140,8 @@ class MoveKotlinTopLevelDeclarationsProcessor( TextOccurrencesUtil.findNonCodeUsages( lightElement, name, - options.searchInCommentsAndStrings, - options.searchInNonCode, + descriptor.searchInCommentsAndStrings, + descriptor.searchInNonCode, newFqName, results ) @@ -169,8 +176,9 @@ class MoveKotlinTopLevelDeclarationsProcessor( val container = element.getUsageContext() if (!declarationToContainers.getOrPut(declaration) { HashSet() }.add(container)) continue + // todo: ok for now, will be replaced by proper visibility analysis val currentPackage = element.containingFile?.containingDirectory?.getPackage() - if (currentPackage?.qualifiedName == newPackageName) continue + if (currentPackage?.qualifiedName == newContainerName) continue conflicts.putValue( declaration, @@ -184,7 +192,7 @@ class MoveKotlinTopLevelDeclarationsProcessor( } fun collectConflictsInDeclarations() { - if (newPackageName == UNKNOWN_PACKAGE_FQ_NAME.asString()) return + if (newContainerName == UNKNOWN_PACKAGE_FQ_NAME.asString()) return val declarationToReferenceTargets = HashMap>() for (declaration in elementsToMove) { @@ -207,8 +215,9 @@ class MoveKotlinTopLevelDeclarationsProcessor( if (!declarationToReferenceTargets.getOrPut(declaration) { HashSet() }.add(refTarget)) continue + // todo: ok for now, will be replaced by proper visibility analysis val currentPackage = declaration.containingFile?.containingDirectory?.getPackage() - if (currentPackage?.qualifiedName == newPackageName) continue + if (currentPackage?.qualifiedName == newContainerName) continue conflicts.putValue( declaration, @@ -224,14 +233,29 @@ class MoveKotlinTopLevelDeclarationsProcessor( val usages = ArrayList() for ((sourceFile, kotlinToLightElements) in kotlinToLightElementsBySourceFile) { - // No need to find and process usages if package is not changed - if (sourceFile.packageFqName.asString() == newPackageName) return UsageInfo.EMPTY_ARRAY + kotlinToLightElements.keys.forEach { + if (descriptor.updateInternalReferences) { + val packageNameInfo = descriptor.delegate.getContainerChangeInfo(it, descriptor.moveTarget) + val (usagesToProcessLater, usagesToProcessEarly) = it + .getInternalReferencesToUpdateOnPackageNameChange(packageNameInfo) + .partition { it is MoveRenameUsageInfoForExtension } + usages.addAll(usagesToProcessLater) + usagesToProcessBeforeMove.addAll(usagesToProcessEarly) + } + } + // No need to find and process usages if package is not changed + val originalContainerName = descriptor.delegate.getOriginalContainerFqName(descriptor, sourceFile).asString() + if (originalContainerName == newContainerName) return UsageInfo.EMPTY_ARRAY + + usages += descriptor.delegate.findUsages(descriptor) collectUsages(kotlinToLightElements, usages) collectConflictsInUsages(usages) collectConflictsInDeclarations() + descriptor.delegate.collectConflicts(usages, conflicts) } + descriptor.delegate.collectConflicts(usagesToProcessBeforeMove, conflicts) return UsageViewUtil.removeDuplicatedUsages(usages.toTypedArray()) } @@ -241,27 +265,15 @@ class MoveKotlinTopLevelDeclarationsProcessor( } override fun performRefactoring(usages: Array) { - fun moveDeclaration( - declaration: KtNamedDeclaration, - moveTarget: KotlinMoveTarget, - usagesToProcessAfterMove: MutableList - ): KtNamedDeclaration? { + fun moveDeclaration(declaration: KtNamedDeclaration, moveTarget: KotlinMoveTarget): KtNamedDeclaration? { val file = declaration.containingFile as? KtFile assert(file != null) { "${declaration.javaClass}: ${declaration.text}" } - val targetFile = moveTarget.getOrCreateTargetPsi(declaration) as? KtFile - ?: throw AssertionError("Couldn't create Kotlin file for: ${declaration.javaClass}: ${declaration.text}") + val targetContainer = moveTarget.getOrCreateTargetPsi(declaration) + ?: throw AssertionError("Couldn't create Kotlin file for: ${declaration.javaClass}: ${declaration.text}") - if (options.updateInternalReferences) { - val packageNameInfo = PackageNameInfo(file!!.packageFqName, targetFile.packageFqName.toUnsafe()) - val (usagesToProcessLater, usagesToProcessNow) = declaration - .getInternalReferencesToUpdateOnPackageNameChange(packageNameInfo) - .partition { it is MoveRenameUsageInfoForExtension } - postProcessMoveUsages(usagesToProcessNow, shorteningMode = ShorteningMode.NO_SHORTENING) - usagesToProcessAfterMove.addAll(usagesToProcessLater) - } - - val newElement = mover(declaration, targetFile) + descriptor.delegate.preprocessDeclaration(descriptor, declaration) + val newElement = mover(declaration, targetContainer) newElement.addToShorteningWaitSet() @@ -271,6 +283,10 @@ class MoveKotlinTopLevelDeclarationsProcessor( try { val usageList = usages.toArrayList() + descriptor.delegate.preprocessUsages(project, usageList) + + postProcessMoveUsages(usagesToProcessBeforeMove, shorteningMode = ShorteningMode.NO_SHORTENING) + val oldToNewElementsMapping = THashMap( object: TObjectHashingStrategy { override fun equals(e1: PsiElement?, e2: PsiElement?): Boolean { @@ -293,7 +309,7 @@ class MoveKotlinTopLevelDeclarationsProcessor( ) for ((sourceFile, kotlinToLightElements) in kotlinToLightElementsBySourceFile) { for ((oldDeclaration, oldLightElements) in kotlinToLightElements) { - val newDeclaration = moveDeclaration(oldDeclaration, options.moveTarget, usageList) + val newDeclaration = moveDeclaration(oldDeclaration, descriptor.moveTarget) if (newDeclaration == null) { for (oldElement in oldLightElements) { oldToNewElementsMapping[oldElement] = oldElement @@ -307,9 +323,13 @@ class MoveKotlinTopLevelDeclarationsProcessor( for ((oldElement, newElement) in oldLightElements.asSequence().zip(newDeclaration.toLightElements().asSequence())) { oldToNewElementsMapping[oldElement] = newElement } + + if (descriptor.openInEditor) { + EditorHelper.openInEditor(newDeclaration) + } } - if (options.deleteSourceFiles) { + if (descriptor.deleteSourceFiles) { sourceFile.delete() } } @@ -324,7 +344,7 @@ class MoveKotlinTopLevelDeclarationsProcessor( override fun performPsiSpoilingRefactoring() { nonCodeUsages?.let { nonCodeUsages -> RenameUtil.renameNonCodeUsages(myProject, nonCodeUsages) } - options.moveCallback?.refactoringCompleted() + descriptor.moveCallback?.refactoringCompleted() } fun execute(usages: List) { diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/ui/KotlinAwareMoveFilesOrDirectoriesDialog.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/KotlinAwareMoveFilesOrDirectoriesDialog.kt similarity index 99% rename from idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/ui/KotlinAwareMoveFilesOrDirectoriesDialog.kt rename to idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/KotlinAwareMoveFilesOrDirectoriesDialog.kt index cb95542d333..10695342ff5 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/ui/KotlinAwareMoveFilesOrDirectoriesDialog.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/KotlinAwareMoveFilesOrDirectoriesDialog.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.ui +package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui import com.intellij.ide.util.DirectoryUtil import com.intellij.ide.util.PropertiesComponent diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/ui/MoveKotlinTopLevelDeclarationsDialog.form b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinTopLevelDeclarationsDialog.form similarity index 99% rename from idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/ui/MoveKotlinTopLevelDeclarationsDialog.form rename to idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinTopLevelDeclarationsDialog.form index 82dad3b8336..8f750cbbf14 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/ui/MoveKotlinTopLevelDeclarationsDialog.form +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinTopLevelDeclarationsDialog.form @@ -1,5 +1,5 @@ -
+ diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/ui/MoveKotlinTopLevelDeclarationsDialog.java b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinTopLevelDeclarationsDialog.java similarity index 97% rename from idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/ui/MoveKotlinTopLevelDeclarationsDialog.java rename to idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinTopLevelDeclarationsDialog.java index 14c3a7e2259..0780f307ca0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveTopLevelDeclarations/ui/MoveKotlinTopLevelDeclarationsDialog.java +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ui/MoveKotlinTopLevelDeclarationsDialog.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.ui; +package org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.event.DocumentAdapter; @@ -69,7 +69,7 @@ import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberInfo; import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberSelectionPanel; import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberSelectionTable; import org.jetbrains.kotlin.idea.refactoring.move.MoveUtilsKt; -import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.*; +import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.*; import org.jetbrains.kotlin.idea.util.application.ApplicationUtilsKt; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.psi.KtFile; @@ -533,7 +533,6 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { } return new KotlinMoveTargetForDeferredFile( - myProject, new FqName(getTargetPackage()), new Function1() { @Override @@ -556,7 +555,7 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { return null; } - return new KotlinMoveTargetForExistingFile(jetFile); + return new KotlinMoveTargetForExistingElement(jetFile); } File targetDir = targetFile.getParentFile(); @@ -570,7 +569,6 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { } return new KotlinMoveTargetForDeferredFile( - myProject, new FqName(psiPackage.getQualifiedName()), new Function1() { @Override @@ -757,10 +755,18 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog { deleteSourceFile = ret == Messages.YES; } - MoveKotlinTopLevelDeclarationsOptions options = new MoveKotlinTopLevelDeclarationsOptions( - elementsToMove, target, isSearchInComments(), isSearchInNonJavaFiles(), true, deleteSourceFile, moveCallback + MoveDeclarationsDescriptor options = new MoveDeclarationsDescriptor( + elementsToMove, + target, + MoveDeclarationsDelegate.TopLevel.INSTANCE, + isSearchInComments(), + isSearchInNonJavaFiles(), + true, + deleteSourceFile, + moveCallback, + false ); - invokeRefactoring(new MoveKotlinTopLevelDeclarationsProcessor(myProject, options, Mover.Default.INSTANCE)); + invokeRefactoring(new MoveKotlinDeclarationsProcessor(myProject, options, Mover.Default.INSTANCE)); } catch (IncorrectOperationException e) { CommonRefactoringUtil.showErrorMessage(RefactoringBundle.message("error.title"), e.getMessage(), null, myProject); diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/KotlinMoveDirectoryWithClassesHelper.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/KotlinMoveDirectoryWithClassesHelper.kt index 57c2d44708c..2b33f226d99 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/KotlinMoveDirectoryWithClassesHelper.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/KotlinMoveDirectoryWithClassesHelper.kt @@ -27,7 +27,7 @@ import com.intellij.usageView.UsageInfo import com.intellij.util.Function import org.jetbrains.kotlin.idea.core.getPackage import org.jetbrains.kotlin.idea.refactoring.invokeOnceOnCommandFinish -import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.MoveKotlinTopLevelDeclarationsProcessor +import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.MoveKotlinDeclarationsProcessor import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtFile import java.util.ArrayList @@ -37,13 +37,13 @@ class KotlinMoveDirectoryWithClassesHelper : MoveDirectoryWithClassesHelper() { private class FileUsagesWrapper( val psiFile: PsiFile, val usages: List, - val moveDeclarationsProcessor: MoveKotlinTopLevelDeclarationsProcessor? + val moveDeclarationsProcessor: MoveKotlinDeclarationsProcessor? ) : UsageInfo(psiFile) private class MoveContext( val newParent: PsiDirectory, val internalUsages: MoveKotlinFileHandler.InternalUsagesWrapper, - val moveDeclarationsProcessor: MoveKotlinTopLevelDeclarationsProcessor? + val moveDeclarationsProcessor: MoveKotlinDeclarationsProcessor? ) private val fileHandler = MoveKotlinFileHandler() 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 d536b574bda..e128915f058 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 @@ -28,7 +28,7 @@ import org.jetbrains.kotlin.idea.core.getPackage import org.jetbrains.kotlin.idea.core.packageMatchesDirectory import org.jetbrains.kotlin.idea.refactoring.hasIdentifiersOnly import org.jetbrains.kotlin.idea.refactoring.move.* -import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.* +import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.* import org.jetbrains.kotlin.name.FqNameUnsafe import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtNamedDeclaration @@ -42,48 +42,50 @@ class MoveKotlinFileHandler : MoveFileHandler() { // so that it can be kept in the transition map private class MoveContext( psiManager: PsiManager, - val declarationMoveProcessor: MoveKotlinTopLevelDeclarationsProcessor + val declarationMoveProcessor: MoveKotlinDeclarationsProcessor ): LightElement(psiManager, KotlinLanguage.INSTANCE) { override fun toString() = "" } - private fun KtFile.getPackageNameInfo(newParent: PsiDirectory?, clearUserData: Boolean): PackageNameInfo? { + private fun KtFile.getPackageNameInfo(newParent: PsiDirectory?, clearUserData: Boolean): ContainerChangeInfo? { val shouldUpdatePackageDirective = updatePackageDirective ?: packageMatchesDirectory() updatePackageDirective = if (clearUserData) null else shouldUpdatePackageDirective if (!shouldUpdatePackageDirective) return null val oldPackageName = packageFqName - val newPackage = newParent?.getPackage() ?: return PackageNameInfo(oldPackageName, UNKNOWN_PACKAGE_FQ_NAME) + val newPackage = newParent?.getPackage() ?: return ContainerChangeInfo(ContainerInfo.Package(oldPackageName), + ContainerInfo.UnknownPackage) val newPackageName = FqNameUnsafe(newPackage.qualifiedName) if (oldPackageName.asString() == newPackageName.asString()) return null - if (newPackageName != UNKNOWN_PACKAGE_FQ_NAME && !newPackageName.hasIdentifiersOnly()) return null + if (!newPackageName.hasIdentifiersOnly()) return null - return PackageNameInfo(oldPackageName, newPackageName) + return ContainerChangeInfo(ContainerInfo.Package(oldPackageName), ContainerInfo.Package(newPackageName.toSafe())) } - fun initMoveProcessor(psiFile: PsiFile, newParent: PsiDirectory?): MoveKotlinTopLevelDeclarationsProcessor? { + fun initMoveProcessor(psiFile: PsiFile, newParent: PsiDirectory?): MoveKotlinDeclarationsProcessor? { if (psiFile !is KtFile) return null val packageNameInfo = psiFile.getPackageNameInfo(newParent, false) ?: return null val project = psiFile.project - val newPackageName = packageNameInfo.newPackageName - val moveTarget = when (newPackageName) { - UNKNOWN_PACKAGE_FQ_NAME -> EmptyKotlinMoveTarget + val newPackage = packageNameInfo.newContainer + val moveTarget = when (newPackage) { + ContainerInfo.UnknownPackage -> EmptyKotlinMoveTarget - else -> KotlinMoveTargetForDeferredFile(project, newPackageName.toSafe()) { + else -> KotlinMoveTargetForDeferredFile(newPackage.fqName!!) { MoveFilesOrDirectoriesUtil.doMoveFile(psiFile, newParent) newParent?.findFile(psiFile.name) as? KtFile } } - val declarationMoveProcessor = MoveKotlinTopLevelDeclarationsProcessor( + val declarationMoveProcessor = MoveKotlinDeclarationsProcessor( project, - MoveKotlinTopLevelDeclarationsOptions( + MoveDeclarationsDescriptor( elementsToMove = psiFile.declarations.filterIsInstance(), moveTarget = moveTarget, + delegate = MoveDeclarationsDelegate.TopLevel, updateInternalReferences = false ), Mover.Idle @@ -126,9 +128,7 @@ class MoveKotlinFileHandler : MoveFileHandler() { if (file !is KtFile) return val newDirectory = file.parent ?: return val packageNameInfo = file.getPackageNameInfo(newDirectory, true) ?: return - val newPackageName = packageNameInfo.newPackageName - assert(newPackageName.isSafe) { newPackageName } - file.packageDirective?.fqName = newPackageName.toSafe() + file.packageDirective?.fqName = packageNameInfo.newContainer.fqName!! } override fun retargetUsages(usageInfos: List?, oldToNewMap: Map) { @@ -136,7 +136,7 @@ class MoveKotlinFileHandler : MoveFileHandler() { retargetUsages(usageInfos, moveContext.declarationMoveProcessor) } - fun retargetUsages(usageInfos: List?, moveDeclarationsProcessor: MoveKotlinTopLevelDeclarationsProcessor) { + fun retargetUsages(usageInfos: List?, moveDeclarationsProcessor: MoveKotlinDeclarationsProcessor) { postProcessMoveUsages(usageInfos?.firstIsInstanceOrNull()?.usages ?: emptyList()) moveDeclarationsProcessor.project.runWithElementsToShortenIsEmptyIgnored { usageInfos?.let { moveDeclarationsProcessor.execute(it) } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveUtils.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveUtils.kt index 717042dbfd1..fa17bdaf77b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveUtils.kt @@ -22,6 +22,7 @@ import com.intellij.openapi.ui.DialogWrapper import com.intellij.openapi.util.Comparing import com.intellij.openapi.util.Key import com.intellij.psi.* +import com.intellij.psi.util.PsiTreeUtil import com.intellij.refactoring.RefactoringBundle import com.intellij.refactoring.RefactoringSettings import com.intellij.refactoring.copy.CopyFilesOrDirectoriesHandler @@ -36,17 +37,20 @@ import com.intellij.refactoring.util.MoveRenameUsageInfo import com.intellij.refactoring.util.NonCodeUsageInfo import com.intellij.usageView.UsageInfo import com.intellij.util.IncorrectOperationException +import com.intellij.util.SmartList import org.jetbrains.kotlin.asJava.namedUnwrappedElement import org.jetbrains.kotlin.asJava.unwrapped import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.idea.KotlinFileType +import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor +import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde import org.jetbrains.kotlin.idea.codeInsight.KotlinFileReferencesResolver import org.jetbrains.kotlin.idea.imports.importableFqName import org.jetbrains.kotlin.idea.refactoring.fqName.isImported import org.jetbrains.kotlin.idea.refactoring.isInJavaSourceRoot -import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.ui.KotlinAwareMoveFilesOrDirectoriesDialog +import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.ui.KotlinAwareMoveFilesOrDirectoriesDialog import org.jetbrains.kotlin.idea.references.KtReference import org.jetbrains.kotlin.idea.references.KtSimpleNameReference import org.jetbrains.kotlin.idea.references.KtSimpleNameReference.ShorteningMode @@ -60,22 +64,48 @@ import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.descriptorUtil.getImportableDescriptor +import org.jetbrains.kotlin.resolve.descriptorUtil.parents +import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver +import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver import org.jetbrains.kotlin.utils.addIfNotNull import java.util.* val UNKNOWN_PACKAGE_FQ_NAME = FqNameUnsafe("org.jetbrains.kotlin.idea.refactoring.move.") -class PackageNameInfo(val oldPackageName: FqName, val newPackageName: FqNameUnsafe) +sealed class ContainerInfo() { + abstract val fqName: FqName? + abstract fun matches(descriptor: DeclarationDescriptor): Boolean -fun KtElement.getInternalReferencesToUpdateOnPackageNameChange(packageNameInfo: PackageNameInfo): List { + object UnknownPackage : ContainerInfo() { + override val fqName = null + override fun matches(descriptor: DeclarationDescriptor) = descriptor is PackageViewDescriptor + } + + class Package(override val fqName: FqName): ContainerInfo() { + override fun matches(descriptor: DeclarationDescriptor): Boolean { + return descriptor is PackageFragmentDescriptor && descriptor.fqName == fqName + } + } + + class Class(override val fqName: FqName) : ContainerInfo() { + override fun matches(descriptor: DeclarationDescriptor): Boolean { + return descriptor is ClassDescriptor && descriptor.importableFqName == fqName + } + } +} + +data class ContainerChangeInfo(val oldContainer: ContainerInfo, val newContainer: ContainerInfo) + +fun KtElement.getInternalReferencesToUpdateOnPackageNameChange(containerChangeInfo: ContainerChangeInfo): List { val usages = ArrayList() - lazilyProcessInternalReferencesToUpdateOnPackageNameChange(packageNameInfo) { expr, factory -> usages.addIfNotNull(factory(expr)) } + lazilyProcessInternalReferencesToUpdateOnPackageNameChange(containerChangeInfo) { expr, factory -> usages.addIfNotNull(factory(expr)) } return usages } fun KtElement.lazilyProcessInternalReferencesToUpdateOnPackageNameChange( - packageNameInfo: PackageNameInfo, + containerChangeInfo: ContainerChangeInfo, body: (originalRefExpr: KtSimpleNameExpression, usageFactory: (KtSimpleNameExpression) -> UsageInfo?) -> Unit ) { val file = containingFile as? KtFile ?: return @@ -99,46 +129,61 @@ fun KtElement.lazilyProcessInternalReferencesToUpdateOnPackageNameChange( val declaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, descriptor) ?: return null // Special case for enum entry superclass references (they have empty text and don't need to be processed by the refactoring) - if (refExpr.textRange.isEmpty) { - return null - } + if (refExpr.textRange.isEmpty) return null + + if (descriptor is ClassDescriptor && descriptor.isInner && refExpr.parent is KtCallExpression) return null val isCallable = descriptor is CallableDescriptor val isExtension = isCallable && declaration.isExtensionDeclaration() - if (isCallable && !isExtension) { + if (isCallable) { val containingDescriptor = descriptor.containingDeclaration - if (refExpr.getReceiverExpression() != null) { - return fun(refExpr: KtSimpleNameExpression): UsageInfo? { - val receiver = refExpr.getReceiverExpression() ?: return null - val receiverRef = receiver.getQualifiedElementSelector() as? KtSimpleNameExpression ?: return null - if (bindingContext[BindingContext.QUALIFIER, receiverRef] == null) return null - return processReference(receiverRef, bindingContext)?.invoke(receiverRef) + if (isExtension && containingDescriptor is ClassDescriptor) { + val implicitClass = (refExpr.getResolvedCall(bindingContext)?.dispatchReceiver as? ImplicitClassReceiver)?.classDescriptor + if (DescriptorUtils.isCompanionObject(implicitClass)) { + return { ImplicitCompanionAsDispatchReceiverUsageInfo(it) } } + return null + } + if (!isExtension) { + if (refExpr.getReceiverExpression() != null) { + return fun(refExpr: KtSimpleNameExpression): UsageInfo? { + val receiver = refExpr.getReceiverExpression() ?: return null + val receiverRef = receiver.getQualifiedElementSelector() as? KtSimpleNameExpression ?: return null + if (bindingContext[BindingContext.QUALIFIER, receiverRef] == null) return null + return processReference(receiverRef, bindingContext)?.invoke(receiverRef) + } + } + if (!(containingDescriptor is PackageFragmentDescriptor + || containingDescriptor is ClassDescriptor && containingDescriptor.kind == ClassKind.OBJECT)) return null } - if (containingDescriptor !is PackageFragmentDescriptor) return null } val fqName = DescriptorUtils.getFqName(descriptor) if (!fqName.isSafe) return null - val packageName = DescriptorUtils.getParentOfType(descriptor, PackageFragmentDescriptor::class.java, false)?.let { - DescriptorUtils.getFqName(it).toSafe() - } + val (oldContainer, newContainer) = containerChangeInfo - val oldPackageName = packageNameInfo.oldPackageName - val newPackageName = packageNameInfo.newPackageName + val containerFqName = descriptor + .parents + .mapNotNull { + when { + oldContainer.matches(it) -> oldContainer.fqName + newContainer.matches(it) -> newContainer.fqName + else -> null + } + } + .firstOrNull() fun doCreateUsageInfo(refExpr: KtSimpleNameExpression): UsageInfo? { if (isAncestor(declaration, false)) { if (descriptor.importableFqName == null) return null - if (descriptor is ClassDescriptor && descriptor.isInner && refExpr.parent is KtCallExpression) return null if (isUnqualifiedExtensionReference(refExpr.mainReference, declaration)) return null - if (packageName == null || !newPackageName.isSafe) return null + if (containerFqName == null || newContainer is ContainerInfo.UnknownPackage) return null return fqName.asString().let { - val prefix = packageName.asString() + val prefix = containerFqName.asString() val prefixOffset = it.indexOf(prefix) - val newFqName = FqName(it.replaceRange(prefixOffset..prefixOffset + prefix.length - 1, newPackageName.asString())) + val newFqName = FqName(it.replaceRange(prefixOffset..prefixOffset + prefix.length - 1, newContainer.fqName!!.asString())) MoveRenameSelfUsageInfo(refExpr.mainReference, declaration, newFqName) } } @@ -146,11 +191,8 @@ fun KtElement.lazilyProcessInternalReferencesToUpdateOnPackageNameChange( return createMoveUsageInfoIfPossible(refExpr.mainReference, declaration, false) } - if (!isExtension && - packageName != oldPackageName && - packageName?.asString() != newPackageName.asString() && - !isImported(descriptor)) return null - return ::doCreateUsageInfo + if (isExtension || containerFqName != null || isImported(descriptor)) return ::doCreateUsageInfo + return null } val referenceToContext = KotlinFileReferencesResolver.resolve(file = file, elements = listOf(this)) @@ -163,6 +205,8 @@ fun KtElement.lazilyProcessInternalReferencesToUpdateOnPackageNameChange( } } +class ImplicitCompanionAsDispatchReceiverUsageInfo(callee: KtSimpleNameExpression) : UsageInfo(callee) + class MoveRenameUsageInfoForExtension( element: PsiElement, reference: PsiReference, @@ -276,7 +320,7 @@ fun postProcessMoveUsages(usages: List, val nonCodeUsages = ArrayList() - for (usage in sortedUsages) { + usageLoop@ for (usage in sortedUsages) { when (usage) { is NonCodeUsageInfo -> { nonCodeUsages.add(usage) @@ -295,21 +339,17 @@ fun postProcessMoveUsages(usages: List, is MoveRenameUsageInfo -> { val oldElement = usage.referencedElement!! val newElement = counterpart(oldElement) - usage.reference?.let { - try { - if (it is KtSimpleNameReference) { - it.bindToElement(newElement, shorteningMode) - } - else if (it is PsiReferenceExpression && updateJavaReference(it, oldElement, newElement)) { - } - else { - it.bindToElement(newElement) - } - } - catch (e: IncorrectOperationException) { - // Suppress exception if bindToElement is not implemented + val reference = usage.reference ?: (usage.element as? KtSimpleNameExpression)?.mainReference + try { + when { + reference is KtSimpleNameReference -> reference.bindToElement(newElement, shorteningMode) + reference is PsiReferenceExpression && updateJavaReference(reference, oldElement, newElement) -> continue@usageLoop + else -> reference?.bindToElement(newElement) } } + catch (e: IncorrectOperationException) { + // Suppress exception if bindToElement is not implemented + } } } } @@ -388,3 +428,86 @@ fun moveFilesOrDirectories( show() } } + +sealed class OuterInstanceReferenceUsageInfo(element: PsiElement, val isIndirectOuter: Boolean) : UsageInfo(element) { + class ExplicitThis( + expression: KtThisExpression, + isIndirectOuter: Boolean + ) : OuterInstanceReferenceUsageInfo(expression, isIndirectOuter) { + val expression: KtThisExpression? + get() = element as? KtThisExpression + } + + class ImplicitReceiver( + callElement: KtElement, + isIndirectOuter: Boolean, + val isDoubleReceiver: Boolean + ) : OuterInstanceReferenceUsageInfo(callElement, isIndirectOuter) { + val callElement: KtElement? + get() = element as? KtElement + } +} + +@JvmOverloads +fun traverseOuterInstanceReferences(innerClass: KtClass, stopAtFirst: Boolean, body: (OuterInstanceReferenceUsageInfo) -> Unit = {}): Boolean { + if (!innerClass.isInner()) return false + + val context = innerClass.analyzeFully() + val innerClassDescriptor = innerClass.resolveToDescriptorIfAny() as? ClassDescriptor ?: return false + val outerClassDescriptor = innerClassDescriptor.containingDeclaration as? ClassDescriptor ?: return false + var found = false + innerClass.accept( + object : PsiRecursiveElementWalkingVisitor() { + private fun getOuterInstanceReference(element: PsiElement): OuterInstanceReferenceUsageInfo? { + return when (element) { + is KtThisExpression -> { + val descriptor = context[BindingContext.REFERENCE_TARGET, element.instanceReference] + val isIndirect = when { + descriptor == outerClassDescriptor -> false + DescriptorUtils.isAncestor(descriptor, outerClassDescriptor, true) -> true + else -> return null + } + OuterInstanceReferenceUsageInfo.ExplicitThis(element, isIndirect) + } + is KtSimpleNameExpression -> { + val resolvedCall = element.getResolvedCall(context) ?: return null + val dispatchReceiver = resolvedCall.dispatchReceiver as? ImplicitReceiver + val extensionReceiver = resolvedCall.extensionReceiver as? ImplicitReceiver + var isIndirect = false + val isDoubleReceiver = when { + dispatchReceiver?.declarationDescriptor == outerClassDescriptor -> extensionReceiver != null + extensionReceiver?.declarationDescriptor == outerClassDescriptor -> dispatchReceiver != null + else -> { + isIndirect = true + when { + DescriptorUtils.isAncestor(dispatchReceiver?.declarationDescriptor, outerClassDescriptor, true) -> + extensionReceiver != null + DescriptorUtils.isAncestor(extensionReceiver?.declarationDescriptor, outerClassDescriptor, true) -> + dispatchReceiver != null + else -> return null + } + } + } + OuterInstanceReferenceUsageInfo.ImplicitReceiver(resolvedCall.call.callElement, isIndirect, isDoubleReceiver) + } + else -> null + } + } + + override fun visitElement(element: PsiElement) { + getOuterInstanceReference(element)?.let { + body(it) + found = true + if (stopAtFirst) stopWalking() + return + } + super.visitElement(element) + } + } + ) + return found +} + +fun collectOuterInstanceReferences(innerClass: KtClass): List { + return SmartList().apply { traverseOuterInstanceReferences(innerClass, false) { add(it) } } +} diff --git a/idea/testData/multiFileIntentions/moveDeclarationToSeparateFile/moveClassToExistingFile/moveClassToExistingFile.test b/idea/testData/multiFileIntentions/moveDeclarationToSeparateFile/moveClassToExistingFile/moveClassToExistingFile.test index 0a22c66d7f9..64dceadea3f 100644 --- a/idea/testData/multiFileIntentions/moveDeclarationToSeparateFile/moveClassToExistingFile/moveClassToExistingFile.test +++ b/idea/testData/multiFileIntentions/moveDeclarationToSeparateFile/moveClassToExistingFile/moveClassToExistingFile.test @@ -1,4 +1,4 @@ { "mainFile": "source/test.kt", - "intentionClass": "org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.MoveDeclarationToSeparateFileIntention" + "intentionClass": "org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.MoveDeclarationToSeparateFileIntention" } \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/moveDeclarationToSeparateFile/moveClassToFile/moveClassToFile.test b/idea/testData/multiFileIntentions/moveDeclarationToSeparateFile/moveClassToFile/moveClassToFile.test index 0a22c66d7f9..64dceadea3f 100644 --- a/idea/testData/multiFileIntentions/moveDeclarationToSeparateFile/moveClassToFile/moveClassToFile.test +++ b/idea/testData/multiFileIntentions/moveDeclarationToSeparateFile/moveClassToFile/moveClassToFile.test @@ -1,4 +1,4 @@ { "mainFile": "source/test.kt", - "intentionClass": "org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.MoveDeclarationToSeparateFileIntention" + "intentionClass": "org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.MoveDeclarationToSeparateFileIntention" } \ No newline at end of file diff --git a/idea/testData/multiFileIntentions/moveDeclarationToSeparateFile/moveSingleToFile/moveSingleToFile.test b/idea/testData/multiFileIntentions/moveDeclarationToSeparateFile/moveSingleToFile/moveSingleToFile.test index 02d810e77b3..0a55778dce5 100644 --- a/idea/testData/multiFileIntentions/moveDeclarationToSeparateFile/moveSingleToFile/moveSingleToFile.test +++ b/idea/testData/multiFileIntentions/moveDeclarationToSeparateFile/moveSingleToFile/moveSingleToFile.test @@ -1,5 +1,5 @@ { "mainFile": "source/test.kt", - "intentionClass": "org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.MoveDeclarationToSeparateFileIntention", + "intentionClass": "org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.MoveDeclarationToSeparateFileIntention", "isApplicable": "false" } \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithOuterOuterThis/after/test.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithOuterOuterThis/after/test.kt new file mode 100644 index 00000000000..ad7c5d8634c --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithOuterOuterThis/after/test.kt @@ -0,0 +1,14 @@ +package test + +class A { + inner class OuterOuterY + + inner class B { + inner class C { + fun test() { + OuterOuterY() + this@A.OuterOuterY() + } + } + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithOuterOuterThis/before/test.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithOuterOuterThis/before/test.kt new file mode 100644 index 00000000000..5ddfaf10ff5 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithOuterOuterThis/before/test.kt @@ -0,0 +1,14 @@ +package test + +class A { + inner class OuterOuterY + + inner class B { + inner class C { + fun test() { + OuterOuterY() + this@A.OuterOuterY() + } + } + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithOuterOuterThis/conflicts.txt b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithOuterOuterThis/conflicts.txt new file mode 100644 index 00000000000..39c07d23b25 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithOuterOuterThis/conflicts.txt @@ -0,0 +1,2 @@ +Indirect outer instances won't be extracted: OuterOuterY() +Indirect outer instances won't be extracted: this@A \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithOuterOuterThis/deepInnerToTopLevelWithOuterOuterThis.test b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithOuterOuterThis/deepInnerToTopLevelWithOuterOuterThis.test new file mode 100644 index 00000000000..8dd75509bdc --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithOuterOuterThis/deepInnerToTopLevelWithOuterOuterThis.test @@ -0,0 +1,6 @@ +{ + "mainFile": "test.kt", + "type": "MOVE_KOTLIN_NESTED_CLASS", + "outerInstanceParameter": "a", + "withRuntime": "true" +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/after/C.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/after/C.kt new file mode 100644 index 00000000000..dc74f7e4efa --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/after/C.kt @@ -0,0 +1,26 @@ +package test + +class C(private val b: A.B) { + fun test() { + A.X() + + A.Companion.Y() + A.foo(A.bar) + //1.extFoo(1.extBar) // conflict + + b.OuterY() + b.outerFoo(b.outerBar) + + b.OuterY() + b.outerFoo(b.outerBar) + + A.O.Y() + A.O.foo(A.O.bar) + + with (A.O) { + A.Companion.Y() + foo(bar) + 1.extFoo(1.extBar) + } + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/after/test.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/after/test.kt new file mode 100644 index 00000000000..6b2ca65557d --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/after/test.kt @@ -0,0 +1,42 @@ +package test + +inline fun with(receiver: T, block: T.() -> R): R = receiver.block() + +class A { + class X { + + } + + companion object { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + object O { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + inner class B { + inner class OuterY + + fun outerFoo(n: Int) {} + + val outerBar = 1 + + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/after/test2/usages.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/after/test2/usages.java new file mode 100644 index 00000000000..17d3fd010ad --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/after/test2/usages.java @@ -0,0 +1,10 @@ +package test2; + +import test.A; +import test.C; + +class Test { + C foo() { + return new C(new A().new B()); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/after/test2/usages2.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/after/test2/usages2.java new file mode 100644 index 00000000000..17d3fd010ad --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/after/test2/usages2.java @@ -0,0 +1,10 @@ +package test2; + +import test.A; +import test.C; + +class Test { + C foo() { + return new C(new A().new B()); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/after/test2/usages3.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/after/test2/usages3.java new file mode 100644 index 00000000000..17d3fd010ad --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/after/test2/usages3.java @@ -0,0 +1,10 @@ +package test2; + +import test.A; +import test.C; + +class Test { + C foo() { + return new C(new A().new B()); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/after/usages.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/after/usages.kt new file mode 100644 index 00000000000..c4fa7b5174a --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/after/usages.kt @@ -0,0 +1,8 @@ +package test2 + +import test.A +import test.C + +fun foo(): C { + return C(A().B()) +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/after/usages2.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/after/usages2.kt new file mode 100644 index 00000000000..af02fff3fed --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/after/usages2.kt @@ -0,0 +1,8 @@ +package test2 + +import test.A +import test.C + +fun foo2(): C { + return C(A().B()) +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/after/usages3.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/after/usages3.kt new file mode 100644 index 00000000000..a785c6ebf86 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/after/usages3.kt @@ -0,0 +1,9 @@ +package test2 + +import test.A +import test.A.B +import test.C + +fun foo2(): C { + return C(A().B()) +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/before/test.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/before/test.kt new file mode 100644 index 00000000000..2e93986b3bd --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/before/test.kt @@ -0,0 +1,66 @@ +package test + +inline fun with(receiver: T, block: T.() -> R): R = receiver.block() + +class A { + class X { + + } + + companion object { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + object O { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + inner class B { + inner class OuterY + + fun outerFoo(n: Int) {} + + val outerBar = 1 + + inner class C { + fun test() { + X() + + Y() + foo(bar) + //1.extFoo(1.extBar) // conflict + + OuterY() + outerFoo(outerBar) + + this@B.OuterY() + this@B.outerFoo(this@B.outerBar) + + O.Y() + O.foo(O.bar) + + with (O) { + Y() + foo(bar) + 1.extFoo(1.extBar) + } + } + } + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/before/test2/usages.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/before/test2/usages.java new file mode 100644 index 00000000000..7c230c2826d --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/before/test2/usages.java @@ -0,0 +1,9 @@ +package test2; + +import test.A; + +class Test { + A.B.C foo() { + return new A().new B().new C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/before/test2/usages2.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/before/test2/usages2.java new file mode 100644 index 00000000000..e1de8eed4c3 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/before/test2/usages2.java @@ -0,0 +1,10 @@ +package test2; + +import test.A; +import test.A.B.C; + +class Test { + C foo() { + return new A().new B().new C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/before/test2/usages3.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/before/test2/usages3.java new file mode 100644 index 00000000000..7f428e83cd1 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/before/test2/usages3.java @@ -0,0 +1,10 @@ +package test2; + +import test.A; +import test.A.B; + +class Test { + B.C foo() { + return new A().new B().new C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/before/usages.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/before/usages.kt new file mode 100644 index 00000000000..affd1011069 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/before/usages.kt @@ -0,0 +1,7 @@ +package test2 + +import test.A + +fun foo(): A.B.C { + return A().B().C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/before/usages2.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/before/usages2.kt new file mode 100644 index 00000000000..364b8ea21e5 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/before/usages2.kt @@ -0,0 +1,8 @@ +package test2 + +import test.A +import test.A.B.C + +fun foo2(): C { + return A().B().C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/before/usages3.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/before/usages3.kt new file mode 100644 index 00000000000..9bd81f193ab --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/before/usages3.kt @@ -0,0 +1,8 @@ +package test2 + +import test.A +import test.A.B + +fun foo2(): B.C { + return A().B().C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/deepInnerToTopLevelWithThis.test b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/deepInnerToTopLevelWithThis.test new file mode 100644 index 00000000000..fcade99675c --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/deepInnerToTopLevelWithThis.test @@ -0,0 +1,6 @@ +{ + "mainFile": "test.kt", + "type": "MOVE_KOTLIN_NESTED_CLASS", + "outerInstanceParameter": "b", + "withRuntime": "true" +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/after/C.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/after/C.kt new file mode 100644 index 00000000000..383e8aa6e4f --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/after/C.kt @@ -0,0 +1,20 @@ +package test + +class C { + fun test() { + A.X() + + A.Companion.Y() + A.foo(A.bar) + //1.extFoo(1.extBar) // conflict + + A.O.Y() + A.O.foo(A.O.bar) + + with (A.O) { + A.Companion.Y() + foo(bar) + 1.extFoo(1.extBar) + } + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/after/test.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/after/test.kt new file mode 100644 index 00000000000..5f0c588136c --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/after/test.kt @@ -0,0 +1,36 @@ +package test + +inline fun with(receiver: T, block: T.() -> R): R = receiver.block() + +class A { + class X { + + } + + companion object { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + object O { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + class B { + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/after/test2/usages.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/after/test2/usages.java new file mode 100644 index 00000000000..441e9e66760 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/after/test2/usages.java @@ -0,0 +1,9 @@ +package test2; + +import test.C; + +class Test { + C foo() { + return new C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/after/test2/usages2.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/after/test2/usages2.java new file mode 100644 index 00000000000..441e9e66760 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/after/test2/usages2.java @@ -0,0 +1,9 @@ +package test2; + +import test.C; + +class Test { + C foo() { + return new C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/after/test2/usages3.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/after/test2/usages3.java new file mode 100644 index 00000000000..441e9e66760 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/after/test2/usages3.java @@ -0,0 +1,9 @@ +package test2; + +import test.C; + +class Test { + C foo() { + return new C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/after/usages.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/after/usages.kt new file mode 100644 index 00000000000..1ba1c0843bb --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/after/usages.kt @@ -0,0 +1,8 @@ +package test2 + +import test.A +import test.C + +fun foo(): C { + return C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/after/usages2.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/after/usages2.kt new file mode 100644 index 00000000000..cc5203bc1e3 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/after/usages2.kt @@ -0,0 +1,7 @@ +package test2 + +import test.C + +fun foo(): C { + return C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/after/usages3.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/after/usages3.kt new file mode 100644 index 00000000000..b619da37c21 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/after/usages3.kt @@ -0,0 +1,8 @@ +package test2 + +import test.A.B +import test.C + +fun foo(): C { + return C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/before/test.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/before/test.kt new file mode 100644 index 00000000000..ff3802b3c50 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/before/test.kt @@ -0,0 +1,54 @@ +package test + +inline fun with(receiver: T, block: T.() -> R): R = receiver.block() + +class A { + class X { + + } + + companion object { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + object O { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + class B { + class C { + fun test() { + X() + + Y() + foo(bar) + //1.extFoo(1.extBar) // conflict + + O.Y() + O.foo(O.bar) + + with (O) { + Y() + foo(bar) + 1.extFoo(1.extBar) + } + } + } + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/before/test2/usages.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/before/test2/usages.java new file mode 100644 index 00000000000..90a6077ccc3 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/before/test2/usages.java @@ -0,0 +1,9 @@ +package test2; + +import test.A; + +class Test { + A.B.C foo() { + return new A.B.C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/before/test2/usages2.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/before/test2/usages2.java new file mode 100644 index 00000000000..fa34d0f6f64 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/before/test2/usages2.java @@ -0,0 +1,9 @@ +package test2; + +import test.A.B.C; + +class Test { + C foo() { + return new C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/before/test2/usages3.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/before/test2/usages3.java new file mode 100644 index 00000000000..3565b2b3dad --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/before/test2/usages3.java @@ -0,0 +1,9 @@ +package test2; + +import test.A.B; + +class Test { + B.C foo() { + return new B.C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/before/usages.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/before/usages.kt new file mode 100644 index 00000000000..cb4eb950d5a --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/before/usages.kt @@ -0,0 +1,7 @@ +package test2 + +import test.A + +fun foo(): A.B.C { + return A.B.C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/before/usages2.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/before/usages2.kt new file mode 100644 index 00000000000..fdd69c90bc0 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/before/usages2.kt @@ -0,0 +1,7 @@ +package test2 + +import test.A.B.C + +fun foo(): C { + return C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/before/usages3.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/before/usages3.kt new file mode 100644 index 00000000000..a7b2b9b127d --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/before/usages3.kt @@ -0,0 +1,7 @@ +package test2 + +import test.A.B + +fun foo(): B.C { + return B.C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/deepNonInnerToTopLevel.test b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/deepNonInnerToTopLevel.test new file mode 100644 index 00000000000..7d61ef53852 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/deepNonInnerToTopLevel.test @@ -0,0 +1,5 @@ +{ + "mainFile": "test.kt", + "type": "MOVE_KOTLIN_NESTED_CLASS", + "withRuntime": "true" +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/after/B.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/after/B.kt new file mode 100644 index 00000000000..71bf44c9638 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/after/B.kt @@ -0,0 +1,20 @@ +package test + +class B { + fun test() { + A.X() + + A.Companion.Y() + A.foo(A.bar) + //1.extFoo(1.extBar) // conflict + + A.O.Y() + A.O.foo(A.O.bar) + + with (A.O) { + A.Companion.Y() + foo(bar) + 1.extFoo(1.extBar) + } + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/after/test.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/after/test.kt new file mode 100644 index 00000000000..e8b1584ecdb --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/after/test.kt @@ -0,0 +1,34 @@ +package test + +inline fun with(receiver: T, block: T.() -> R): R = receiver.block() + +class A { + class X { + + } + + companion object { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + object O { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/after/test2/usages.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/after/test2/usages.java new file mode 100644 index 00000000000..5871d0e9fa5 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/after/test2/usages.java @@ -0,0 +1,10 @@ +package test2; + +import test.A; +import test.B; + +class Test { + B foo() { + return new A().new B(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/after/test2/usages2.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/after/test2/usages2.java new file mode 100644 index 00000000000..5871d0e9fa5 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/after/test2/usages2.java @@ -0,0 +1,10 @@ +package test2; + +import test.A; +import test.B; + +class Test { + B foo() { + return new A().new B(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/after/usages.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/after/usages.kt new file mode 100644 index 00000000000..a4144525b4e --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/after/usages.kt @@ -0,0 +1,8 @@ +package test2 + +import test.A +import test.B + +fun foo(): B { + return B() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/after/usages2.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/after/usages2.kt new file mode 100644 index 00000000000..041f2898975 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/after/usages2.kt @@ -0,0 +1,8 @@ +package test2 + +import test.A +import test.B + +fun foo2(): B { + return B() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/before/test.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/before/test.kt new file mode 100644 index 00000000000..1076c01f048 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/before/test.kt @@ -0,0 +1,52 @@ +package test + +inline fun with(receiver: T, block: T.() -> R): R = receiver.block() + +class A { + class X { + + } + + companion object { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + object O { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + inner class B { + fun test() { + X() + + Y() + foo(bar) + //1.extFoo(1.extBar) // conflict + + O.Y() + O.foo(O.bar) + + with (O) { + Y() + foo(bar) + 1.extFoo(1.extBar) + } + } + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/before/test2/usages.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/before/test2/usages.java new file mode 100644 index 00000000000..0858bb64317 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/before/test2/usages.java @@ -0,0 +1,9 @@ +package test2; + +import test.A; + +class Test { + A.B foo() { + return new A().new B(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/before/test2/usages2.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/before/test2/usages2.java new file mode 100644 index 00000000000..c4eba0b1f69 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/before/test2/usages2.java @@ -0,0 +1,10 @@ +package test2; + +import test.A; +import test.A.B; + +class Test { + B foo() { + return new A().new B(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/before/usages.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/before/usages.kt new file mode 100644 index 00000000000..439c6744def --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/before/usages.kt @@ -0,0 +1,7 @@ +package test2 + +import test.A + +fun foo(): A.B { + return A().B() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/before/usages2.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/before/usages2.kt new file mode 100644 index 00000000000..7a6a74fa8c5 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/before/usages2.kt @@ -0,0 +1,8 @@ +package test2 + +import test.A +import test.A.B + +fun foo2(): B { + return A().B() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/innerToTopLevelNoThis.test b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/innerToTopLevelNoThis.test new file mode 100644 index 00000000000..7d61ef53852 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/innerToTopLevelNoThis.test @@ -0,0 +1,5 @@ +{ + "mainFile": "test.kt", + "type": "MOVE_KOTLIN_NESTED_CLASS", + "withRuntime": "true" +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/after/B.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/after/B.kt new file mode 100644 index 00000000000..b4a5171f6b4 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/after/B.kt @@ -0,0 +1,26 @@ +package test + +class B(private val a: A) { + fun test() { + A.X() + + A.Companion.Y() + A.foo(A.bar) + //1.extFoo(1.extBar) // conflict + + a.OuterY() + a.outerFoo(a.outerBar) + + a.OuterY() + a.outerFoo(a.outerBar) + + A.O.Y() + A.O.foo(A.O.bar) + + with (A.O) { + A.Companion.Y() + foo(bar) + 1.extFoo(1.extBar) + } + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/after/test.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/after/test.kt new file mode 100644 index 00000000000..b23f2e60306 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/after/test.kt @@ -0,0 +1,40 @@ +package test + +inline fun with(receiver: T, block: T.() -> R): R = receiver.block() + +class A { + class X { + + } + + inner class OuterY + + fun outerFoo(n: Int) {} + + val outerBar = 1 + + companion object { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + object O { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/after/test2/usages.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/after/test2/usages.java new file mode 100644 index 00000000000..89d1d91268b --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/after/test2/usages.java @@ -0,0 +1,10 @@ +package test2; + +import test.A; +import test.B; + +class Test { + B foo() { + return new B(new A()); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/after/test2/usages2.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/after/test2/usages2.java new file mode 100644 index 00000000000..89d1d91268b --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/after/test2/usages2.java @@ -0,0 +1,10 @@ +package test2; + +import test.A; +import test.B; + +class Test { + B foo() { + return new B(new A()); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/after/usages.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/after/usages.kt new file mode 100644 index 00000000000..51b77dda3d0 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/after/usages.kt @@ -0,0 +1,8 @@ +package test2 + +import test.A +import test.B + +fun foo(): B { + return B(A()) +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/after/usages2.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/after/usages2.kt new file mode 100644 index 00000000000..f93d852bde7 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/after/usages2.kt @@ -0,0 +1,8 @@ +package test2 + +import test.A +import test.B + +fun foo2(): B { + return B(A()) +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/before/test.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/before/test.kt new file mode 100644 index 00000000000..bdc7c96c12b --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/before/test.kt @@ -0,0 +1,64 @@ +package test + +inline fun with(receiver: T, block: T.() -> R): R = receiver.block() + +class A { + class X { + + } + + inner class OuterY + + fun outerFoo(n: Int) {} + + val outerBar = 1 + + companion object { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + object O { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + inner class B { + fun test() { + X() + + Y() + foo(bar) + //1.extFoo(1.extBar) // conflict + + OuterY() + outerFoo(outerBar) + + this@A.OuterY() + this@A.outerFoo(this@A.outerBar) + + O.Y() + O.foo(O.bar) + + with (O) { + Y() + foo(bar) + 1.extFoo(1.extBar) + } + } + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/before/test2/usages.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/before/test2/usages.java new file mode 100644 index 00000000000..0858bb64317 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/before/test2/usages.java @@ -0,0 +1,9 @@ +package test2; + +import test.A; + +class Test { + A.B foo() { + return new A().new B(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/before/test2/usages2.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/before/test2/usages2.java new file mode 100644 index 00000000000..c4eba0b1f69 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/before/test2/usages2.java @@ -0,0 +1,10 @@ +package test2; + +import test.A; +import test.A.B; + +class Test { + B foo() { + return new A().new B(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/before/usages.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/before/usages.kt new file mode 100644 index 00000000000..439c6744def --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/before/usages.kt @@ -0,0 +1,7 @@ +package test2 + +import test.A + +fun foo(): A.B { + return A().B() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/before/usages2.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/before/usages2.kt new file mode 100644 index 00000000000..7a6a74fa8c5 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/before/usages2.kt @@ -0,0 +1,8 @@ +package test2 + +import test.A +import test.A.B + +fun foo2(): B { + return A().B() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/innerToTopLevelWithThis.test b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/innerToTopLevelWithThis.test new file mode 100644 index 00000000000..8dd75509bdc --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/innerToTopLevelWithThis.test @@ -0,0 +1,6 @@ +{ + "mainFile": "test.kt", + "type": "MOVE_KOTLIN_NESTED_CLASS", + "outerInstanceParameter": "a", + "withRuntime": "true" +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThisOuterRefConflicts/after/test.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThisOuterRefConflicts/after/test.kt new file mode 100644 index 00000000000..097f1b07216 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThisOuterRefConflicts/after/test.kt @@ -0,0 +1,19 @@ +package test + +inline fun with(receiver: T, block: T.() -> R): R = receiver.block() + +class A() { + fun X.bar() {} +} + +class X { + fun Int.foo() {} + + inner class Y { + fun test() { + 1.foo() + with(1) { foo() } + with(A()) { bar() } + } + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThisOuterRefConflicts/before/test.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThisOuterRefConflicts/before/test.kt new file mode 100644 index 00000000000..3ed523cd5a2 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThisOuterRefConflicts/before/test.kt @@ -0,0 +1,19 @@ +package test + +inline fun with(receiver: T, block: T.() -> R): R = receiver.block() + +class A() { + fun X.bar() {} +} + +class X { + fun Int.foo() {} + + inner class Y { + fun test() { + 1.foo() + with(1) { foo() } + with(A()) { bar() } + } + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThisOuterRefConflicts/conflicts.txt b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThisOuterRefConflicts/conflicts.txt new file mode 100644 index 00000000000..a00781457d5 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThisOuterRefConflicts/conflicts.txt @@ -0,0 +1,3 @@ +Call with two implicit receivers won't be processed: bar() +Call with two implicit receivers won't be processed: foo() +Qualified call won't be processed: 1.foo() \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThisOuterRefConflicts/innerToTopLevelWithThisOuterRefConflicts.test b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThisOuterRefConflicts/innerToTopLevelWithThisOuterRefConflicts.test new file mode 100644 index 00000000000..8dd75509bdc --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThisOuterRefConflicts/innerToTopLevelWithThisOuterRefConflicts.test @@ -0,0 +1,6 @@ +{ + "mainFile": "test.kt", + "type": "MOVE_KOTLIN_NESTED_CLASS", + "outerInstanceParameter": "a", + "withRuntime": "true" +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/after/test.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/after/test.kt new file mode 100644 index 00000000000..ed63b5929cf --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/after/test.kt @@ -0,0 +1,55 @@ +package test + +inline fun with(receiver: T, block: T.() -> R): R = receiver.block() + +class A { + class B { + class X { + + } + + companion object { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + object O { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + } + + class C { + fun test() { + B.X() + + B.Companion.Y() + B.foo(B.bar) + //1.extFoo(1.extBar) // conflict + + B.O.Y() + B.O.foo(B.O.bar) + + with (B.O) { + B.Companion.Y() + foo(bar) + 1.extFoo(1.extBar) + } + } + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/after/test2/usages.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/after/test2/usages.java new file mode 100644 index 00000000000..440bbbc97b1 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/after/test2/usages.java @@ -0,0 +1,9 @@ +package test2; + +import test.A; + +class Test { + A.C foo() { + return new A.C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/after/test2/usages2.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/after/test2/usages2.java new file mode 100644 index 00000000000..b93ffffda5d --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/after/test2/usages2.java @@ -0,0 +1,9 @@ +package test2; + +import test.A.C; + +class Test { + C foo() { + return new C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/after/test2/usages3.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/after/test2/usages3.java new file mode 100644 index 00000000000..440bbbc97b1 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/after/test2/usages3.java @@ -0,0 +1,9 @@ +package test2; + +import test.A; + +class Test { + A.C foo() { + return new A.C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/after/usages.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/after/usages.kt new file mode 100644 index 00000000000..61cbf87f733 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/after/usages.kt @@ -0,0 +1,7 @@ +package test2 + +import test.A + +fun foo(): A.C { + return A.C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/after/usages2.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/after/usages2.kt new file mode 100644 index 00000000000..841814e2e54 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/after/usages2.kt @@ -0,0 +1,7 @@ +package test2 + +import test.A.C + +fun foo(): C { + return C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/after/usages3.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/after/usages3.kt new file mode 100644 index 00000000000..686f5fef9b4 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/after/usages3.kt @@ -0,0 +1,8 @@ +package test2 + +import test.A +import test.A.B + +fun foo(): A.C { + return A.C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/before/test.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/before/test.kt new file mode 100644 index 00000000000..9a541ad4999 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/before/test.kt @@ -0,0 +1,54 @@ +package test + +inline fun with(receiver: T, block: T.() -> R): R = receiver.block() + +class A { + class B { + class X { + + } + + companion object { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + object O { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + class C { + fun test() { + X() + + Y() + foo(bar) + //1.extFoo(1.extBar) // conflict + + O.Y() + O.foo(O.bar) + + with (O) { + Y() + foo(bar) + 1.extFoo(1.extBar) + } + } + } + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/before/test2/usages.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/before/test2/usages.java new file mode 100644 index 00000000000..90a6077ccc3 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/before/test2/usages.java @@ -0,0 +1,9 @@ +package test2; + +import test.A; + +class Test { + A.B.C foo() { + return new A.B.C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/before/test2/usages2.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/before/test2/usages2.java new file mode 100644 index 00000000000..fa34d0f6f64 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/before/test2/usages2.java @@ -0,0 +1,9 @@ +package test2; + +import test.A.B.C; + +class Test { + C foo() { + return new C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/before/test2/usages3.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/before/test2/usages3.java new file mode 100644 index 00000000000..3565b2b3dad --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/before/test2/usages3.java @@ -0,0 +1,9 @@ +package test2; + +import test.A.B; + +class Test { + B.C foo() { + return new B.C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/before/usages.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/before/usages.kt new file mode 100644 index 00000000000..cb4eb950d5a --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/before/usages.kt @@ -0,0 +1,7 @@ +package test2 + +import test.A + +fun foo(): A.B.C { + return A.B.C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/before/usages2.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/before/usages2.kt new file mode 100644 index 00000000000..fdd69c90bc0 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/before/usages2.kt @@ -0,0 +1,7 @@ +package test2 + +import test.A.B.C + +fun foo(): C { + return C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/before/usages3.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/before/usages3.kt new file mode 100644 index 00000000000..a7b2b9b127d --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/before/usages3.kt @@ -0,0 +1,7 @@ +package test2 + +import test.A.B + +fun foo(): B.C { + return B.C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/nonInnerToOuterClass1.test b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/nonInnerToOuterClass1.test new file mode 100644 index 00000000000..c762ffd8dc7 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/nonInnerToOuterClass1.test @@ -0,0 +1,6 @@ +{ + "mainFile": "test.kt", + "type": "MOVE_KOTLIN_NESTED_CLASS", + "targetClass": "test.A", + "withRuntime": "true" +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/after/test.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/after/test.kt new file mode 100644 index 00000000000..f3210c154f8 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/after/test.kt @@ -0,0 +1,55 @@ +package test + +inline fun with(receiver: T, block: T.() -> R): R = receiver.block() + +class A { + class X { + + } + + companion object { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + object O { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + class B { + } + + class C { + fun test() { + X() + + Y() + foo(bar) + //1.extFoo(1.extBar) // conflict + + O.Y() + O.foo(O.bar) + + with (O) { + Y() + foo(bar) + 1.extFoo(1.extBar) + } + } + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/after/test2/usages.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/after/test2/usages.java new file mode 100644 index 00000000000..440bbbc97b1 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/after/test2/usages.java @@ -0,0 +1,9 @@ +package test2; + +import test.A; + +class Test { + A.C foo() { + return new A.C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/after/test2/usages2.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/after/test2/usages2.java new file mode 100644 index 00000000000..b93ffffda5d --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/after/test2/usages2.java @@ -0,0 +1,9 @@ +package test2; + +import test.A.C; + +class Test { + C foo() { + return new C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/after/test2/usages3.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/after/test2/usages3.java new file mode 100644 index 00000000000..440bbbc97b1 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/after/test2/usages3.java @@ -0,0 +1,9 @@ +package test2; + +import test.A; + +class Test { + A.C foo() { + return new A.C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/after/usages.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/after/usages.kt new file mode 100644 index 00000000000..61cbf87f733 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/after/usages.kt @@ -0,0 +1,7 @@ +package test2 + +import test.A + +fun foo(): A.C { + return A.C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/after/usages2.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/after/usages2.kt new file mode 100644 index 00000000000..841814e2e54 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/after/usages2.kt @@ -0,0 +1,7 @@ +package test2 + +import test.A.C + +fun foo(): C { + return C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/after/usages3.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/after/usages3.kt new file mode 100644 index 00000000000..686f5fef9b4 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/after/usages3.kt @@ -0,0 +1,8 @@ +package test2 + +import test.A +import test.A.B + +fun foo(): A.C { + return A.C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/before/test.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/before/test.kt new file mode 100644 index 00000000000..ff3802b3c50 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/before/test.kt @@ -0,0 +1,54 @@ +package test + +inline fun with(receiver: T, block: T.() -> R): R = receiver.block() + +class A { + class X { + + } + + companion object { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + object O { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + class B { + class C { + fun test() { + X() + + Y() + foo(bar) + //1.extFoo(1.extBar) // conflict + + O.Y() + O.foo(O.bar) + + with (O) { + Y() + foo(bar) + 1.extFoo(1.extBar) + } + } + } + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/before/test2/usages.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/before/test2/usages.java new file mode 100644 index 00000000000..90a6077ccc3 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/before/test2/usages.java @@ -0,0 +1,9 @@ +package test2; + +import test.A; + +class Test { + A.B.C foo() { + return new A.B.C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/before/test2/usages2.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/before/test2/usages2.java new file mode 100644 index 00000000000..fa34d0f6f64 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/before/test2/usages2.java @@ -0,0 +1,9 @@ +package test2; + +import test.A.B.C; + +class Test { + C foo() { + return new C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/before/test2/usages3.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/before/test2/usages3.java new file mode 100644 index 00000000000..3565b2b3dad --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/before/test2/usages3.java @@ -0,0 +1,9 @@ +package test2; + +import test.A.B; + +class Test { + B.C foo() { + return new B.C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/before/usages.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/before/usages.kt new file mode 100644 index 00000000000..cb4eb950d5a --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/before/usages.kt @@ -0,0 +1,7 @@ +package test2 + +import test.A + +fun foo(): A.B.C { + return A.B.C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/before/usages2.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/before/usages2.kt new file mode 100644 index 00000000000..fdd69c90bc0 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/before/usages2.kt @@ -0,0 +1,7 @@ +package test2 + +import test.A.B.C + +fun foo(): C { + return C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/before/usages3.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/before/usages3.kt new file mode 100644 index 00000000000..a7b2b9b127d --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/before/usages3.kt @@ -0,0 +1,7 @@ +package test2 + +import test.A.B + +fun foo(): B.C { + return B.C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/nonInnerToOuterClass2.test b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/nonInnerToOuterClass2.test new file mode 100644 index 00000000000..c762ffd8dc7 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/nonInnerToOuterClass2.test @@ -0,0 +1,6 @@ +{ + "mainFile": "test.kt", + "type": "MOVE_KOTLIN_NESTED_CLASS", + "targetClass": "test.A", + "withRuntime": "true" +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/after/B.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/after/B.kt new file mode 100644 index 00000000000..71bf44c9638 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/after/B.kt @@ -0,0 +1,20 @@ +package test + +class B { + fun test() { + A.X() + + A.Companion.Y() + A.foo(A.bar) + //1.extFoo(1.extBar) // conflict + + A.O.Y() + A.O.foo(A.O.bar) + + with (A.O) { + A.Companion.Y() + foo(bar) + 1.extFoo(1.extBar) + } + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/after/test.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/after/test.kt new file mode 100644 index 00000000000..e8b1584ecdb --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/after/test.kt @@ -0,0 +1,34 @@ +package test + +inline fun with(receiver: T, block: T.() -> R): R = receiver.block() + +class A { + class X { + + } + + companion object { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + object O { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/after/test2/usages.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/after/test2/usages.java new file mode 100644 index 00000000000..85c927ec2e9 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/after/test2/usages.java @@ -0,0 +1,9 @@ +package test2; + +import test.B; + +class Test { + B foo() { + return new B(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/after/test2/usages2.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/after/test2/usages2.java new file mode 100644 index 00000000000..85c927ec2e9 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/after/test2/usages2.java @@ -0,0 +1,9 @@ +package test2; + +import test.B; + +class Test { + B foo() { + return new B(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/after/usages.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/after/usages.kt new file mode 100644 index 00000000000..a4144525b4e --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/after/usages.kt @@ -0,0 +1,8 @@ +package test2 + +import test.A +import test.B + +fun foo(): B { + return B() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/after/usages2.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/after/usages2.kt new file mode 100644 index 00000000000..203a5c48065 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/after/usages2.kt @@ -0,0 +1,7 @@ +package test2 + +import test.B + +fun foo(): B { + return B() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/before/test.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/before/test.kt new file mode 100644 index 00000000000..0db275c7531 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/before/test.kt @@ -0,0 +1,52 @@ +package test + +inline fun with(receiver: T, block: T.() -> R): R = receiver.block() + +class A { + class X { + + } + + companion object { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + object O { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + class B { + fun test() { + X() + + Y() + foo(bar) + //1.extFoo(1.extBar) // conflict + + O.Y() + O.foo(O.bar) + + with (O) { + Y() + foo(bar) + 1.extFoo(1.extBar) + } + } + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/before/test2/usages.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/before/test2/usages.java new file mode 100644 index 00000000000..7816fedd348 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/before/test2/usages.java @@ -0,0 +1,9 @@ +package test2; + +import test.A; + +class Test { + A.B foo() { + return new A.B(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/before/test2/usages2.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/before/test2/usages2.java new file mode 100644 index 00000000000..c543d09b86f --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/before/test2/usages2.java @@ -0,0 +1,9 @@ +package test2; + +import test.A.B; + +class Test { + B foo() { + return new B(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/before/usages.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/before/usages.kt new file mode 100644 index 00000000000..b4343208678 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/before/usages.kt @@ -0,0 +1,7 @@ +package test2 + +import test.A + +fun foo(): A.B { + return A.B() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/before/usages2.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/before/usages2.kt new file mode 100644 index 00000000000..afebe70e74c --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/before/usages2.kt @@ -0,0 +1,7 @@ +package test2 + +import test.A.B + +fun foo(): B { + return B() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/nonInnerToTopLevel.test b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/nonInnerToTopLevel.test new file mode 100644 index 00000000000..7d61ef53852 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/nonInnerToTopLevel.test @@ -0,0 +1,5 @@ +{ + "mainFile": "test.kt", + "type": "MOVE_KOTLIN_NESTED_CLASS", + "withRuntime": "true" +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/after/target.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/after/target.kt new file mode 100644 index 00000000000..a5ce29a7ecc --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/after/target.kt @@ -0,0 +1,25 @@ +package test3 + +import test.A + +class D { + class C { + fun test() { + A.B.X() + + A.B.Companion.Y() + A.B.foo(A.B.bar) + //1.extFoo(1.extBar) // conflict + + A.B.O.Y() + A.B.O.foo(A.B.O.bar) + + with (A.B.O) { + A.B.Companion.Y() + foo(bar) + 1.extFoo(1.extBar) + } + } + } + +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/after/test.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/after/test.kt new file mode 100644 index 00000000000..442cad63ade --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/after/test.kt @@ -0,0 +1,36 @@ +package test + +inline fun with(receiver: T, block: T.() -> R): R = receiver.block() + +class A { + class B { + class X { + + } + + companion object { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + object O { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/after/test2/usages.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/after/test2/usages.java new file mode 100644 index 00000000000..9045b755610 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/after/test2/usages.java @@ -0,0 +1,9 @@ +package test2; + +import test3.D; + +class Test { + D.C foo() { + return new D.C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/after/test2/usages2.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/after/test2/usages2.java new file mode 100644 index 00000000000..bdde8ad6e06 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/after/test2/usages2.java @@ -0,0 +1,9 @@ +package test2; + +import test3.D.C; + +class Test { + C foo() { + return new C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/after/test2/usages3.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/after/test2/usages3.java new file mode 100644 index 00000000000..9045b755610 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/after/test2/usages3.java @@ -0,0 +1,9 @@ +package test2; + +import test3.D; + +class Test { + D.C foo() { + return new D.C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/after/usages.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/after/usages.kt new file mode 100644 index 00000000000..8a7acc956c6 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/after/usages.kt @@ -0,0 +1,8 @@ +package test2 + +import test.A +import test3.D + +fun foo(): D.C { + return D.C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/after/usages2.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/after/usages2.kt new file mode 100644 index 00000000000..e5dcfa94eed --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/after/usages2.kt @@ -0,0 +1,7 @@ +package test2 + +import test3.D.C + +fun foo(): C { + return C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/after/usages3.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/after/usages3.kt new file mode 100644 index 00000000000..cd89a25f2d6 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/after/usages3.kt @@ -0,0 +1,8 @@ +package test2 + +import test.A.B +import test3.D + +fun foo(): D.C { + return D.C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/before/target.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/before/target.kt new file mode 100644 index 00000000000..48b3a152be2 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/before/target.kt @@ -0,0 +1,5 @@ +package test3 + +class D { + +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/before/test.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/before/test.kt new file mode 100644 index 00000000000..9a541ad4999 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/before/test.kt @@ -0,0 +1,54 @@ +package test + +inline fun with(receiver: T, block: T.() -> R): R = receiver.block() + +class A { + class B { + class X { + + } + + companion object { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + object O { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + class C { + fun test() { + X() + + Y() + foo(bar) + //1.extFoo(1.extBar) // conflict + + O.Y() + O.foo(O.bar) + + with (O) { + Y() + foo(bar) + 1.extFoo(1.extBar) + } + } + } + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/before/test2/usages.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/before/test2/usages.java new file mode 100644 index 00000000000..90a6077ccc3 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/before/test2/usages.java @@ -0,0 +1,9 @@ +package test2; + +import test.A; + +class Test { + A.B.C foo() { + return new A.B.C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/before/test2/usages2.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/before/test2/usages2.java new file mode 100644 index 00000000000..fa34d0f6f64 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/before/test2/usages2.java @@ -0,0 +1,9 @@ +package test2; + +import test.A.B.C; + +class Test { + C foo() { + return new C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/before/test2/usages3.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/before/test2/usages3.java new file mode 100644 index 00000000000..3565b2b3dad --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/before/test2/usages3.java @@ -0,0 +1,9 @@ +package test2; + +import test.A.B; + +class Test { + B.C foo() { + return new B.C(); + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/before/usages.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/before/usages.kt new file mode 100644 index 00000000000..cb4eb950d5a --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/before/usages.kt @@ -0,0 +1,7 @@ +package test2 + +import test.A + +fun foo(): A.B.C { + return A.B.C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/before/usages2.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/before/usages2.kt new file mode 100644 index 00000000000..fdd69c90bc0 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/before/usages2.kt @@ -0,0 +1,7 @@ +package test2 + +import test.A.B.C + +fun foo(): C { + return C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/before/usages3.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/before/usages3.kt new file mode 100644 index 00000000000..a7b2b9b127d --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/before/usages3.kt @@ -0,0 +1,7 @@ +package test2 + +import test.A.B + +fun foo(): B.C { + return B.C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/nonInnerToTopLevelClass.test b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/nonInnerToTopLevelClass.test new file mode 100644 index 00000000000..22482d2bffa --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/nonInnerToTopLevelClass.test @@ -0,0 +1,6 @@ +{ + "mainFile": "test.kt", + "type": "MOVE_KOTLIN_NESTED_CLASS", + "targetClass": "test3.D", + "withRuntime": "true" +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelCompanionConflict/after/test.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelCompanionConflict/after/test.kt new file mode 100644 index 00000000000..d6f8cf59a1e --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelCompanionConflict/after/test.kt @@ -0,0 +1,15 @@ +package test + +class A { + companion object { + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + class B { + fun test() { + 1.extFoo(1.extBar) + } + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelCompanionConflict/before/test.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelCompanionConflict/before/test.kt new file mode 100644 index 00000000000..70b10d76039 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelCompanionConflict/before/test.kt @@ -0,0 +1,15 @@ +package test + +class A { + companion object { + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + class B { + fun test() { + 1.extFoo(1.extBar) + } + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelCompanionConflict/conflicts.txt b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelCompanionConflict/conflicts.txt new file mode 100644 index 00000000000..cebc3ff451e --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelCompanionConflict/conflicts.txt @@ -0,0 +1,2 @@ +Implicit companion object will be inaccessible: extBar +Implicit companion object will be inaccessible: extFoo \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelCompanionConflict/nonInnerToTopLevelCompanionConflict.test b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelCompanionConflict/nonInnerToTopLevelCompanionConflict.test new file mode 100644 index 00000000000..7d61ef53852 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelCompanionConflict/nonInnerToTopLevelCompanionConflict.test @@ -0,0 +1,5 @@ +{ + "mainFile": "test.kt", + "type": "MOVE_KOTLIN_NESTED_CLASS", + "withRuntime": "true" +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/after/B.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/after/B.kt new file mode 100644 index 00000000000..7b460f413b3 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/after/B.kt @@ -0,0 +1,20 @@ +package test + +object B { + fun test() { + A.X() + + A.Companion.Y() + A.foo(A.bar) + //1.extFoo(1.extBar) // conflict + + A.O.Y() + A.O.foo(A.O.bar) + + with (A.O) { + A.Companion.Y() + foo(bar) + 1.extFoo(1.extBar) + } + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/after/test.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/after/test.kt new file mode 100644 index 00000000000..e8b1584ecdb --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/after/test.kt @@ -0,0 +1,34 @@ +package test + +inline fun with(receiver: T, block: T.() -> R): R = receiver.block() + +class A { + class X { + + } + + companion object { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + object O { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/after/test2/usages.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/after/test2/usages.java new file mode 100644 index 00000000000..1d16aa0b149 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/after/test2/usages.java @@ -0,0 +1,9 @@ +package test2; + +import test.B; + +class Test { + B foo() { + return B.INSTANCE; + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/after/test2/usages2.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/after/test2/usages2.java new file mode 100644 index 00000000000..1d16aa0b149 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/after/test2/usages2.java @@ -0,0 +1,9 @@ +package test2; + +import test.B; + +class Test { + B foo() { + return B.INSTANCE; + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/after/usages.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/after/usages.kt new file mode 100644 index 00000000000..96507d86d49 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/after/usages.kt @@ -0,0 +1,8 @@ +package test2 + +import test.A +import test.B + +fun foo(): B { + return B +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/after/usages2.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/after/usages2.kt new file mode 100644 index 00000000000..b1c38174b45 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/after/usages2.kt @@ -0,0 +1,7 @@ +package test2 + +import test.B + +fun foo(): B { + return B +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/before/test.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/before/test.kt new file mode 100644 index 00000000000..bdaf2bd5f5e --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/before/test.kt @@ -0,0 +1,52 @@ +package test + +inline fun with(receiver: T, block: T.() -> R): R = receiver.block() + +class A { + class X { + + } + + companion object { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + object O { + class Y + + fun foo(n: Int) {} + + val bar = 1 + + fun Int.extFoo(n: Int) {} + + val Int.extBar: Int get() = 1 + } + + object B { + fun test() { + X() + + Y() + foo(bar) + //1.extFoo(1.extBar) // conflict + + O.Y() + O.foo(O.bar) + + with (O) { + Y() + foo(bar) + 1.extFoo(1.extBar) + } + } + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/before/test2/usages.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/before/test2/usages.java new file mode 100644 index 00000000000..5049e512daa --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/before/test2/usages.java @@ -0,0 +1,9 @@ +package test2; + +import test.A; + +class Test { + A.B foo() { + return A.B.INSTANCE; + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/before/test2/usages2.java b/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/before/test2/usages2.java new file mode 100644 index 00000000000..eba00c1d28a --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/before/test2/usages2.java @@ -0,0 +1,9 @@ +package test2; + +import test.A.B; + +class Test { + B foo() { + return B.INSTANCE; + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/before/usages.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/before/usages.kt new file mode 100644 index 00000000000..32d725b3f59 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/before/usages.kt @@ -0,0 +1,7 @@ +package test2 + +import test.A + +fun foo(): A.B { + return A.B +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/before/usages2.kt b/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/before/usages2.kt new file mode 100644 index 00000000000..c8820c1f9bf --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/before/usages2.kt @@ -0,0 +1,7 @@ +package test2 + +import test.A.B + +fun foo(): B { + return B +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/objectToTopLevel.test b/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/objectToTopLevel.test new file mode 100644 index 00000000000..7d61ef53852 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/objectToTopLevel.test @@ -0,0 +1,5 @@ +{ + "mainFile": "test.kt", + "type": "MOVE_KOTLIN_NESTED_CLASS", + "withRuntime": "true" +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/AbstractMoveTest.kt b/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/AbstractMoveTest.kt index 2951ea4ed6f..ec8998f7230 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/AbstractMoveTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/AbstractMoveTest.kt @@ -37,20 +37,20 @@ 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.createKotlinFile -import org.jetbrains.kotlin.idea.refactoring.toPsiDirectory import org.jetbrains.kotlin.idea.jsonUtils.getNullableString import org.jetbrains.kotlin.idea.jsonUtils.getString +import org.jetbrains.kotlin.idea.refactoring.createKotlinFile import org.jetbrains.kotlin.idea.refactoring.move.changePackage.KotlinChangePackageRefactoring -import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.KotlinMoveTargetForDeferredFile -import org.jetbrains.kotlin.idea.refactoring.move.moveTopLevelDeclarations.KotlinMoveTargetForExistingFile -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.moveDeclarations.* +import org.jetbrains.kotlin.idea.refactoring.toPsiDirectory import org.jetbrains.kotlin.idea.search.allScope +import org.jetbrains.kotlin.idea.search.projectScope +import org.jetbrains.kotlin.idea.stubindex.KotlinFullClassNameIndex import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil import org.jetbrains.kotlin.idea.test.KotlinMultiFileTestCase import org.jetbrains.kotlin.idea.test.PluginTestCaseBase import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtNamedDeclaration import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType @@ -249,16 +249,16 @@ enum class MoveAction { val elementToMove = elementAtCaret!!.getNonStrictParentOfType()!! val moveTarget = config.getNullableString("targetPackage")?.let { packageName -> - KotlinMoveTargetForDeferredFile(project, FqName(packageName)) { + KotlinMoveTargetForDeferredFile(FqName(packageName)) { val moveDestination = MultipleRootsMoveDestination(PackageWrapper(mainFile.getManager(), packageName)) createKotlinFile(guessNewFileName(listOf(elementToMove))!!, moveDestination.getTargetDirectory(mainFile)) } } ?: config.getString("targetFile").let { filePath -> - KotlinMoveTargetForExistingFile(PsiManager.getInstance(project).findFile(rootDir.findFileByRelativePath(filePath)!!) as KtFile) + KotlinMoveTargetForExistingElement(PsiManager.getInstance(project).findFile(rootDir.findFileByRelativePath(filePath)!!) as KtFile) } - val options = MoveKotlinTopLevelDeclarationsOptions(listOf(elementToMove), moveTarget) - MoveKotlinTopLevelDeclarationsProcessor(mainFile.getProject(), options).run() + val options = MoveDeclarationsDescriptor(listOf(elementToMove), moveTarget, MoveDeclarationsDelegate.TopLevel) + MoveKotlinDeclarationsProcessor(mainFile.getProject(), options).run() } }, @@ -275,6 +275,34 @@ enum class MoveAction { val targetDir = rootDir.findFileByRelativePath(config.getString("targetDir"))!!.toPsiDirectory(project)!! MoveDirectoryWithClassesProcessor(project, arrayOf(sourceDir), targetDir, true, true, true, {}).run() } + }, + + MOVE_KOTLIN_NESTED_CLASS { + override fun runRefactoring(rootDir: VirtualFile, mainFile: PsiFile, elementAtCaret: PsiElement?, config: JsonObject) { + val project = mainFile.project + val elementToMove = elementAtCaret!!.getNonStrictParentOfType()!! + val targetClassName = config.getNullableString("targetClass") + val targetClass = + if (targetClassName != null) { + KotlinFullClassNameIndex.getInstance().get(targetClassName, project, project.projectScope()).first()!! + } + else null + val delegate = MoveDeclarationsDelegate.NestedClass(config.getNullableString("newName"), + config.getNullableString("outerInstanceParameter")) + val moveTarget = + if (targetClass != null) { + KotlinMoveTargetForExistingElement(targetClass) + } + else { + val fileName = (delegate.newClassName ?: elementToMove.name!!) + ".kt" + val targetPackageFqName = (mainFile as KtFile).packageFqName + KotlinMoveTargetForDeferredFile(targetPackageFqName) { + createKotlinFile(fileName, mainFile.containingDirectory!!, targetPackageFqName.asString()) + } + } + val descriptor = MoveDeclarationsDescriptor(listOf(elementToMove), moveTarget, delegate) + MoveKotlinDeclarationsProcessor(project, descriptor).run() + } }; abstract fun runRefactoring(rootDir: VirtualFile, mainFile: PsiFile, elementAtCaret: PsiElement?, config: JsonObject) diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/MoveTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/MoveTestGenerated.java index 22ec1f50f6f..058f14a1bed 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/MoveTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/MoveTestGenerated.java @@ -275,6 +275,78 @@ public class MoveTestGenerated extends AbstractMoveTest { doTest(fileName); } + @TestMetadata("kotlin/moveNestedClass/deepInnerToTopLevelWithOuterOuterThis/deepInnerToTopLevelWithOuterOuterThis.test") + public void testKotlin_moveNestedClass_deepInnerToTopLevelWithOuterOuterThis_DeepInnerToTopLevelWithOuterOuterThis() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithOuterOuterThis/deepInnerToTopLevelWithOuterOuterThis.test"); + doTest(fileName); + } + + @TestMetadata("kotlin/moveNestedClass/deepInnerToTopLevelWithThis/deepInnerToTopLevelWithThis.test") + public void testKotlin_moveNestedClass_deepInnerToTopLevelWithThis_DeepInnerToTopLevelWithThis() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveNestedClass/deepInnerToTopLevelWithThis/deepInnerToTopLevelWithThis.test"); + doTest(fileName); + } + + @TestMetadata("kotlin/moveNestedClass/deepNonInnerToTopLevel/deepNonInnerToTopLevel.test") + public void testKotlin_moveNestedClass_deepNonInnerToTopLevel_DeepNonInnerToTopLevel() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveNestedClass/deepNonInnerToTopLevel/deepNonInnerToTopLevel.test"); + doTest(fileName); + } + + @TestMetadata("kotlin/moveNestedClass/innerToTopLevelNoThis/innerToTopLevelNoThis.test") + public void testKotlin_moveNestedClass_innerToTopLevelNoThis_InnerToTopLevelNoThis() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelNoThis/innerToTopLevelNoThis.test"); + doTest(fileName); + } + + @TestMetadata("kotlin/moveNestedClass/innerToTopLevelWithThis/innerToTopLevelWithThis.test") + public void testKotlin_moveNestedClass_innerToTopLevelWithThis_InnerToTopLevelWithThis() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThis/innerToTopLevelWithThis.test"); + doTest(fileName); + } + + @TestMetadata("kotlin/moveNestedClass/innerToTopLevelWithThisOuterRefConflicts/innerToTopLevelWithThisOuterRefConflicts.test") + public void testKotlin_moveNestedClass_innerToTopLevelWithThisOuterRefConflicts_InnerToTopLevelWithThisOuterRefConflicts() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveNestedClass/innerToTopLevelWithThisOuterRefConflicts/innerToTopLevelWithThisOuterRefConflicts.test"); + doTest(fileName); + } + + @TestMetadata("kotlin/moveNestedClass/nonInnerToOuterClass1/nonInnerToOuterClass1.test") + public void testKotlin_moveNestedClass_nonInnerToOuterClass1_NonInnerToOuterClass1() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass1/nonInnerToOuterClass1.test"); + doTest(fileName); + } + + @TestMetadata("kotlin/moveNestedClass/nonInnerToOuterClass2/nonInnerToOuterClass2.test") + public void testKotlin_moveNestedClass_nonInnerToOuterClass2_NonInnerToOuterClass2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToOuterClass2/nonInnerToOuterClass2.test"); + doTest(fileName); + } + + @TestMetadata("kotlin/moveNestedClass/nonInnerToTopLevel/nonInnerToTopLevel.test") + public void testKotlin_moveNestedClass_nonInnerToTopLevel_NonInnerToTopLevel() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevel/nonInnerToTopLevel.test"); + doTest(fileName); + } + + @TestMetadata("kotlin/moveNestedClass/nonInnerToTopLevelClass/nonInnerToTopLevelClass.test") + public void testKotlin_moveNestedClass_nonInnerToTopLevelClass_NonInnerToTopLevelClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelClass/nonInnerToTopLevelClass.test"); + doTest(fileName); + } + + @TestMetadata("kotlin/moveNestedClass/nonInnerToTopLevelCompanionConflict/nonInnerToTopLevelCompanionConflict.test") + public void testKotlin_moveNestedClass_nonInnerToTopLevelCompanionConflict_NonInnerToTopLevelCompanionConflict() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveNestedClass/nonInnerToTopLevelCompanionConflict/nonInnerToTopLevelCompanionConflict.test"); + doTest(fileName); + } + + @TestMetadata("kotlin/moveNestedClass/objectToTopLevel/objectToTopLevel.test") + public void testKotlin_moveNestedClass_objectToTopLevel_ObjectToTopLevel() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveNestedClass/objectToTopLevel/objectToTopLevel.test"); + doTest(fileName); + } + @TestMetadata("kotlin/movePackage/movePackage/movePackage.test") public void testKotlin_movePackage_movePackage_MovePackage() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/movePackage/movePackage/movePackage.test");