From bf2ab99b6147a38a267067bdcbf7f16bb2c2389f Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Thu, 11 Apr 2019 17:16:20 +0300 Subject: [PATCH] IR: IrSimpleTypeBuilder --- .../inline/DeepCopyIrTreeWithDescriptors.kt | 37 ++++------ .../kotlin/ir/types/impl/IrSimpleTypeImpl.kt | 74 ++++++++++++------- .../org/jetbrains/kotlin/ir/types/irTypes.kt | 46 ++++-------- .../kotlin/ir/util/TypeTranslator.kt | 45 +++++------ 4 files changed, 97 insertions(+), 105 deletions(-) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/DeepCopyIrTreeWithDescriptors.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/DeepCopyIrTreeWithDescriptors.kt index 019baabfe6e..fb7545efc42 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/DeepCopyIrTreeWithDescriptors.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/DeepCopyIrTreeWithDescriptors.kt @@ -12,8 +12,9 @@ import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.types.* -import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl +import org.jetbrains.kotlin.ir.types.impl.buildSimpleType import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection +import org.jetbrains.kotlin.ir.types.impl.toBuilder import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid @@ -153,27 +154,22 @@ internal class DeepCopyIrTreeWithSymbolsForInliner(val context: Context, val substitutedType = typeArguments?.get(type.classifier) if (substitutedType != null) { substitutedType as IrSimpleType - return IrSimpleTypeImpl( - kotlinType = null, - classifier = substitutedType.classifier, - hasQuestionMark = type.hasQuestionMark or substitutedType.isMarkedNullable(), - arguments = substitutedType.arguments, - annotations = substitutedType.annotations - ) + return substitutedType.buildSimpleType { + kotlinType = null + hasQuestionMark = type.hasQuestionMark or substitutedType.isMarkedNullable() + } } - return IrSimpleTypeImpl( - kotlinType = null, - classifier = symbolRemapper.getReferencedClassifier(type.classifier), - hasQuestionMark = type.hasQuestionMark, - arguments = remapTypeArguments(type.arguments), - annotations = type.annotations.map { it.transform(copier, null) as IrCall } - ) + return type.buildSimpleType { + kotlinType = null + classifier = symbolRemapper.getReferencedClassifier(type.classifier) + arguments = remapTypeArguments(type.arguments) + annotations = type.annotations.map { it.transform(copier, null) as IrCall } + } } } - private class SymbolRemapperImpl(descriptorsRemapper: DescriptorsRemapper) - : DeepCopySymbolRemapper(descriptorsRemapper) { + private class SymbolRemapperImpl(descriptorsRemapper: DescriptorsRemapper) : DeepCopySymbolRemapper(descriptorsRemapper) { var typeArguments: Map? = null set(value) { @@ -192,9 +188,6 @@ internal class DeepCopyIrTreeWithSymbolsForInliner(val context: Context, } private val symbolRemapper = SymbolRemapperImpl(DescriptorsToIrRemapper()) - private val copier = DeepCopyIrTreeWithSymbols( - symbolRemapper, - InlinerTypeRemapper(symbolRemapper, typeArguments), - InlinerSymbolRenamer() - ) + private val copier = + DeepCopyIrTreeWithSymbols(symbolRemapper, InlinerTypeRemapper(symbolRemapper, typeArguments), InlinerSymbolRenamer()) } \ No newline at end of file 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 896957c71dc..288678cc03b 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 @@ -11,53 +11,73 @@ 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(kotlinType, annotations, variance), IrSimpleType, IrTypeProjection { + annotations: List +) : IrTypeBase(kotlinType, annotations, Variance.INVARIANT), IrSimpleType, IrTypeProjection { constructor( classifier: IrClassifierSymbol, hasQuestionMark: Boolean, arguments: List, annotations: List - ) : 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.safeAs()?.kotlinType, - other.classifier, other.hasQuestionMark, other.arguments, other.annotations, variance - ) + ) : this(null, classifier, hasQuestionMark, arguments, annotations) override fun equals(other: Any?): Boolean = other is IrSimpleTypeImpl && FqNameEqualityChecker.areEqual(classifier, other.classifier) && hasQuestionMark == other.hasQuestionMark && - arguments == other.arguments && - variance == other.variance + arguments == other.arguments override fun hashCode(): Int = - ((FqNameEqualityChecker.getHashCode(classifier) * 31 + hasQuestionMark.hashCode()) * 31 + - arguments.hashCode()) * 31 + variance.hashCode() + (FqNameEqualityChecker.getHashCode(classifier) * 31 + + hasQuestionMark.hashCode()) * 31 + + arguments.hashCode() } +class IrSimpleTypeBuilder { + var kotlinType: KotlinType? = null + var classifier: IrClassifierSymbol? = null + var hasQuestionMark = false + var arguments: List = emptyList() + var annotations: List = emptyList() + var variance = Variance.INVARIANT +} + +fun IrSimpleType.toBuilder() = + IrSimpleTypeBuilder().also { b -> + b.kotlinType = originalKotlinType + b.classifier = classifier + b.hasQuestionMark = hasQuestionMark + b.arguments = arguments + b.annotations = annotations + } + +fun IrSimpleTypeBuilder.buildSimpleType() = + IrSimpleTypeImpl( + kotlinType, + classifier ?: throw AssertionError("Classifier not provided"), + hasQuestionMark, + arguments, + annotations + ) + +fun IrSimpleTypeBuilder.buildTypeProjection() = + if (variance == Variance.INVARIANT) + buildSimpleType() + else + IrTypeProjectionImpl(buildSimpleType(), variance) + +inline fun IrSimpleType.buildSimpleType(b: IrSimpleTypeBuilder.() -> Unit): IrSimpleType = + toBuilder().apply(b).buildSimpleType() + +inline fun IrSimpleType.buildTypeProjection(b: IrSimpleTypeBuilder.() -> Unit): IrTypeProjection = + toBuilder().apply(b).buildTypeProjection() + class IrTypeProjectionImpl internal constructor( override val type: IrType, override val variance: Variance @@ -72,7 +92,7 @@ class IrTypeProjectionImpl internal constructor( fun makeTypeProjection(type: IrType, variance: Variance): IrTypeProjection = when { type is IrTypeProjection && type.variance == variance -> type - type is IrSimpleType -> IrSimpleTypeImpl(type, variance) + type is IrSimpleType -> type.toBuilder().apply { this.variance = variance }.buildTypeProjection() type is IrDynamicType -> IrDynamicTypeImpl(null, type.annotations, variance) type is IrErrorType -> IrErrorTypeImpl(null, type.annotations, variance) else -> IrTypeProjectionImpl(type, variance) 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 9bf5a692179..52f66779819 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 @@ -6,35 +6,29 @@ package org.jetbrains.kotlin.ir.types import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.ClassifierDescriptor -import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrTypeParameter import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol -import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl -import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl import org.jetbrains.kotlin.ir.types.impl.* -import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.typeUtil.makeNotNullable import org.jetbrains.kotlin.types.typeUtil.makeNullable import org.jetbrains.kotlin.utils.addToStdlib.cast import org.jetbrains.kotlin.utils.addToStdlib.safeAs -fun IrType.withHasQuestionMark(hasQuestionMark: Boolean): IrType = +fun IrType.withHasQuestionMark(newHasQuestionMark: Boolean): IrType = when (this) { is IrSimpleType -> - if (this.hasQuestionMark == hasQuestionMark) + if (this.hasQuestionMark == newHasQuestionMark) this else - IrSimpleTypeImpl( - originalKotlinType?.run { if (hasQuestionMark) makeNullable() else makeNotNullable() }, - classifier, - hasQuestionMark, - arguments, - annotations - ) + buildSimpleType { + hasQuestionMark = newHasQuestionMark + kotlinType = originalKotlinType?.run { + if (newHasQuestionMark) makeNullable() else makeNotNullable() + } + } else -> this } @@ -49,27 +43,19 @@ val IrType.classOrNull: IrClassSymbol? fun IrType.makeNotNull() = if (this is IrSimpleType && this.hasQuestionMark) { - IrSimpleTypeImpl( - originalKotlinType?.makeNotNullable(), - classifier, - false, - arguments, - annotations, - Variance.INVARIANT - ) + buildSimpleType { + kotlinType = originalKotlinType?.makeNotNullable() + hasQuestionMark = false + } } else this fun IrType.makeNullable() = if (this is IrSimpleType && !this.hasQuestionMark) - IrSimpleTypeImpl( - originalKotlinType?.makeNullable(), - classifier, - true, - arguments, - annotations, - Variance.INVARIANT - ) + buildSimpleType { + kotlinType = originalKotlinType?.makeNullable() + hasQuestionMark = true + } else this 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 dae9111cd60..85a4271e0ae 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 @@ -15,10 +15,7 @@ import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrTypeProjection -import org.jetbrains.kotlin.ir.types.impl.IrDynamicTypeImpl -import org.jetbrains.kotlin.ir.types.impl.IrErrorTypeImpl -import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl -import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl +import org.jetbrains.kotlin.ir.types.impl.* import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.typeUtil.replaceArgumentsWithStarProjections import org.jetbrains.kotlin.types.typesApproximation.approximateCapturedTypes @@ -78,30 +75,26 @@ class TypeTranslator( val ktTypeDescriptor = ktTypeConstructor.declarationDescriptor ?: throw AssertionError("No descriptor for type $approximatedType") - return when (ktTypeDescriptor) { - is TypeParameterDescriptor -> - IrSimpleTypeImpl( - approximatedType, - resolveTypeParameter(ktTypeDescriptor), - approximatedType.isMarkedNullable, - emptyList(), - translateTypeAnnotations(approximatedType.annotations), - variance - ) + return IrSimpleTypeBuilder().apply { + kotlinType = approximatedType + hasQuestionMark = approximatedType.isMarkedNullable + this.variance = variance + when (ktTypeDescriptor) { + is TypeParameterDescriptor -> { + classifier = resolveTypeParameter(ktTypeDescriptor) + annotations = translateTypeAnnotations(approximatedType.annotations) + } - is ClassDescriptor -> - IrSimpleTypeImpl( - approximatedType, - symbolTable.referenceClass(ktTypeDescriptor), - approximatedType.isMarkedNullable, - translateTypeArguments(approximatedType.arguments), - translateTypeAnnotations(approximatedType.annotations), - variance - ) + is ClassDescriptor -> { + classifier = symbolTable.referenceClass(ktTypeDescriptor) + arguments = translateTypeArguments(approximatedType.arguments) + annotations = translateTypeAnnotations(approximatedType.annotations) + } - else -> - throw AssertionError("Unexpected type descriptor $ktTypeDescriptor :: ${ktTypeDescriptor::class}") - } + else -> + throw AssertionError("Unexpected type descriptor $ktTypeDescriptor :: ${ktTypeDescriptor::class}") + } + }.buildTypeProjection() } private inner class LegacyTypeApproximation {