[NI] Implement New CommonSuperTypeCalculation

This commit is contained in:
Stanislav Erokhin
2017-04-13 22:22:54 +03:00
parent 6aac67aa7e
commit ff8a57dc26
6 changed files with 206 additions and 19 deletions
@@ -23,6 +23,9 @@ import kotlin.collections.HashSet
fun intersectWrappedTypes(types: Collection<KotlinType>) = intersectTypes(types.map { it.unwrap() })
fun intersectTypes(types: List<SimpleType>) = intersectTypes(types as List<UnwrappedType>) as SimpleType
fun intersectTypes(types: List<UnwrappedType>): UnwrappedType {
when (types.size) {
0 -> error("Expected some types")
@@ -45,7 +48,7 @@ fun intersectTypes(types: List<UnwrappedType>): UnwrappedType {
}
if (!hasFlexibleTypes) {
return intersectTypes(lowerBounds)
return TypeIntersector.intersectTypes(lowerBounds)
}
val upperBounds = types.map { it.upperIfFlexible() }
@@ -56,14 +59,9 @@ fun intersectTypes(types: List<UnwrappedType>): UnwrappedType {
*
* Note: when we construct intersection type of dynamic(or Raw type) & other type, we can get non-dynamic type. // todo discuss
*/
return KotlinTypeFactory.flexibleType(intersectTypes(lowerBounds), intersectTypes(upperBounds))
return KotlinTypeFactory.flexibleType(TypeIntersector.intersectTypes(lowerBounds), TypeIntersector.intersectTypes(upperBounds))
}
// types.size >= 2
// It is incorrect see to nullability here, because of KT-12684
private fun intersectTypes(types: List<SimpleType>): SimpleType {
return TypeIntersector.intersectTypes(types)
}
object TypeIntersector {
@@ -40,7 +40,7 @@ fun prepareArgumentTypeRegardingCaptureTypes(argumentType: UnwrappedType): Unwra
}
if (simpleType is NewCapturedType) {
// todo may be we should respect flexible capture types also...
return simpleType.constructor.supertypes.takeIf { it.isNotEmpty() }?.let(::intersectTypes) ?: argumentType.builtIns.nullableAnyType
return simpleType.constructor.supertypes.takeIf { it.isNotEmpty() }?.let{ intersectTypes(it) } ?: argumentType.builtIns.nullableAnyType
}
return captureFromExpression(simpleType)
}
@@ -227,7 +227,8 @@ object NewKotlinTypeChecker : KotlinTypeChecker {
}
// nullability was checked earlier via nullabilityChecker
private fun TypeCheckerContext.findCorrespondingSupertypes(
// should be used only if you really sure that it is correct
fun TypeCheckerContext.findCorrespondingSupertypes(
baseType: SimpleType,
constructor: TypeConstructor
): List<SimpleType> {
@@ -410,6 +411,9 @@ object NullabilityChecker {
fun UnwrappedType.hasSupertypeWithGivenTypeConstructor(typeConstructor: TypeConstructor) =
TypeCheckerContext(false).anySupertype(lowerIfFlexible(), { it.constructor == typeConstructor }, { SupertypesPolicy.LowerIfFlexible })
fun UnwrappedType.anySuperTypeConstructor(predicate: (TypeConstructor) -> Boolean) =
TypeCheckerContext(false).anySupertype(lowerIfFlexible(), { predicate(it.constructor) }, { SupertypesPolicy.LowerIfFlexible })
/**
* ClassType means that type constructor for this type is type for real class or interface
*/