From 4ed93d3dee25f6f81411980e7ec3984b3955f00a Mon Sep 17 00:00:00 2001 From: Roman Artemev Date: Fri, 5 Feb 2021 17:19:55 +0300 Subject: [PATCH] [IR] Add IrCapturedType into IR type system - support it in TypeSystemContext --- .../kotlin/ir/types/IrTypeSystemContext.kt | 38 ++++++++------ .../kotlin/ir/types/impl/IrSimpleTypeImpl.kt | 1 + .../kotlin/ir/types/impl/IrTypeBase.kt | 52 ++++++++++++++++++- 3 files changed, 75 insertions(+), 16 deletions(-) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt index 2b89a9ab30e..a832de72003 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt @@ -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 { 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 diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrSimpleTypeImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrSimpleTypeImpl.kt index daecddcd6fd..dac83e8297e 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrSimpleTypeImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrSimpleTypeImpl.kt @@ -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) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrTypeBase.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrTypeBase.kt index 7bbc6f0859d..edc84085d34 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrTypeBase.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrTypeBase.kt @@ -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 = emptyList() + + val superTypes: List get() = _superTypes + + fun initSuperTypes(superTypes: List) { + _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 get() = emptyList() + override val abbreviation: IrTypeAbbreviation? get () = null + override val hasQuestionMark: Boolean get() = false + override val annotations: List 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() + } +} \ No newline at end of file