[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 package org.jetbrains.kotlin.ir.types
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.builtins.PrimitiveType import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities 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.IrElement
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns 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 override fun SimpleTypeMarker.asDefinitelyNotNullType(): DefinitelyNotNullTypeMarker? = null
@@ -83,19 +82,24 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
else simpleType.run { IrSimpleTypeImpl(classifier, nullable, arguments, annotations) } 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 = override fun CapturedTypeMarker.typeConstructor(): CapturedTypeConstructorMarker =
error("Captured types should be used for IrTypes") (this as IrCapturedType).constructor
override fun CapturedTypeMarker.isProjectionNotNull(): Boolean = // Note: `isProjectionNotNull` is used inside inference along with intersection types.
error("Captured types should be used for IrTypes") // 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 = override fun CapturedTypeMarker.captureStatus(): CaptureStatus =
error("Captured types should be used for IrTypes") (this as IrCapturedType).captureStatus
override fun CapturedTypeConstructorMarker.projection(): TypeArgumentMarker = override fun CapturedTypeConstructorMarker.projection(): TypeArgumentMarker =
error("Captured types should be used for IrTypes") (this as IrCapturedType.Constructor).argument
override fun KotlinTypeMarker.argumentsCount(): Int = override fun KotlinTypeMarker.argumentsCount(): Int =
when (this) { when (this) {
@@ -116,7 +120,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
override fun KotlinTypeMarker.asTypeArgument() = this as IrTypeArgument 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 override fun TypeArgumentMarker.isStarProjection() = this is IrStarProjection
@@ -139,6 +143,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
override fun TypeConstructorMarker.supertypes(): Collection<KotlinTypeMarker> { override fun TypeConstructorMarker.supertypes(): Collection<KotlinTypeMarker> {
return when (this) { return when (this) {
is IrCapturedType.Constructor -> superTypes
is IrClassSymbol -> owner.superTypes is IrClassSymbol -> owner.superTypes
is IrTypeParameterSymbol -> owner.superTypes is IrTypeParameterSymbol -> owner.superTypes
else -> error("unsupported type constructor") else -> error("unsupported type constructor")
@@ -159,11 +164,12 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
override fun TypeParameterMarker.getTypeConstructor() = this as IrTypeParameterSymbol override fun TypeParameterMarker.getTypeConstructor() = this as IrTypeParameterSymbol
override fun areEqualTypeConstructors(c1: TypeConstructorMarker, c2: TypeConstructorMarker) = FqNameEqualityChecker.areEqual( override fun areEqualTypeConstructors(c1: TypeConstructorMarker, c2: TypeConstructorMarker): Boolean =
c1 as IrClassifierSymbol, c2 as IrClassifierSymbol 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 { override fun TypeConstructorMarker.isCommonFinalClassConstructor(): Boolean {
val classSymbol = this as? IrClassSymbol ?: return false val classSymbol = this as? IrClassSymbol ?: return false
@@ -185,6 +191,8 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
// TODO: is that correct? // TODO: is that correct?
require(type is IrSimpleType) require(type is IrSimpleType)
if (type is IrCapturedType) return null
val classifier = type.classifier as? IrClassSymbol ?: return null val classifier = type.classifier as? IrClassSymbol ?: return null
val typeArguments = type.arguments val typeArguments = type.arguments
@@ -95,6 +95,7 @@ class IrTypeProjectionImpl internal constructor(
fun makeTypeProjection(type: IrType, variance: Variance): IrTypeProjection = fun makeTypeProjection(type: IrType, variance: Variance): IrTypeProjection =
when { when {
type is IrCapturedType -> IrTypeProjectionImpl(type, variance)
type is IrTypeProjection && type.variance == variance -> type type is IrTypeProjection && type.variance == variance -> type
type is IrSimpleType -> type.toBuilder().apply { this.variance = variance }.buildTypeProjection() type is IrSimpleType -> type.toBuilder().apply { this.variance = variance }.buildTypeProjection()
type is IrDynamicType -> IrDynamicTypeImpl(null, type.annotations, variance) type is IrDynamicType -> IrDynamicTypeImpl(null, type.annotations, variance)
@@ -6,11 +6,15 @@
package org.jetbrains.kotlin.ir.types.impl package org.jetbrains.kotlin.ir.types.impl
import org.jetbrains.kotlin.ir.declarations.IrFunction 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.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.Variance 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 import org.jetbrains.kotlin.utils.addToStdlib.safeAs
abstract class IrTypeBase(val kotlinType: KotlinType?) : IrType, IrTypeProjection { abstract class IrTypeBase(val kotlinType: KotlinType?) : IrType, IrTypeProjection {
@@ -69,3 +73,49 @@ object IrUninitializedType : IrType {
class ReturnTypeIsNotInitializedException(function: IrFunction) : IllegalStateException( class ReturnTypeIsNotInitializedException(function: IrFunction) : IllegalStateException(
"Return type is not initialized for function '${function.name}'" "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()
}
}