EmptyIntersectionTypeChecker: simplify code
This commit is contained in:
committed by
Space Team
parent
2a1a5c6936
commit
4d01ad439a
+20
-27
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.types.AbstractTypeChecker
|
|||||||
import org.jetbrains.kotlin.types.EmptyIntersectionTypeKind
|
import org.jetbrains.kotlin.types.EmptyIntersectionTypeKind
|
||||||
import org.jetbrains.kotlin.types.isDefinitelyEmpty
|
import org.jetbrains.kotlin.types.isDefinitelyEmpty
|
||||||
import org.jetbrains.kotlin.types.isPossiblyEmpty
|
import org.jetbrains.kotlin.types.isPossiblyEmpty
|
||||||
|
import org.jetbrains.kotlin.types.TypeCheckerState
|
||||||
import org.jetbrains.kotlin.types.model.*
|
import org.jetbrains.kotlin.types.model.*
|
||||||
|
|
||||||
internal object EmptyIntersectionTypeChecker {
|
internal object EmptyIntersectionTypeChecker {
|
||||||
@@ -91,39 +92,24 @@ internal object EmptyIntersectionTypeChecker {
|
|||||||
return EmptyIntersectionTypeInfo(EmptyIntersectionTypeKind.MULTIPLE_CLASSES, firstType, secondType)
|
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 {
|
when {
|
||||||
firstSuperTypeWithSecondConstructor != null || secondSuperTypeByFirstConstructor != null -> {
|
firstType.lowerBoundIfFlexible().isSubtypeOfIgnoringArguments(typeCheckerState, secondTypeConstructor) ||
|
||||||
continue
|
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
|
// Two classes can't have a common subtype if neither is a subtype of another
|
||||||
return EmptyIntersectionTypeInfo(EmptyIntersectionTypeKind.MULTIPLE_CLASSES, firstType, secondType)
|
return EmptyIntersectionTypeInfo(EmptyIntersectionTypeKind.MULTIPLE_CLASSES, firstType, secondType)
|
||||||
}
|
}
|
||||||
else -> {
|
firstTypeConstructor.isFinalClassConstructor() || secondTypeConstructor.isFinalClassConstructor() -> {
|
||||||
// don't have incompatible supertypes so can have a common subtype only if all types are interfaces
|
val incompatibleSupertypes = getIncompatibleSuperTypes(firstType, secondType)
|
||||||
if (firstTypeConstructor.isFinalClassConstructor() || secondTypeConstructor.isFinalClassConstructor()) {
|
if (incompatibleSupertypes != null) {
|
||||||
possibleEmptyIntersectionKind = EmptyIntersectionTypeInfo(
|
return EmptyIntersectionTypeInfo(EmptyIntersectionTypeKind.INCOMPATIBLE_SUPERTYPES, *incompatibleSupertypes)
|
||||||
if (atLeastOneInterface) EmptyIntersectionTypeKind.FINAL_CLASS_AND_INTERFACE
|
|
||||||
else EmptyIntersectionTypeKind.SINGLE_FINAL_CLASS,
|
|
||||||
firstType, secondType
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
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
|
return possibleEmptyIntersectionKind
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun SimpleTypeMarker.isSubtypeOfIgnoringArguments(
|
||||||
|
typeCheckerState: TypeCheckerState,
|
||||||
|
otherConstructorMarker: TypeConstructorMarker
|
||||||
|
): Boolean = AbstractTypeChecker.findCorrespondingSupertypes(
|
||||||
|
typeCheckerState, this, otherConstructorMarker
|
||||||
|
).isNotEmpty()
|
||||||
|
|
||||||
private fun TypeSystemInferenceExtensionContext.getIncompatibleSuperTypes(
|
private fun TypeSystemInferenceExtensionContext.getIncompatibleSuperTypes(
|
||||||
firstType: KotlinTypeMarker, secondType: KotlinTypeMarker
|
firstType: KotlinTypeMarker, secondType: KotlinTypeMarker
|
||||||
): Array<KotlinTypeMarker>? {
|
): Array<KotlinTypeMarker>? {
|
||||||
|
|||||||
@@ -9,8 +9,7 @@ enum class EmptyIntersectionTypeKind(val description: String) {
|
|||||||
MULTIPLE_CLASSES("multiple incompatible classes"),
|
MULTIPLE_CLASSES("multiple incompatible classes"),
|
||||||
INCOMPATIBLE_SUPERTYPES("incompatible supertypes"),
|
INCOMPATIBLE_SUPERTYPES("incompatible supertypes"),
|
||||||
INCOMPATIBLE_TYPE_ARGUMENTS("incompatible type arguments"),
|
INCOMPATIBLE_TYPE_ARGUMENTS("incompatible type arguments"),
|
||||||
FINAL_CLASS_AND_INTERFACE("final class and interface"),
|
FINAL_CLASS_AND_INTERFACE("final class and interface")
|
||||||
SINGLE_FINAL_CLASS("final class and non-final class")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun EmptyIntersectionTypeKind.isDefinitelyEmpty(): Boolean =
|
fun EmptyIntersectionTypeKind.isDefinitelyEmpty(): Boolean =
|
||||||
@@ -18,5 +17,4 @@ fun EmptyIntersectionTypeKind.isDefinitelyEmpty(): Boolean =
|
|||||||
|| this == EmptyIntersectionTypeKind.INCOMPATIBLE_SUPERTYPES
|
|| this == EmptyIntersectionTypeKind.INCOMPATIBLE_SUPERTYPES
|
||||||
|| this == EmptyIntersectionTypeKind.INCOMPATIBLE_TYPE_ARGUMENTS
|
|| this == EmptyIntersectionTypeKind.INCOMPATIBLE_TYPE_ARGUMENTS
|
||||||
|
|
||||||
fun EmptyIntersectionTypeKind.isPossiblyEmpty(): Boolean =
|
fun EmptyIntersectionTypeKind.isPossiblyEmpty(): Boolean = this == EmptyIntersectionTypeKind.FINAL_CLASS_AND_INTERFACE
|
||||||
this == EmptyIntersectionTypeKind.SINGLE_FINAL_CLASS || this == EmptyIntersectionTypeKind.FINAL_CLASS_AND_INTERFACE
|
|
||||||
|
|||||||
Reference in New Issue
Block a user