Move: Check if sealed class is moved with its subclasses
#KT-22769 Fixed
This commit is contained in:
+34
@@ -59,6 +59,7 @@ import org.jetbrains.kotlin.renderer.ParameterNameRenderingPolicy
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getImportableDescriptor
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isSubclassOf
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
@@ -451,6 +452,38 @@ class MoveConflictChecker(
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSealedClassMove(conflicts: MultiMap<PsiElement, String>) {
|
||||
val visited = HashSet<PsiElement>()
|
||||
for (elementToMove in elementsToMove) {
|
||||
if (!visited.add(elementToMove)) continue
|
||||
if (elementToMove !is KtClassOrObject) continue
|
||||
|
||||
val rootClass: KtClass
|
||||
val rootClassDescriptor: ClassDescriptor
|
||||
if (elementToMove is KtClass && elementToMove.isSealed()) {
|
||||
rootClass = elementToMove
|
||||
rootClassDescriptor = rootClass.resolveToDescriptorIfAny() as? ClassDescriptor ?: return
|
||||
}
|
||||
else {
|
||||
val classDescriptor = elementToMove.resolveToDescriptorIfAny() as? ClassDescriptor ?: return
|
||||
val superClassDescriptor = classDescriptor.getSuperClassNotAny() ?: return
|
||||
if (superClassDescriptor.modality != Modality.SEALED) return
|
||||
rootClassDescriptor = superClassDescriptor
|
||||
rootClass = rootClassDescriptor.source.getPsi() as? KtClass ?: return
|
||||
}
|
||||
|
||||
val subclasses = rootClassDescriptor.sealedSubclasses.mapNotNull { it.source.getPsi() }
|
||||
if (subclasses.isEmpty()) continue
|
||||
|
||||
visited.add(rootClass)
|
||||
visited.addAll(subclasses)
|
||||
|
||||
if (isToBeMoved(rootClass) && subclasses.all { isToBeMoved(it) }) continue
|
||||
|
||||
conflicts.putValue(rootClass, "Sealed class '${rootClass.name}' must be moved with all its subclasses")
|
||||
}
|
||||
}
|
||||
|
||||
fun checkAllConflicts(
|
||||
externalUsages: MutableSet<UsageInfo>,
|
||||
internalUsages: MutableSet<UsageInfo>,
|
||||
@@ -461,6 +494,7 @@ class MoveConflictChecker(
|
||||
checkVisibilityInUsages(externalUsages, conflicts)
|
||||
checkVisibilityInDeclarations(conflicts)
|
||||
checkInternalMemberUsages(conflicts)
|
||||
checkSealedClassMove(conflicts)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user