[kotlin] Move ContainerInfo to common refactoring module

^KTIJ-23273 Also renames it to `MoveContainerInfo`.

GitOrigin-RevId: 7cfc0917f999eb0aeef32ed934828d94f6bf7431
This commit is contained in:
Bart van Helvert
2023-04-28 13:11:34 +00:00
committed by intellij-monorepo-bot
parent f8d79cb446
commit 63e34c4bf3
8 changed files with 69 additions and 71 deletions
@@ -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 {
@@ -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)) {
@@ -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<UsageInfo> = 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<UsageInfo> {
@@ -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<UsageInfo>()
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 {
@@ -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
@@ -67,9 +67,9 @@ class MoveKotlinMethodProcessor(
}
override fun findUsages(): Array<UsageInfo> {
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)
@@ -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<UsageInfo> {
fun KtElement.getInternalReferencesToUpdateOnPackageNameChange(containerChangeInfo: MoveContainerChangeInfo): List<UsageInfo> {
val usages = ArrayList<UsageInfo>()
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
@@ -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)