[FIR] Add implementation of intersection types to Fir type system

This commit is contained in:
Dmitriy Novozhilov
2019-07-29 09:59:33 +03:00
parent 1708a34eb8
commit 637fb55a7b
17 changed files with 350 additions and 26 deletions
@@ -173,4 +173,53 @@ class ConeDefinitelyNotNullType(val original: ConeKotlinType): ConeKotlinType(),
get() = original.typeArguments
override val nullability: ConeNullability
get() = ConeNullability.NOT_NULL
}
/*
* Contract of the intersection type: it is flat. It means that
* intersection type can not contains another intersection types
* inside it. To keep this contract construct new intersection types
* only via ConeTypeIntersector
*/
class ConeIntersectionType(
val constructor: ConeIntersectionTypeConstructor
) : ConeKotlinType(), SimpleTypeMarker {
override val typeArguments: Array<out ConeKotlinTypeProjection>
get() = emptyArray()
override val nullability: ConeNullability
get() = ConeNullability.NOT_NULL
val intersectedTypes: Collection<ConeKotlinType> get() = constructor.intersectedTypes
val statusMap: Map<ConeKotlinType, ConeIntersectionTypeConstructor.IntersectionStatus> get() = constructor.statusMap
}
class ConeIntersectionTypeConstructor(
val intersectedTypes: Collection<ConeKotlinType>,
val statusMap: Map<ConeKotlinType, IntersectionStatus>
) : TypeConstructorMarker {
val supertypes: Collection<ConeKotlinType> get() = intersectedTypes
/*
* IMPORTANT: use this method only for types from intersectedTypes
*/
fun getStatus(type: ConeKotlinType): IntersectionStatus {
return statusMap[type] ?: error("")
}
enum class IntersectionStatus {
FROM_INFERENCE,
FROM_SMARTCAST
}
}
fun ConeIntersectionTypeConstructor.mapTypes(func: (ConeKotlinType) -> ConeKotlinType): ConeIntersectionTypeConstructor {
val newStatusMap = mutableMapOf<ConeKotlinType, ConeIntersectionTypeConstructor.IntersectionStatus>()
val newTypes = intersectedTypes.map { type ->
val newType = func(type)
// TODO: what if some types squash? What status should we choose?
newStatusMap[newType] = getStatus(type)
newType
}
return ConeIntersectionTypeConstructor(newTypes, newStatusMap)
}
@@ -39,5 +39,12 @@ fun ConeKotlinType.render(): String {
append(">")
}
}
is ConeIntersectionType -> {
intersectedTypes.joinToString(
separator = " & ",
prefix = "it(",
postfix = ")"
)
}
} + nullabilitySuffix
}