[FIR] Add implementation of intersection types to Fir type system
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user