[IR] Add IrCapturedType into IR type system

- support it in TypeSystemContext
This commit is contained in:
Roman Artemev
2021-02-05 17:19:55 +03:00
parent 9b6f95faa2
commit 4ed93d3dee
3 changed files with 75 additions and 16 deletions
@@ -5,12 +5,11 @@
package org.jetbrains.kotlin.ir.types
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
@@ -71,7 +70,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
}
}
override fun SimpleTypeMarker.asCapturedType(): CapturedTypeMarker? = null
override fun SimpleTypeMarker.asCapturedType(): CapturedTypeMarker? = this as? IrCapturedType
override fun SimpleTypeMarker.asDefinitelyNotNullType(): DefinitelyNotNullTypeMarker? = null
@@ -83,19 +82,24 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
else simpleType.run { IrSimpleTypeImpl(classifier, nullable, arguments, annotations) }
}
override fun SimpleTypeMarker.typeConstructor() = (this as IrSimpleType).classifier
override fun SimpleTypeMarker.typeConstructor(): TypeConstructorMarker = when (this) {
is IrCapturedType -> constructor
is IrSimpleType -> classifier
else -> error("Unknown type constructor")
}
override fun CapturedTypeMarker.typeConstructor(): CapturedTypeConstructorMarker =
error("Captured types should be used for IrTypes")
(this as IrCapturedType).constructor
override fun CapturedTypeMarker.isProjectionNotNull(): Boolean =
error("Captured types should be used for IrTypes")
// Note: `isProjectionNotNull` is used inside inference along with intersection types.
// IrTypes are not used in type inference and do not have intersection type so implemenation is default (false)
override fun CapturedTypeMarker.isProjectionNotNull(): Boolean = false
override fun CapturedTypeMarker.captureStatus(): CaptureStatus =
error("Captured types should be used for IrTypes")
(this as IrCapturedType).captureStatus
override fun CapturedTypeConstructorMarker.projection(): TypeArgumentMarker =
error("Captured types should be used for IrTypes")
(this as IrCapturedType.Constructor).argument
override fun KotlinTypeMarker.argumentsCount(): Int =
when (this) {
@@ -116,7 +120,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
override fun KotlinTypeMarker.asTypeArgument() = this as IrTypeArgument
override fun CapturedTypeMarker.lowerType(): KotlinTypeMarker? = error("Captured Type is not valid for IrTypes")
override fun CapturedTypeMarker.lowerType(): KotlinTypeMarker? = (this as IrCapturedType).lowerType
override fun TypeArgumentMarker.isStarProjection() = this is IrStarProjection
@@ -139,6 +143,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
override fun TypeConstructorMarker.supertypes(): Collection<KotlinTypeMarker> {
return when (this) {
is IrCapturedType.Constructor -> superTypes
is IrClassSymbol -> owner.superTypes
is IrTypeParameterSymbol -> owner.superTypes
else -> error("unsupported type constructor")
@@ -159,11 +164,12 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
override fun TypeParameterMarker.getTypeConstructor() = this as IrTypeParameterSymbol
override fun areEqualTypeConstructors(c1: TypeConstructorMarker, c2: TypeConstructorMarker) = FqNameEqualityChecker.areEqual(
c1 as IrClassifierSymbol, c2 as IrClassifierSymbol
)
override fun areEqualTypeConstructors(c1: TypeConstructorMarker, c2: TypeConstructorMarker): Boolean =
if (c1 is IrClassifierSymbol && c2 is IrClassifierSymbol) {
FqNameEqualityChecker.areEqual(c1 , c2)
} else c1 === c2
override fun TypeConstructorMarker.isDenotable() = true
override fun TypeConstructorMarker.isDenotable() = this !is IrCapturedType.Constructor
override fun TypeConstructorMarker.isCommonFinalClassConstructor(): Boolean {
val classSymbol = this as? IrClassSymbol ?: return false
@@ -185,6 +191,8 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
// TODO: is that correct?
require(type is IrSimpleType)
if (type is IrCapturedType) return null
val classifier = type.classifier as? IrClassSymbol ?: return null
val typeArguments = type.arguments
@@ -95,6 +95,7 @@ class IrTypeProjectionImpl internal constructor(
fun makeTypeProjection(type: IrType, variance: Variance): IrTypeProjection =
when {
type is IrCapturedType -> IrTypeProjectionImpl(type, variance)
type is IrTypeProjection && type.variance == variance -> type
type is IrSimpleType -> type.toBuilder().apply { this.variance = variance }.buildTypeProjection()
type is IrDynamicType -> IrDynamicTypeImpl(null, type.annotations, variance)
@@ -6,11 +6,15 @@
package org.jetbrains.kotlin.ir.types.impl
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.model.CaptureStatus
import org.jetbrains.kotlin.types.model.CapturedTypeConstructorMarker
import org.jetbrains.kotlin.types.model.CapturedTypeMarker
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
abstract class IrTypeBase(val kotlinType: KotlinType?) : IrType, IrTypeProjection {
@@ -69,3 +73,49 @@ object IrUninitializedType : IrType {
class ReturnTypeIsNotInitializedException(function: IrFunction) : IllegalStateException(
"Return type is not initialized for function '${function.name}'"
)
// Please note this type is not denotable which means it could only exist inside type system
class IrCapturedType(
val captureStatus: CaptureStatus,
val lowerType: IrType?,
projection: IrTypeArgument,
typeParameter: IrTypeParameter
) : IrSimpleType, CapturedTypeMarker {
class Constructor(val argument: IrTypeArgument, val typeParameter: IrTypeParameter) :
CapturedTypeConstructorMarker {
private var _superTypes: List<IrType> = emptyList()
val superTypes: List<IrType> get() = _superTypes
fun initSuperTypes(superTypes: List<IrType>) {
_superTypes = superTypes
}
}
val constructor: Constructor = Constructor(projection, typeParameter)
override val classifier: IrClassifierSymbol get() = error("Captured Type does not have a classifier")
override val arguments: List<IrTypeArgument> get() = emptyList()
override val abbreviation: IrTypeAbbreviation? get () = null
override val hasQuestionMark: Boolean get() = false
override val annotations: List<IrConstructorCall> get() = emptyList()
override fun equals(other: Any?): Boolean {
return other is IrCapturedType
&& captureStatus == other.captureStatus
&& lowerType == other.lowerType
&& constructor.argument == other.constructor.argument
&& constructor.typeParameter == other.constructor.typeParameter
&& constructor.superTypes == other.constructor.superTypes
}
override fun hashCode(): Int {
return (((captureStatus.hashCode() * 31
+ (lowerType?.hashCode() ?: 0)) * 31
+ constructor.argument.hashCode()) * 31
+ constructor.typeParameter.hashCode()) + constructor.superTypes.hashCode()
}
}