diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/KtSimpleNameReference.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/KtSimpleNameReference.kt index 9ef6bc7fce8..0ff562164e2 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/KtSimpleNameReference.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/KtSimpleNameReference.kt @@ -24,7 +24,6 @@ import com.intellij.util.IncorrectOperationException import com.intellij.util.SmartList import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.idea.codeInsight.shorten.addToShorteningWaitSet -import org.jetbrains.kotlin.idea.codeInsight.shorten.isToBeShortened import org.jetbrains.kotlin.idea.core.ShortenReferences import org.jetbrains.kotlin.idea.core.copied import org.jetbrains.kotlin.idea.core.quoteIfNeeded @@ -38,7 +37,10 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.isOneSegmentFQN import org.jetbrains.kotlin.plugin.references.SimpleNameReferenceExtension import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.* +import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch +import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementOrCallableRef +import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector +import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DataClassDescriptorResolver import org.jetbrains.kotlin.types.expressions.OperatorConventions @@ -130,7 +132,6 @@ class KtSimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleRefere enum class ShorteningMode { NO_SHORTENING, DELAYED_SHORTENING, - DELAYED_SHORTENING_VIA_USER_DATA, FORCED_SHORTENING } @@ -159,7 +160,6 @@ class KtSimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleRefere if (needToShorten) { when (shorteningMode) { ShorteningMode.FORCED_SHORTENING -> ShortenReferences.DEFAULT.process(newQualifiedElement) - ShorteningMode.DELAYED_SHORTENING_VIA_USER_DATA -> newQualifiedElement.isToBeShortened = true else -> newQualifiedElement.addToShorteningWaitSet() } } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsProcessor.kt index 05a7619d4fd..37dd6578390 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsProcessor.kt @@ -18,6 +18,7 @@ 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.Key import com.intellij.openapi.util.Ref import com.intellij.openapi.util.text.StringUtil import com.intellij.psi.PsiElement @@ -29,6 +30,7 @@ import com.intellij.refactoring.move.MoveCallback import com.intellij.refactoring.move.MoveMultipleElementsViewDescriptor import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassHandler 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 @@ -47,9 +49,9 @@ import org.jetbrains.kotlin.idea.core.deleteSingle import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName 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.* +import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext import org.jetbrains.kotlin.psi.psiUtil.isAncestor @@ -81,6 +83,8 @@ interface Mover : (KtNamedDeclaration, KtElement) -> KtNamedDeclaration { } } +internal var KtSimpleNameExpression.internalUsageInfo: UsageInfo? by CopyableUserDataProperty(Key.create("INTERNAL_USAGE_INFO")) + class MoveDeclarationsDescriptor( val elementsToMove: Collection, val moveTarget: KotlinMoveTarget, @@ -122,12 +126,6 @@ class MoveKotlinDeclarationsProcessor( fun getConflictsAsUsages(): List = conflicts.entrySet().map { ConflictUsageInfo(it.key, it.value) } - class UsageToProcessBeforeMoveWrapper private constructor (element: PsiElement, val originalUsage: UsageInfo): UsageInfo(element) { - companion object { - fun create(originalUsage: UsageInfo) = originalUsage.element?.let { UsageToProcessBeforeMoveWrapper(it, originalUsage) } - } - } - public override fun findUsages(): Array { if (elementsToMove.isEmpty()) return UsageInfo.EMPTY_ARRAY @@ -194,12 +192,8 @@ class MoveKotlinDeclarationsProcessor( conflictChecker.checkAllConflicts(externalUsages, internalUsages, conflicts) descriptor.delegate.collectConflicts(descriptor, internalUsages, conflicts) + usages += internalUsages usages += externalUsages - - val (usagesToProcessLater, usagesToProcessEarly) = internalUsages.partition { it is UnqualifiableMoveRenameUsageInfo } - usages += usagesToProcessLater - usagesToProcessBeforeMove += usagesToProcessEarly - usages += usagesToProcessBeforeMove.mapNotNull { UsageToProcessBeforeMoveWrapper.create(it) } } descriptor.delegate.collectConflicts(descriptor, usagesToProcessBeforeMove, conflicts) @@ -212,32 +206,25 @@ class MoveKotlinDeclarationsProcessor( } override fun performRefactoring(usages: Array) { - fun moveDeclaration(declaration: KtNamedDeclaration, moveTarget: KotlinMoveTarget): KtNamedDeclaration? { - val file = declaration.containingFile as? KtFile - assert(file != null) { "${declaration::class.java}: ${declaration.text}" } - + fun moveDeclaration(declaration: KtNamedDeclaration, moveTarget: KotlinMoveTarget): KtNamedDeclaration { val targetContainer = moveTarget.getOrCreateTargetPsi(declaration) ?: throw AssertionError("Couldn't create Kotlin file for: ${declaration::class.java}: ${declaration.text}") - descriptor.delegate.preprocessDeclaration(descriptor, declaration) - val newElement = mover(declaration, targetContainer) - - newElement.addToBeShortenedDescendantsToWaitingSet() - - return newElement + return mover(declaration, targetContainer).apply { + addToBeShortenedDescendantsToWaitingSet() + } } + val usageList = usages.toList() + val (oldInternalUsages, externalUsages) = usageList.partition { (it as? InternableUsage)?.scope != null } + val newInternalUsages = ArrayList() + + oldInternalUsages.forEach { (it.element as? KtSimpleNameExpression)?.internalUsageInfo = it } + + val usagesToProcess = ArrayList(externalUsages) + try { - val usageList = usages.toList() - - val (usagesToProcessBeforeMoveWrappers, usagesToProcessAfterMove) = - usageList.partition { it is UsageToProcessBeforeMoveWrapper } - val usagesToProcessBeforeMove = usagesToProcessBeforeMoveWrappers.map { (it as UsageToProcessBeforeMoveWrapper).originalUsage } - - descriptor.delegate.preprocessUsages(project, descriptor, usagesToProcessBeforeMove) - descriptor.delegate.preprocessUsages(project, descriptor, usagesToProcessAfterMove) - - postProcessMoveUsages(usagesToProcessBeforeMove, shorteningMode = ShorteningMode.DELAYED_SHORTENING_VIA_USER_DATA) + descriptor.delegate.preprocessUsages(project, descriptor, usageList) val oldToNewElementsMapping = THashMap( object: TObjectHashingStrategy { @@ -259,18 +246,17 @@ class MoveKotlinDeclarationsProcessor( } } ) + + val newDeclarations = ArrayList() + for ((sourceFile, kotlinToLightElements) in kotlinToLightElementsBySourceFile) { for ((oldDeclaration, oldLightElements) in kotlinToLightElements) { val elementListener = transaction!!.getElementListener(oldDeclaration) val newDeclaration = moveDeclaration(oldDeclaration, descriptor.moveTarget) - if (newDeclaration == null) { - for (oldElement in oldLightElements) { - oldToNewElementsMapping[oldElement] = oldElement - } - continue - } + newDeclarations += newDeclaration + oldToNewElementsMapping[oldDeclaration] = newDeclaration oldToNewElementsMapping[sourceFile] = newDeclaration.containingKtFile elementListener.elementMoved(newDeclaration) @@ -288,12 +274,33 @@ class MoveKotlinDeclarationsProcessor( } } - nonCodeUsages = postProcessMoveUsages(usagesToProcessAfterMove, oldToNewElementsMapping).toTypedArray() + newDeclarations.forEach { newDeclaration -> + newInternalUsages += newDeclaration.collectDescendantsOfType().mapNotNull { + val usageInfo = it.internalUsageInfo + if (usageInfo?.element != null) return@mapNotNull usageInfo + val referencedElement = (usageInfo as? MoveRenameUsageInfo)?.referencedElement ?: return@mapNotNull null + val newReferencedElement = oldToNewElementsMapping[referencedElement] ?: referencedElement + if (!newReferencedElement.isValid) return@mapNotNull null + (usageInfo as? InternableUsage)?.refresh(it, newReferencedElement) + } + } + + usagesToProcess += newInternalUsages + + nonCodeUsages = postProcessMoveUsages(usagesToProcess, oldToNewElementsMapping).toTypedArray() } catch (e: IncorrectOperationException) { nonCodeUsages = null RefactoringUIUtil.processIncorrectOperation(myProject, e) } + finally { + (newInternalUsages + oldInternalUsages).forEach { + val element = it.element as? KtSimpleNameExpression ?: return@forEach + if (element.isValid) { + element.internalUsageInfo = null + } + } + } } override fun performPsiSpoilingRefactoring() { 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 794f58d2b7f..dc35e60f75b 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.impl.source.resolve.reference.impl.PsiMultiReference import com.intellij.refactoring.RefactoringBundle import com.intellij.refactoring.copy.CopyFilesOrDirectoriesHandler import com.intellij.refactoring.move.MoveCallback @@ -123,11 +124,9 @@ fun KtElement.lazilyProcessInternalReferencesToUpdateOnPackageNameChange( val descriptor = bindingContext[BindingContext.REFERENCE_TARGET, refExpr]?.getImportableDescriptor() ?: return null val containingDescriptor = descriptor.containingDeclaration ?: return null - val declaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, descriptor) ?: return null + var declaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, descriptor) ?: return null val callableKind = (descriptor as? CallableMemberDescriptor)?.kind - val containingDeclarationForNonRealMember = if (callableKind != CallableMemberDescriptor.Kind.DECLARATION) { - DescriptorToSourceUtilsIde.getAnyDeclaration(project, containingDescriptor) as? KtClassOrObject - } else null + if (callableKind != null && callableKind != CallableMemberDescriptor.Kind.DECLARATION) 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 @@ -156,13 +155,13 @@ fun KtElement.lazilyProcessInternalReferencesToUpdateOnPackageNameChange( } } - val fqName = DescriptorUtils.getFqName(descriptor).let { - if (DescriptorUtils.isCompanionObject(descriptor) - && bindingContext[BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, refExpr] != null) { - it.parent() - } - else it + if (declaration is KtObjectDeclaration + && declaration.isCompanion() + && bindingContext[BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, refExpr] != null) { + declaration = declaration.containingClassOrObject ?: declaration } + + val fqName = DescriptorUtils.getFqName(descriptor) if (!fqName.isSafe) return null val (oldContainer, newContainer) = containerChangeInfo @@ -178,30 +177,10 @@ fun KtElement.lazilyProcessInternalReferencesToUpdateOnPackageNameChange( } .firstOrNull() - fun doCreateUsageInfo(refExpr: KtSimpleNameExpression): UsageInfo? { - // Check container instead of declaration itself as the latter may be not real (e.g. fake override) - if (isAncestor(containingDeclarationForNonRealMember ?: declaration, false)) { - if (descriptor.importableFqName == null) return null - if (getReferenceKind(refExpr.mainReference, declaration) != ReferenceKind.QUALIFIABLE) return null - if (containerFqName == null || newContainer is ContainerInfo.UnknownPackage) return null - return fqName.asString().let { - val prefix = containerFqName.asString() - val prefixOffset = it.indexOf(prefix) - val newFqName = if (prefix.isEmpty()) { - val newContainerFqName = newContainer.fqName!! - FqName(if (newContainerFqName.isRoot) it else "${newContainer.fqName!!.asString()}.$it") - } - else { - FqName(it.replaceRange(prefixOffset..prefixOffset + prefix.length - 1, newContainer.fqName!!.asString())) - } - MoveRenameSelfUsageInfo(refExpr.mainReference, declaration, newFqName) - } - } - - return createMoveUsageInfoIfPossible(refExpr.mainReference, declaration, false, fqName.toSafe()) + if (isExtension || containerFqName != null || isImported(descriptor)) return { + createMoveUsageInfoIfPossible(it.mainReference, declaration, false, this@lazilyProcessInternalReferencesToUpdateOnPackageNameChange) } - if (isExtension || containerFqName != null || isImported(descriptor)) return ::doCreateUsageInfo return null } @@ -216,49 +195,52 @@ fun KtElement.lazilyProcessInternalReferencesToUpdateOnPackageNameChange( class ImplicitCompanionAsDispatchReceiverUsageInfo(callee: KtSimpleNameExpression) : UsageInfo(callee) +interface InternableUsage { + val scope: PsiElement? + + fun refresh(refExpr: KtSimpleNameExpression, referencedElement: PsiElement): UsageInfo? +} + class UnqualifiableMoveRenameUsageInfo( element: PsiElement, reference: PsiReference, - startOffset: Int, - endOffset: Int, referencedElement: PsiElement, val originalFile: PsiFile, - val addImportToOriginalFile: Boolean -): MoveRenameUsageInfo(element, reference, startOffset, endOffset, referencedElement, false) - -class MoveRenameSelfUsageInfo(ref: KtSimpleNameReference, refTarget: PsiElement, val newFqName: FqName): - MoveRenameUsageInfo(ref.element, ref, ref.rangeInElement.startOffset, ref.rangeInElement.endOffset, refTarget, false) { - override fun getReference() = super.getReference() as? KtSimpleNameReference + val addImportToOriginalFile: Boolean, + override val scope: PsiElement? +): MoveRenameUsageInfo(element, reference, reference.rangeInElement.startOffset, reference.rangeInElement.endOffset, referencedElement, false), InternableUsage { + override fun refresh(refExpr: KtSimpleNameExpression, referencedElement: PsiElement): UsageInfo? { + return UnqualifiableMoveRenameUsageInfo(refExpr, refExpr.mainReference, referencedElement, originalFile, addImportToOriginalFile, scope) + } } class QualifiableMoveRenameUsageInfo( element: PsiElement, reference: PsiReference, - startOffset: Int, - endOffset: Int, referencedElement: PsiElement, - val newFqName: FqName? -): MoveRenameUsageInfo(element, reference, startOffset, endOffset, referencedElement, false) + override val scope: PsiElement? +): MoveRenameUsageInfo(element, reference, reference.rangeInElement.startOffset, reference.rangeInElement.endOffset, referencedElement, false), + InternableUsage { + override fun refresh(refExpr: KtSimpleNameExpression, referencedElement: PsiElement): UsageInfo? { + return QualifiableMoveRenameUsageInfo(refExpr, refExpr.mainReference, referencedElement, scope) + } +} fun createMoveUsageInfoIfPossible( reference: PsiReference, referencedElement: PsiElement, addImportToOriginalFile: Boolean, - newFqName: FqName? + scope: PsiElement? ): UsageInfo? { val element = reference.element if (element.getStrictParentOfType() != null) return null - val range = reference.rangeInElement!! - val startOffset = range.startOffset - val endOffset = range.endOffset - return when (getReferenceKind(reference, referencedElement)) { ReferenceKind.QUALIFIABLE -> QualifiableMoveRenameUsageInfo( - element, reference, startOffset, endOffset, referencedElement, newFqName + element, reference, referencedElement, scope ) ReferenceKind.UNQUALIFIABLE -> UnqualifiableMoveRenameUsageInfo( - element, reference, startOffset, endOffset, referencedElement, element.containingFile!!, addImportToOriginalFile + element, reference, referencedElement, element.containingFile!!, addImportToOriginalFile, scope ) else -> null } @@ -332,6 +314,48 @@ private fun updateJavaReference(reference: PsiReferenceExpression, oldElement: P return false } +private fun mapToNewOrThis(e: PsiElement, oldToNewElementsMapping: Map) = oldToNewElementsMapping[e] ?: e + +private fun postProcessMoveUsage( + usage: UsageInfo, + oldToNewElementsMapping: Map, + nonCodeUsages: ArrayList, + shorteningMode: ShorteningMode +) { + when (usage) { + is NonCodeUsageInfo -> { + nonCodeUsages.add(usage) + } + + is UnqualifiableMoveRenameUsageInfo -> { + val file = with(usage) { if (addImportToOriginalFile) originalFile else mapToNewOrThis(originalFile, oldToNewElementsMapping) } as KtFile + val declaration = mapToNewOrThis(usage.referencedElement!!, oldToNewElementsMapping) + addDelayedImportRequest(declaration, file) + } + + is MoveRenameUsageInfo -> { + val oldElement = usage.referencedElement!! + val newElement = mapToNewOrThis(oldElement, oldToNewElementsMapping) + val reference = usage.reference ?: (usage.element as? KtSimpleNameExpression)?.mainReference + processReference(reference, newElement, shorteningMode, oldElement) + } + } +} + +private fun processReference(reference: PsiReference?, newElement: PsiElement, shorteningMode: ShorteningMode, oldElement: PsiElement) { + try { + when { + reference is PsiMultiReference -> reference.references.forEach { processReference(it, newElement, shorteningMode, oldElement) } + reference is KtSimpleNameReference -> reference.bindToElement(newElement, shorteningMode) + reference is PsiReferenceExpression && updateJavaReference(reference, oldElement, newElement) -> return + else -> reference?.bindToElement(newElement) + } + } + catch (e: IncorrectOperationException) { + // Suppress exception if bindToElement is not implemented + } +} + /** * Perform usage postprocessing and return non-code usages */ @@ -339,9 +363,7 @@ fun postProcessMoveUsages(usages: Collection, oldToNewElementsMapping: Map = Collections.emptyMap(), shorteningMode: ShorteningMode = ShorteningMode.DELAYED_SHORTENING ): List { - fun counterpart(e: PsiElement) = oldToNewElementsMapping[e] ?: e - - val sortedUsages = usages.sortedWith( + val sortedUsages = usages.sortedWith( Comparator { o1, o2 -> val file1 = o1.virtualFile val file2 = o2.virtualFile @@ -362,45 +384,7 @@ fun postProcessMoveUsages(usages: Collection, val nonCodeUsages = ArrayList() usageLoop@ for (usage in sortedUsages) { - when (usage) { - is NonCodeUsageInfo -> { - nonCodeUsages.add(usage) - } - - is MoveRenameSelfUsageInfo -> { - usage.reference?.bindToFqName(usage.newFqName, shorteningMode) - } - - is UnqualifiableMoveRenameUsageInfo -> { - val file = with(usage) { if (addImportToOriginalFile) originalFile else counterpart(originalFile) } as KtFile - val declaration = counterpart(usage.referencedElement!!) - addDelayedImportRequest(declaration, file) - } - - is MoveRenameUsageInfo -> { - val oldElement = usage.referencedElement!! - val newElement = counterpart(oldElement) - val reference = usage.reference ?: (usage.element as? KtSimpleNameExpression)?.mainReference - try { - when { - reference is KtSimpleNameReference -> { - val newFqName = (usage as? QualifiableMoveRenameUsageInfo)?.newFqName - if (newFqName != null) { - reference.bindToFqName(newFqName, shorteningMode) - } - else { - 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 - } - } - } + postProcessMoveUsage(usage, oldToNewElementsMapping, nonCodeUsages, shorteningMode) } return nonCodeUsages diff --git a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/mutualDependency/after/pack/test.kt b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/mutualDependency/after/pack/test.kt new file mode 100644 index 00000000000..b3e8a6e2a81 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/mutualDependency/after/pack/test.kt @@ -0,0 +1,3 @@ +package pack + +class C \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/mutualDependency/after/pack2/test.kt b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/mutualDependency/after/pack2/test.kt new file mode 100644 index 00000000000..da33f117476 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/mutualDependency/after/pack2/test.kt @@ -0,0 +1,15 @@ +package pack2 + +import pack.C + +class A { + val a = A() + val b = B() + val c = C() +} + +class B { + val a = A() + val b = B() + val c = C() +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/mutualDependency/before/pack/test.kt b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/mutualDependency/before/pack/test.kt new file mode 100644 index 00000000000..83505e3694c --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/mutualDependency/before/pack/test.kt @@ -0,0 +1,15 @@ +package pack + +class A { + val a = A() + val b = B() + val c = C() +} + +class B { + val a = A() + val b = B() + val c = C() +} + +class C \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/mutualDependency/mutualDependency.test b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/mutualDependency/mutualDependency.test new file mode 100644 index 00000000000..8888b775b06 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/mutualDependency/mutualDependency.test @@ -0,0 +1,5 @@ +{ + "mainFile": "pack/test.kt", + "type": "MOVE_KOTLIN_TOP_LEVEL_DECLARATIONS", + "targetPackage": "pack2" +} 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 87650e226e8..55889e4e572 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/MoveTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/MoveTestGenerated.java @@ -534,6 +534,12 @@ public class MoveTestGenerated extends AbstractMoveTest { doTest(fileName); } + @TestMetadata("kotlin/moveTopLevelDeclarations/misc/mutualDependency/mutualDependency.test") + public void testKotlin_moveTopLevelDeclarations_misc_mutualDependency_MutualDependency() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/mutualDependency/mutualDependency.test"); + doTest(fileName); + } + @TestMetadata("kotlin/moveTopLevelDeclarations/misc/selfReferences/selfReferences.test") public void testKotlin_moveTopLevelDeclarations_misc_selfReferences_SelfReferences() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/selfReferences/selfReferences.test");