diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationsHandler.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationsHandler.kt index 61e8121bc4e0..87ed76a69a93 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationsHandler.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/copy/CopyKotlinDeclarationsHandler.kt @@ -233,9 +233,9 @@ class CopyKotlinDeclarationsHandler : CopyHandlerDelegateBase() { private fun collectInternalUsages(sourceData: SourceData, targetData: TargetData) = runReadAction { val targetPackageName = targetData.targetDirWrapper.getPackageName() - val changeInfo = ContainerChangeInfo( - ContainerInfo.Package(sourceData.originalFile.packageFqName), - ContainerInfo.Package(FqName(targetPackageName)) + val changeInfo = MoveContainerChangeInfo( + MoveContainerInfo.Package(sourceData.originalFile.packageFqName), + MoveContainerInfo.Package(FqName(targetPackageName)) ) sourceData.elementsToCopy.flatMapTo(LinkedHashSet()) { elementToCopy -> elementToCopy.getInternalReferencesToUpdateOnPackageNameChange(changeInfo).filter { diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/changePackage/KotlinChangePackageRefactoring.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/changePackage/KotlinChangePackageRefactoring.kt index 1fe07be33d3f..9ca005b6a3f5 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/changePackage/KotlinChangePackageRefactoring.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/changePackage/KotlinChangePackageRefactoring.kt @@ -40,7 +40,7 @@ class KotlinChangePackageRefactoring(val file: KtFile) { declarationProcessor.findUsages().toList() } } ?: return - val changeInfo = ContainerChangeInfo(ContainerInfo.Package(currentFqName), ContainerInfo.Package(newFqName)) + val changeInfo = MoveContainerChangeInfo(MoveContainerInfo.Package(currentFqName), MoveContainerInfo.Package(newFqName)) val internalUsages = file.getInternalReferencesToUpdateOnPackageNameChange(changeInfo) project.executeWriteCommand(KotlinBundle.message("text.change.file.package.to.0", newFqName)) { diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveDeclarationsDelegate.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveDeclarationsDelegate.kt index 3ba82734ed07..f35b6bd376b7 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveDeclarationsDelegate.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveDeclarationsDelegate.kt @@ -21,7 +21,7 @@ import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.resolve.descriptorUtil.isSubclassOf sealed class MoveDeclarationsDelegate { - abstract fun getContainerChangeInfo(originalDeclaration: KtNamedDeclaration, moveTarget: KotlinMoveTarget): ContainerChangeInfo + abstract fun getContainerChangeInfo(originalDeclaration: KtNamedDeclaration, moveTarget: KotlinMoveTarget): MoveContainerChangeInfo open fun findInternalUsages(descriptor: MoveDeclarationsDescriptor): List = emptyList() @@ -42,10 +42,10 @@ sealed class MoveDeclarationsDelegate { } object TopLevel : MoveDeclarationsDelegate() { - override fun getContainerChangeInfo(originalDeclaration: KtNamedDeclaration, moveTarget: KotlinMoveTarget): ContainerChangeInfo { - val sourcePackage = ContainerInfo.Package(originalDeclaration.containingKtFile.packageFqName) - val targetPackage = moveTarget.targetContainerFqName?.let { ContainerInfo.Package(it) } ?: ContainerInfo.UnknownPackage - return ContainerChangeInfo(sourcePackage, targetPackage) + override fun getContainerChangeInfo(originalDeclaration: KtNamedDeclaration, moveTarget: KotlinMoveTarget): MoveContainerChangeInfo { + val sourcePackage = MoveContainerInfo.Package(originalDeclaration.containingKtFile.packageFqName) + val targetPackage = moveTarget.targetContainerFqName?.let { MoveContainerInfo.Package(it) } ?: MoveContainerInfo.UnknownPackage + return MoveContainerChangeInfo(sourcePackage, targetPackage) } } @@ -53,16 +53,16 @@ sealed class MoveDeclarationsDelegate { val newClassName: String? = null, private val outerInstanceParameterName: String? = null ) : MoveDeclarationsDelegate() { - override fun getContainerChangeInfo(originalDeclaration: KtNamedDeclaration, moveTarget: KotlinMoveTarget): ContainerChangeInfo { - val originalInfo = ContainerInfo.Class(originalDeclaration.containingClassOrObject!!.fqName!!) + override fun getContainerChangeInfo(originalDeclaration: KtNamedDeclaration, moveTarget: KotlinMoveTarget): MoveContainerChangeInfo { + val originalInfo = MoveContainerInfo.Class(originalDeclaration.containingClassOrObject!!.fqName!!) val movingToClass = (moveTarget as? KotlinMoveTarget.ExistingElement)?.targetElement is KtClassOrObject val targetContainerFqName = moveTarget.targetContainerFqName val newInfo = when { - targetContainerFqName == null -> ContainerInfo.UnknownPackage - movingToClass -> ContainerInfo.Class(targetContainerFqName) - else -> ContainerInfo.Package(targetContainerFqName) + targetContainerFqName == null -> MoveContainerInfo.UnknownPackage + movingToClass -> MoveContainerInfo.Class(targetContainerFqName) + else -> MoveContainerInfo.Package(targetContainerFqName) } - return ContainerChangeInfo(originalInfo, newInfo) + return MoveContainerChangeInfo(originalInfo, newInfo) } override fun findInternalUsages(descriptor: MoveDeclarationsDescriptor): List { diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsProcessor.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsProcessor.kt index 2159676df4a2..656a7928c2d5 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsProcessor.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/MoveKotlinDeclarationsProcessor.kt @@ -167,7 +167,7 @@ class MoveKotlinDeclarationsProcessor( val targetModule = moveTarget.getTargetModule(project) ?: return projectScope if (oldContainer != newContainer || ktDeclaration.module != targetModule) return projectScope // Check if facade class may change - if (newContainer is ContainerInfo.Package) { + if (newContainer is MoveContainerInfo.Package) { val javaScope = projectScope.restrictByFileType(JavaFileType.INSTANCE) val currentFile = ktDeclaration.containingKtFile val newFile = when (moveTarget) { @@ -267,9 +267,9 @@ class MoveKotlinDeclarationsProcessor( val externalUsages = LinkedHashSet() if (moveEntireFile) { - val changeInfo = ContainerChangeInfo( - ContainerInfo.Package(sourceFile.packageFqName), - descriptor.moveTarget.targetContainerFqName?.let { ContainerInfo.Package(it) } ?: ContainerInfo.UnknownPackage + val changeInfo = MoveContainerChangeInfo( + MoveContainerInfo.Package(sourceFile.packageFqName), + descriptor.moveTarget.targetContainerFqName?.let { MoveContainerInfo.Package(it) } ?: MoveContainerInfo.UnknownPackage ) internalUsages += sourceFile.getInternalReferencesToUpdateOnPackageNameChange(changeInfo) } else { diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/MoveKotlinFileHandler.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/MoveKotlinFileHandler.kt index 01fd2ea78ba0..3b480906b19b 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/MoveKotlinFileHandler.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveFilesOrDirectories/MoveKotlinFileHandler.kt @@ -35,16 +35,16 @@ class MoveKotlinFileHandler : MoveFileHandler() { override fun toString() = "" } - private fun KtFile.getPackageNameInfo(newParent: PsiDirectory?, clearUserData: Boolean): ContainerChangeInfo? { + private fun KtFile.getPackageNameInfo(newParent: PsiDirectory?, clearUserData: Boolean): MoveContainerChangeInfo? { val shouldUpdatePackageDirective = updatePackageDirective ?: packageMatchesDirectoryOrImplicit() updatePackageDirective = if (clearUserData) null else shouldUpdatePackageDirective if (!shouldUpdatePackageDirective) return null val oldPackageName = packageFqName - val newPackageName = newParent?.getFqNameWithImplicitPrefix() ?: return ContainerChangeInfo( - ContainerInfo.Package(oldPackageName), - ContainerInfo.UnknownPackage + val newPackageName = newParent?.getFqNameWithImplicitPrefix() ?: return MoveContainerChangeInfo( + MoveContainerInfo.Package(oldPackageName), + MoveContainerInfo.UnknownPackage ) if (oldPackageName.asString() == newPackageName.asString() @@ -52,7 +52,7 @@ class MoveKotlinFileHandler : MoveFileHandler() { ) return null if (!newPackageName.hasIdentifiersOnly()) return null - return ContainerChangeInfo(ContainerInfo.Package(oldPackageName), ContainerInfo.Package(newPackageName)) + return MoveContainerChangeInfo(MoveContainerInfo.Package(oldPackageName), MoveContainerInfo.Package(newPackageName)) } fun initMoveProcessor( @@ -68,7 +68,7 @@ class MoveKotlinFileHandler : MoveFileHandler() { val project = psiFile.project val moveTarget = when (val newPackage = packageNameInfo.newContainer) { - ContainerInfo.UnknownPackage -> KotlinMoveTarget.Empty + MoveContainerInfo.UnknownPackage -> KotlinMoveTarget.Empty else -> if (newParent == null) { return null diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveMethod/MoveKotlinMethodProcessor.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveMethod/MoveKotlinMethodProcessor.kt index 5889264d6bc7..8717b1ab9ad7 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveMethod/MoveKotlinMethodProcessor.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveMethod/MoveKotlinMethodProcessor.kt @@ -67,9 +67,9 @@ class MoveKotlinMethodProcessor( } override fun findUsages(): Array { - val changeInfo = ContainerChangeInfo( - ContainerInfo.Class(method.containingClassOrObject!!.fqName!!), - ContainerInfo.Class(targetClassOrObject.fqName!!) + val changeInfo = MoveContainerChangeInfo( + MoveContainerInfo.Class(method.containingClassOrObject!!.fqName!!), + MoveContainerInfo.Class(targetClassOrObject.fqName!!) ) val conflictChecker = MoveConflictChecker(myProject, listOf(method), KotlinMoveTarget.ExistingElement(targetClassOrObject), method) diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveUtils.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveUtils.kt index 9fb5132bf85f..c6fcd285452a 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveUtils.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveUtils.kt @@ -25,8 +25,8 @@ import com.intellij.util.SmartList import com.intellij.util.containers.MultiMap import org.jetbrains.kotlin.asJava.unwrapped import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.idea.base.resources.KotlinBundle import org.jetbrains.kotlin.idea.KotlinFileType +import org.jetbrains.kotlin.idea.base.resources.KotlinBundle import org.jetbrains.kotlin.idea.base.utils.fqname.isImported import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithAllCompilerChecks @@ -61,39 +61,8 @@ import java.io.File import java.lang.System.currentTimeMillis import java.util.* -sealed class ContainerInfo { - abstract val fqName: FqName? - abstract fun matches(descriptor: DeclarationDescriptor): Boolean - object UnknownPackage : ContainerInfo() { - override val fqName: 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 - } - - override fun equals(other: Any?) = other is Package && other.fqName == fqName - - override fun hashCode() = fqName.hashCode() - } - - class Class(override val fqName: FqName) : ContainerInfo() { - override fun matches(descriptor: DeclarationDescriptor): Boolean { - return descriptor is ClassDescriptor && descriptor.importableFqName == fqName - } - - override fun equals(other: Any?) = other is Class && other.fqName == fqName - - override fun hashCode() = fqName.hashCode() - } -} - -data class ContainerChangeInfo(val oldContainer: ContainerInfo, val newContainer: ContainerInfo) - -fun KtElement.getInternalReferencesToUpdateOnPackageNameChange(containerChangeInfo: ContainerChangeInfo): List { +fun KtElement.getInternalReferencesToUpdateOnPackageNameChange(containerChangeInfo: MoveContainerChangeInfo): List { val usages = ArrayList() processInternalReferencesToUpdateOnPackageNameChange(containerChangeInfo) { expr, factory -> usages.addIfNotNull(factory(expr)) } return usages @@ -102,7 +71,7 @@ fun KtElement.getInternalReferencesToUpdateOnPackageNameChange(containerChangeIn private typealias UsageInfoFactory = (KtSimpleNameExpression) -> UsageInfo? fun KtElement.processInternalReferencesToUpdateOnPackageNameChange( - containerChangeInfo: ContainerChangeInfo, + containerChangeInfo: MoveContainerChangeInfo, body: (originalRefExpr: KtSimpleNameExpression, usageFactory: UsageInfoFactory) -> Unit ) { val file = containingFile as? KtFile ?: return @@ -119,6 +88,12 @@ fun KtElement.processInternalReferencesToUpdateOnPackageNameChange( } } + fun MoveContainerInfo.matches(decl: DeclarationDescriptor) = when(this) { + is MoveContainerInfo.UnknownPackage -> decl is PackageViewDescriptor && decl.fqName == fqName + is MoveContainerInfo.Package -> decl is PackageFragmentDescriptor && decl.fqName == fqName + is MoveContainerInfo.Class -> decl is ClassDescriptor && decl.importableFqName == fqName + } + fun processReference(refExpr: KtSimpleNameExpression, bindingContext: BindingContext): (UsageInfoFactory)? { val descriptor = bindingContext[BindingContext.REFERENCE_TARGET, refExpr]?.getImportableDescriptor() ?: return null val containingDescriptor = descriptor.containingDeclaration ?: return null @@ -171,16 +146,13 @@ fun KtElement.processInternalReferencesToUpdateOnPackageNameChange( val (oldContainer, newContainer) = containerChangeInfo - val containerFqName = descriptor - .parents - .mapNotNull { - when { - oldContainer.matches(it) -> oldContainer.fqName - newContainer.matches(it) -> newContainer.fqName - else -> null - } + val containerFqName = descriptor.parents.mapNotNull { + when { + oldContainer.matches(it) -> oldContainer.fqName + newContainer.matches(it) -> newContainer.fqName + else -> null } - .firstOrNull() + }.firstOrNull() val isImported = isImported(descriptor) if (isImported && this is KtFile) return null diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/move/MoveContainerInfo.kt b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/move/MoveContainerInfo.kt new file mode 100644 index 000000000000..2c08d8048428 --- /dev/null +++ b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/move/MoveContainerInfo.kt @@ -0,0 +1,26 @@ +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.idea.refactoring.move + +import org.jetbrains.kotlin.name.FqName + +sealed interface MoveContainerInfo { + val fqName: FqName? + + object UnknownPackage : MoveContainerInfo { + override val fqName: FqName? = null + } + + class Package(override val fqName: FqName) : MoveContainerInfo { + override fun equals(other: Any?) = other is Package && other.fqName == fqName + + override fun hashCode() = fqName.hashCode() + } + + class Class(override val fqName: FqName) : MoveContainerInfo { + override fun equals(other: Any?) = other is Class && other.fqName == fqName + + override fun hashCode() = fqName.hashCode() + } +} + +data class MoveContainerChangeInfo(val oldContainer: MoveContainerInfo, val newContainer: MoveContainerInfo) \ No newline at end of file