From 0c74eef50041ce6924185691c7d0839160a9e57c Mon Sep 17 00:00:00 2001 From: Roman Artemev Date: Fri, 12 Apr 2019 17:35:34 +0300 Subject: [PATCH] Implement IrType context --- .../kotlin/ir/types/IrTypeSubstitutor.kt | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSubstitutor.kt diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSubstitutor.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSubstitutor.kt new file mode 100644 index 00000000000..6cfe36cd32f --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSubstitutor.kt @@ -0,0 +1,63 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.ir.types + +import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns +import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol +import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl +import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection +import org.jetbrains.kotlin.ir.types.impl.originalKotlinType +import org.jetbrains.kotlin.types.Variance + + +class IrTypeSubstitutor( + typeParameters: List, + typeArguments: List, + private val irBuiltIns: IrBuiltIns +) { + private val substitution = typeParameters.zip(typeArguments).toMap() + + fun substitute(type: IrType) = if (substitution.isNotEmpty()) doSubstituteType(type) else type + + private fun doSubstituteTypeArgument(typeArgument: IrTypeArgument): IrTypeArgument { + if (typeArgument is IrStarProjection) return typeArgument + + require(typeArgument is IrTypeProjection) + + return if (typeArgument is IrSimpleType) { + val classifier = typeArgument.classifier + if (classifier is IrTypeParameterSymbol) substitution.getValue(classifier) + else { + makeTypeProjection(doSubstituteType(typeArgument), Variance.INVARIANT) + } + } else makeTypeProjection(doSubstituteType(typeArgument.type), typeArgument.variance) + } + + private fun doSubstituteType(type: IrType): IrType = when (type) { + is IrErrorType -> type + is IrDynamicType -> type + is IrSimpleType -> { + val classifier = type.classifier + if (classifier is IrTypeParameterSymbol) { + val argument = substitution.getValue(classifier) + if (argument is IrTypeProjection) { + argument.type + } else irBuiltIns.anyNType // StarProjection + } else { + type.run { + IrSimpleTypeImpl( + originalKotlinType, + classifier, + hasQuestionMark, + arguments.map { doSubstituteTypeArgument(it) }, + annotations + ) + } + } + } + else -> error("Unknown type") + } +}