EmptyIntersectionTypeChecker: simplify code

This commit is contained in:
Mikhail Glukhikh
2022-11-24 18:19:35 +01:00
committed by Space Team
parent 2a1a5c6936
commit 4d01ad439a
2 changed files with 22 additions and 31 deletions
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.EmptyIntersectionTypeKind
import org.jetbrains.kotlin.types.isDefinitelyEmpty
import org.jetbrains.kotlin.types.isPossiblyEmpty
import org.jetbrains.kotlin.types.TypeCheckerState
import org.jetbrains.kotlin.types.model.*
internal object EmptyIntersectionTypeChecker {
@@ -91,39 +92,24 @@ internal object EmptyIntersectionTypeChecker {
return EmptyIntersectionTypeInfo(EmptyIntersectionTypeKind.MULTIPLE_CLASSES, firstType, secondType)
}
val atLeastOneInterface = firstTypeConstructor.isInterface() || secondTypeConstructor.isInterface()
if (atLeastOneInterface) {
val incompatibleSupertypes = getIncompatibleSuperTypes(firstType, secondType)
if (incompatibleSupertypes != null) {
return EmptyIntersectionTypeInfo(EmptyIntersectionTypeKind.INCOMPATIBLE_SUPERTYPES, *incompatibleSupertypes)
}
}
val firstSuperTypeWithSecondConstructor = AbstractTypeChecker.findCorrespondingSupertypes(
typeCheckerState, firstType.lowerBoundIfFlexible(), secondTypeConstructor
).singleOrNull()
val secondSuperTypeByFirstConstructor = AbstractTypeChecker.findCorrespondingSupertypes(
typeCheckerState, secondType.lowerBoundIfFlexible(), firstTypeConstructor
).singleOrNull()
when {
firstSuperTypeWithSecondConstructor != null || secondSuperTypeByFirstConstructor != null -> {
continue
firstType.lowerBoundIfFlexible().isSubtypeOfIgnoringArguments(typeCheckerState, secondTypeConstructor) ||
secondType.lowerBoundIfFlexible().isSubtypeOfIgnoringArguments(typeCheckerState, firstTypeConstructor) -> {
}
!atLeastOneInterface -> {
!firstTypeConstructor.isInterface() && !secondTypeConstructor.isInterface() -> {
// Two classes can't have a common subtype if neither is a subtype of another
return EmptyIntersectionTypeInfo(EmptyIntersectionTypeKind.MULTIPLE_CLASSES, firstType, secondType)
}
else -> {
// don't have incompatible supertypes so can have a common subtype only if all types are interfaces
if (firstTypeConstructor.isFinalClassConstructor() || secondTypeConstructor.isFinalClassConstructor()) {
possibleEmptyIntersectionKind = EmptyIntersectionTypeInfo(
if (atLeastOneInterface) EmptyIntersectionTypeKind.FINAL_CLASS_AND_INTERFACE
else EmptyIntersectionTypeKind.SINGLE_FINAL_CLASS,
firstType, secondType
)
firstTypeConstructor.isFinalClassConstructor() || secondTypeConstructor.isFinalClassConstructor() -> {
val incompatibleSupertypes = getIncompatibleSuperTypes(firstType, secondType)
if (incompatibleSupertypes != null) {
return EmptyIntersectionTypeInfo(EmptyIntersectionTypeKind.INCOMPATIBLE_SUPERTYPES, *incompatibleSupertypes)
}
continue
// don't have incompatible supertypes so can have a common subtype only if all types are interfaces
possibleEmptyIntersectionKind = EmptyIntersectionTypeInfo(
EmptyIntersectionTypeKind.FINAL_CLASS_AND_INTERFACE,
firstType, secondType
)
}
}
}
@@ -132,6 +118,13 @@ internal object EmptyIntersectionTypeChecker {
return possibleEmptyIntersectionKind
}
private fun SimpleTypeMarker.isSubtypeOfIgnoringArguments(
typeCheckerState: TypeCheckerState,
otherConstructorMarker: TypeConstructorMarker
): Boolean = AbstractTypeChecker.findCorrespondingSupertypes(
typeCheckerState, this, otherConstructorMarker
).isNotEmpty()
private fun TypeSystemInferenceExtensionContext.getIncompatibleSuperTypes(
firstType: KotlinTypeMarker, secondType: KotlinTypeMarker
): Array<KotlinTypeMarker>? {
@@ -9,8 +9,7 @@ enum class EmptyIntersectionTypeKind(val description: String) {
MULTIPLE_CLASSES("multiple incompatible classes"),
INCOMPATIBLE_SUPERTYPES("incompatible supertypes"),
INCOMPATIBLE_TYPE_ARGUMENTS("incompatible type arguments"),
FINAL_CLASS_AND_INTERFACE("final class and interface"),
SINGLE_FINAL_CLASS("final class and non-final class")
FINAL_CLASS_AND_INTERFACE("final class and interface")
}
fun EmptyIntersectionTypeKind.isDefinitelyEmpty(): Boolean =
@@ -18,5 +17,4 @@ fun EmptyIntersectionTypeKind.isDefinitelyEmpty(): Boolean =
|| this == EmptyIntersectionTypeKind.INCOMPATIBLE_SUPERTYPES
|| this == EmptyIntersectionTypeKind.INCOMPATIBLE_TYPE_ARGUMENTS
fun EmptyIntersectionTypeKind.isPossiblyEmpty(): Boolean =
this == EmptyIntersectionTypeKind.SINGLE_FINAL_CLASS || this == EmptyIntersectionTypeKind.FINAL_CLASS_AND_INTERFACE
fun EmptyIntersectionTypeKind.isPossiblyEmpty(): Boolean = this == EmptyIntersectionTypeKind.FINAL_CLASS_AND_INTERFACE