From e8fe788df6754e109fcad1491e24e285c857ff5f Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Tue, 15 May 2018 10:21:14 +0300 Subject: [PATCH] IrTypes: Implicit casts, take 1 Keep KotlinType along with IrTypes created by psi2ir. --- .../transformations/InsertImplicitCasts.kt | 55 ++++++++++--------- .../kotlin/ir/types/impl/IrSimpleTypeImpl.kt | 25 +++++++-- .../kotlin/ir/types/impl/IrTypeBase.kt | 13 ++++- .../org/jetbrains/kotlin/ir/types/irTypes.kt | 5 +- .../kotlin/ir/util/TypeTranslator.kt | 6 +- 5 files changed, 67 insertions(+), 37 deletions(-) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt index 9dd5302a151..924a383429e 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt @@ -17,18 +17,18 @@ package org.jetbrains.kotlin.psi2ir.transformations import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.descriptors.ClassifierDescriptor -import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl -import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol -import org.jetbrains.kotlin.ir.util.ScopedTypeParametersResolver -import org.jetbrains.kotlin.ir.util.SymbolTable +import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.ir.types.classifierOrFail +import org.jetbrains.kotlin.ir.types.impl.originalKotlinType +import org.jetbrains.kotlin.ir.util.TypeTranslator import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.psi2ir.containsNull +import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.isError @@ -37,27 +37,26 @@ import org.jetbrains.kotlin.types.typeUtil.makeNotNullable import org.jetbrains.kotlin.types.typeUtil.makeNullable import org.jetbrains.kotlin.types.upperIfFlexible -fun insertImplicitCasts(builtIns: KotlinBuiltIns, element: IrElement, symbolTable: SymbolTable) { - element.transformChildren(InsertImplicitCasts(builtIns, symbolTable), null) +fun insertImplicitCasts(element: IrElement, context: GeneratorContext) { + element.transformChildren(InsertImplicitCasts(context), null) } -class InsertImplicitCasts(private val builtIns: KotlinBuiltIns, private val symbolTable: SymbolTable) : IrElementTransformerVoid() { +class InsertImplicitCasts(context: GeneratorContext) : IrElementTransformerVoid() { - private val typeParameterResolver = ScopedTypeParametersResolver() + private val builtIns = context.builtIns + private val irBuiltIns = context.irBuiltIns + private val symbolTable = context.symbolTable + + private val typeTranslator = TypeTranslator(context.moduleDescriptor, symbolTable) + private fun KotlinType.toIrType() = typeTranslator.translateType(this) private inline fun runInTypeParameterScope(typeParametersContainer: IrTypeParametersContainer, fn: () -> T): T { - typeParameterResolver.enterTypeParameterScope(typeParametersContainer) + typeTranslator.enterScope(typeParametersContainer) val result = fn() - typeParameterResolver.leaveTypeParameterScope() + typeTranslator.leaveScope() return result } - private fun resolveScopedTypeParameter(classifier: ClassifierDescriptor): IrTypeParameterSymbol? = - if (classifier is TypeParameterDescriptor) - typeParameterResolver.resolveScopedTypeParameter(classifier) - else - null - override fun visitCallableReference(expression: IrCallableReference): IrExpression = expression.transformPostfix { transformReceiverArguments() @@ -188,13 +187,16 @@ class InsertImplicitCasts(private val builtIns: KotlinBuiltIns, private val symb expression = expression.cast(expectedType) } + private fun IrExpression.cast(irType: IrType): IrExpression = + cast(irType.originalKotlinType) + private fun IrExpression.cast(expectedType: KotlinType?): IrExpression { if (expectedType == null) return this if (expectedType.isError) return this val notNullableExpectedType = expectedType.makeNotNullable() - val valueType = this.type + val valueType = this.type.originalKotlinType!! return when { KotlinBuiltIns.isUnit(expectedType) -> @@ -225,29 +227,28 @@ class InsertImplicitCasts(private val builtIns: KotlinBuiltIns, private val symb targetType: KotlinType, typeOperator: IrTypeOperator ): IrExpression { - val typeDescriptor = targetType.constructor.declarationDescriptor - ?: throw AssertionError("No declaration for target type: $targetType") - + val irType = targetType.toIrType() return IrTypeOperatorCallImpl( startOffset, endOffset, - targetType, + irType, typeOperator, - targetType, - resolveScopedTypeParameter(typeDescriptor) ?: symbolTable.referenceClassifier(typeDescriptor), + irType, irType.classifierOrFail, this ) } private fun IrExpression.coerceToUnit(): IrExpression { - val valueType = this.type + val valueType = this.type.originalKotlinType!! return if (KotlinTypeChecker.DEFAULT.isSubtypeOf(valueType, builtIns.unitType)) this else IrTypeOperatorCallImpl( - startOffset, endOffset, builtIns.unitType, - IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, builtIns.unitType, symbolTable.referenceClass(builtIns.unit), + startOffset, endOffset, + irBuiltIns.unitType, + IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, + irBuiltIns.unitType, irBuiltIns.unitType.classifierOrFail, this ) } 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 44fc9bf9f3a..18584d3e484 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 @@ -8,27 +8,42 @@ package org.jetbrains.kotlin.ir.types.impl import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol import org.jetbrains.kotlin.ir.types.* +import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.Variance +import org.jetbrains.kotlin.utils.addToStdlib.safeAs class IrSimpleTypeImpl( + kotlinType: KotlinType?, override val classifier: IrClassifierSymbol, override val hasQuestionMark: Boolean, override val arguments: List, annotations: List, variance: Variance -) : IrTypeBase(annotations, variance), IrSimpleType, IrTypeProjection { +) : IrTypeBase(kotlinType, annotations, variance), IrSimpleType, IrTypeProjection { constructor( classifier: IrClassifierSymbol, hasQuestionMark: Boolean, arguments: List, annotations: List - ) : this(classifier, hasQuestionMark, arguments, annotations, Variance.INVARIANT) + ) : this(null, classifier, hasQuestionMark, arguments, annotations, Variance.INVARIANT) + + constructor( + kotlinType: KotlinType?, + classifier: IrClassifierSymbol, + hasQuestionMark: Boolean, + arguments: List, + annotations: List + ) : this(kotlinType, classifier, hasQuestionMark, arguments, annotations, Variance.INVARIANT) constructor( other: IrSimpleType, variance: Variance - ) : this(other.classifier, other.hasQuestionMark, other.arguments, other.annotations, variance) + ) : + this( + other.safeAs()?.kotlinType, + other.classifier, other.hasQuestionMark, other.arguments, other.annotations, variance + ) } @@ -41,7 +56,7 @@ fun makeTypeProjection(type: IrType, variance: Variance): IrTypeProjection = when { type is IrTypeProjection && type.variance == variance -> type type is IrSimpleType -> IrSimpleTypeImpl(type, variance) - type is IrDynamicType -> IrDynamicTypeImpl(type.annotations, variance) - type is IrErrorType -> IrErrorTypeImpl(type.annotations, variance) + type is IrDynamicType -> IrDynamicTypeImpl(type.originalKotlinType, type.annotations, variance) + type is IrErrorType -> IrErrorTypeImpl(type.originalKotlinType, type.annotations, variance) else -> IrTypeProjectionImpl(type, variance) } \ No newline at end of file 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 d09d7c6192c..b2bfeca85ad 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 @@ -10,9 +10,12 @@ import org.jetbrains.kotlin.ir.types.IrDynamicType import org.jetbrains.kotlin.ir.types.IrErrorType import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrTypeProjection +import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.Variance +import org.jetbrains.kotlin.utils.addToStdlib.safeAs abstract class IrTypeBase( + val kotlinType: KotlinType?, override val annotations: List, override val variance: Variance ) : IrType, IrTypeProjection { @@ -22,11 +25,17 @@ abstract class IrTypeBase( } class IrErrorTypeImpl( + kotlinType: KotlinType?, annotations: List, variance: Variance -) : IrTypeBase(annotations, variance), IrErrorType +) : IrTypeBase(kotlinType, annotations, variance), IrErrorType class IrDynamicTypeImpl( + kotlinType: KotlinType?, annotations: List, variance: Variance -) : IrTypeBase(annotations, variance), IrDynamicType, IrTypeProjection \ No newline at end of file +) : IrTypeBase(kotlinType, annotations, variance), IrDynamicType, IrTypeProjection + + +val IrType.originalKotlinType: KotlinType? + get() = safeAs()?.kotlinType \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt index e8a7d5cdef3..520e3bbf89b 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.types import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl +import org.jetbrains.kotlin.ir.types.impl.originalKotlinType import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.utils.addToStdlib.cast import org.jetbrains.kotlin.utils.addToStdlib.safeAs @@ -17,7 +18,7 @@ fun IrType.withHasQuestionMark(hasQuestionMark: Boolean): IrType = if (this.hasQuestionMark == hasQuestionMark) this else - IrSimpleTypeImpl(classifier, hasQuestionMark, arguments, annotations) + IrSimpleTypeImpl(originalKotlinType, classifier, hasQuestionMark, arguments, annotations) else -> this } @@ -30,6 +31,7 @@ val IrType.classifierOrNull: IrClassifierSymbol? fun IrType.makeNotNull() = if (this is IrSimpleType && this.hasQuestionMark) IrSimpleTypeImpl( + originalKotlinType, classifier, false, arguments, @@ -42,6 +44,7 @@ fun IrType.makeNotNull() = fun IrType.makeNullable() = if (this is IrSimpleType && !this.hasQuestionMark) IrSimpleTypeImpl( + originalKotlinType, classifier, true, arguments, diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/TypeTranslator.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/TypeTranslator.kt index 2622ca60b15..189dfcdc313 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/TypeTranslator.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/TypeTranslator.kt @@ -47,9 +47,9 @@ class TypeTranslator( val ktTypeUpper = approximateCapturedTypes(ktType0).upper when { - ktTypeUpper.isError -> return IrErrorTypeImpl(translateTypeAnnotations(ktTypeUpper.annotations), variance) + ktTypeUpper.isError -> return IrErrorTypeImpl(ktTypeUpper, translateTypeAnnotations(ktTypeUpper.annotations), variance) ktTypeUpper.isFlexible() -> return translateType(ktTypeUpper.upperIfFlexible(), variance) - ktTypeUpper.isDynamic() -> return IrDynamicTypeImpl(translateTypeAnnotations(ktTypeUpper.annotations), variance) + ktTypeUpper.isDynamic() -> return IrDynamicTypeImpl(ktTypeUpper, translateTypeAnnotations(ktTypeUpper.annotations), variance) } val ktTypeConstructor = ktTypeUpper.constructor @@ -58,6 +58,7 @@ class TypeTranslator( return when (ktTypeDescriptor) { is TypeParameterDescriptor -> IrSimpleTypeImpl( + ktTypeUpper, resolveTypeParameter(ktTypeDescriptor), ktTypeUpper.isMarkedNullable, emptyList(), @@ -67,6 +68,7 @@ class TypeTranslator( is ClassDescriptor -> IrSimpleTypeImpl( + ktTypeUpper, symbolTable.referenceClass(ktTypeDescriptor), ktTypeUpper.isMarkedNullable, translateTypeArguments(ktTypeUpper.arguments),