From a28d0e0b7fbf8ba49bed0442da51a95a97ef29a6 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Tue, 22 Sep 2020 19:08:31 +0300 Subject: [PATCH] Make IrTypeMapper delegate to AbstractTypeMapper --- .../backend/jvm/codegen/IrTypeMapper.kt | 178 ++++++++---------- .../kotlin/types/AbstractTypeMapper.kt | 26 ++- .../types/TypeSystemCommonBackendContext.kt | 4 +- 3 files changed, 103 insertions(+), 105 deletions(-) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrTypeMapper.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrTypeMapper.kt index 0dcbcb265fe..0c633f0ec7a 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrTypeMapper.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrTypeMapper.kt @@ -10,7 +10,6 @@ import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.builtins.functions.BuiltInFunctionArity import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.JvmCodegenUtil -import org.jetbrains.kotlin.codegen.signature.AsmTypeFactory import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.codegen.state.KotlinTypeMapperBase @@ -21,23 +20,27 @@ import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrPackageFragment import org.jetbrains.kotlin.ir.declarations.IrTypeParameter +import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.types.* -import org.jetbrains.kotlin.ir.types.impl.originalKotlinType import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.load.kotlin.TypeMappingMode -import org.jetbrains.kotlin.load.kotlin.mapBuiltInType import org.jetbrains.kotlin.name.SpecialNames -import org.jetbrains.kotlin.resolve.jvm.AsmTypes -import org.jetbrains.kotlin.types.Variance -import org.jetbrains.kotlin.types.computeExpandedTypeForInlineClass +import org.jetbrains.kotlin.types.AbstractTypeMapper +import org.jetbrains.kotlin.types.TypeMappingContext +import org.jetbrains.kotlin.types.TypeSystemCommonBackendContextForTypeMapping +import org.jetbrains.kotlin.types.model.KotlinTypeMarker +import org.jetbrains.kotlin.types.model.SimpleTypeMarker +import org.jetbrains.kotlin.types.model.TypeConstructorMarker +import org.jetbrains.kotlin.types.model.TypeParameterMarker import org.jetbrains.org.objectweb.asm.Type +import org.jetbrains.kotlin.backend.jvm.codegen.isRawType as isRawTypeImpl +import org.jetbrains.kotlin.ir.types.isKClass as isKClassImpl +import org.jetbrains.kotlin.ir.util.isSuspendFunction as isSuspendFunctionImpl -class IrTypeMapper(private val context: JvmBackendContext) : KotlinTypeMapperBase() { +class IrTypeMapper(private val context: JvmBackendContext) : KotlinTypeMapperBase(), TypeMappingContext { internal val typeSystem = IrTypeCheckerContext(context.irBuiltIns) - - private val IrTypeArgument.adjustedType - get() = (this as? IrTypeProjection)?.type ?: context.irBuiltIns.anyNType + override val typeContext: TypeSystemCommonBackendContextForTypeMapping = IrTypeCheckerContextForTypeMapping(typeSystem, context) override fun mapClass(classifier: ClassifierDescriptor): Type = when (classifier) { @@ -49,7 +52,10 @@ class IrTypeMapper(private val context: JvmBackendContext) : KotlinTypeMapperBas error("Unknown descriptor: $classifier") } - fun classInternalName(irClass: IrClass): String { + fun classInternalName(irClass: IrClass): String = getClassInternalName(irClass.symbol) + + override fun getClassInternalName(typeConstructor: TypeConstructorMarker): String { + val irClass = (typeConstructor as IrClassSymbol).owner fun report(): Nothing { error( "Local class should have its name computed in InventNamesForLocalClasses: ${irClass.fqNameWhenAvailable}\n" + @@ -71,12 +77,12 @@ class IrTypeMapper(private val context: JvmBackendContext) : KotlinTypeMapperBas prefix + className } is IrClass -> { - classInternalName(parent) + "$" + className + getClassInternalName(parent.symbol) + "$" + className } is IrFunction -> { if (parent.isSuspend && parent.parentAsClass.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS) { val interfaceClass = parent.parentAsClass.parent as IrClass - classInternalName(interfaceClass) + "$" + parent.name.asString() + getClassInternalName(interfaceClass.symbol) + "$" + parent.name.asString() } else report() } else -> report() @@ -100,7 +106,7 @@ class IrTypeMapper(private val context: JvmBackendContext) : KotlinTypeMapperBas if (irClass != null && irClass.isInline) { return mapTypeAsDeclaration(irType) } - val type = mapType(irType) + val type = AbstractTypeMapper.mapType(this, irType) return AsmUtil.boxPrimitiveType(type) ?: type } @@ -108,83 +114,11 @@ class IrTypeMapper(private val context: JvmBackendContext) : KotlinTypeMapperBas type: IrType, mode: TypeMappingMode = TypeMappingMode.DEFAULT, sw: JvmSignatureWriter? = null - ): Type { - if (type !is IrSimpleType) { - val kotlinType = type.originalKotlinType - error("Unexpected type: $type (original Kotlin type=$kotlinType of ${kotlinType?.let { it::class }})") - } + ): Type = AbstractTypeMapper.mapType(this, type, mode, sw) - if (type.isSuspendFunction()) { - val arguments = - type.arguments.dropLast(1).map { it.adjustedType } + - context.ir.symbols.continuationClass.typeWith(type.arguments.last().adjustedType) + - context.irBuiltIns.anyNType - val runtimeFunctionType = context.referenceClass(context.builtIns.getFunction(arguments.size - 1)).typeWith(arguments) - return mapType(runtimeFunctionType, mode, sw) - } - - with(typeSystem) { - mapBuiltInType(type, AsmTypeFactory, mode) - }?.let { builtInType -> - return boxTypeIfNeeded(builtInType, mode.needPrimitiveBoxing).also { asmType -> - sw?.writeGenericType(type, asmType, mode) - } - } - - val classifier = type.classifierOrNull?.owner - - when { - type.isArray() || type.isNullableArray() -> { - val typeArgument = type.arguments.single() - val (variance, memberType) = when (typeArgument) { - is IrTypeProjection -> Pair(typeArgument.variance, typeArgument.type) - is IrStarProjection -> Pair(Variance.OUT_VARIANCE, context.irBuiltIns.anyNType) - else -> error("Unsupported type argument: $typeArgument") - } - - val arrayElementType: Type - sw?.writeArrayType() - if (variance == Variance.IN_VARIANCE) { - arrayElementType = AsmTypes.OBJECT_TYPE - sw?.writeClass(arrayElementType) - } else { - arrayElementType = mapType(memberType, mode.toGenericArgumentMode(variance, ofArray = true), sw) - } - sw?.writeArrayEnd() - - return AsmUtil.getArrayType(arrayElementType) - } - - classifier is IrClass -> { - if (classifier.isInline && !mode.needInlineClassWrapping) { - val expandedType = typeSystem.computeExpandedTypeForInlineClass(type) as IrType? - if (expandedType != null) { - return mapType(expandedType, mode.wrapInlineClassesMode(), sw) - } - } - - val asmType = - if (mode.isForAnnotationParameter && type.isKClass()) AsmTypes.JAVA_CLASS_TYPE - else Type.getObjectType(classInternalName(classifier)) - - sw?.writeGenericType(type, asmType, mode) - - return asmType - } - - classifier is IrTypeParameter -> { - return mapType(classifier.representativeUpperBound, mode, null).also { asmType -> - sw?.writeTypeVariable(classifier.name, asmType) - } - } - - else -> throw UnsupportedOperationException("Unknown type $type") - } - } - - // Copied from KotlinTypeMapper.writeGenericType. - private fun JvmSignatureWriter.writeGenericType(type: IrSimpleType, asmType: Type, mode: TypeMappingMode) { - if (skipGenericSignature() || hasNothingInNonContravariantPosition(type) || type.arguments.isEmpty() || type.isRawType()) { + override fun JvmSignatureWriter.writeGenericType(type: SimpleTypeMarker, asmType: Type, mode: TypeMappingMode) { + require(type is IrSimpleType) + if (skipGenericSignature() || hasNothingInNonContravariantPosition(type) || type.arguments.isEmpty() || type.isRawTypeImpl()) { writeAsmType(asmType) return } @@ -255,12 +189,66 @@ class IrTypeMapper(private val context: JvmBackendContext) : KotlinTypeMapperBas arguments: List, parameters: List, mode: TypeMappingMode - ) = with(KotlinTypeMapper) { - typeSystem.writeGenericArguments(sw, arguments, parameters, mode) { type, sw, mode -> - mapType(type as IrType, mode, sw) + ) { + with(KotlinTypeMapper) { + typeSystem.writeGenericArguments(sw, arguments, parameters, mode) { type, sw, mode -> + mapType(type as IrType, mode, sw) + } + } + } +} + +private class IrTypeCheckerContextForTypeMapping( + private val baseContext: IrTypeSystemContext, + private val backendContext: JvmBackendContext +) : IrTypeSystemContext by baseContext, TypeSystemCommonBackendContextForTypeMapping { + override fun TypeConstructorMarker.isTypeParameter(): Boolean { + return this is IrTypeParameterSymbol + } + + override fun TypeConstructorMarker.defaultType(): IrType { + return when (this) { + is IrClassSymbol -> owner.defaultType + is IrTypeParameterSymbol -> owner.defaultType + else -> error("Unsupported type constructor: $this") } } - private fun boxTypeIfNeeded(possiblyPrimitiveType: Type, needBoxedType: Boolean): Type = - if (needBoxedType) AsmUtil.boxType(possiblyPrimitiveType) else possiblyPrimitiveType + override fun SimpleTypeMarker.isSuspendFunction(): Boolean { + require(this is IrSimpleType) + return isSuspendFunctionImpl() + } + + override fun SimpleTypeMarker.isKClass(): Boolean { + require(this is IrSimpleType) + return isKClassImpl() + } + + override fun KotlinTypeMarker.isRawType(): Boolean { + require(this is IrType) + if (this !is IrSimpleType) return false + return isRawTypeImpl() + } + + override fun TypeConstructorMarker.typeWithArguments(arguments: List): IrSimpleType { + require(this is IrClassSymbol) + arguments.forEach { + require(it is IrType) + } + @Suppress("UNCHECKED_CAST") + return typeWith(arguments as List) + } + + override fun TypeParameterMarker.representativeUpperBound(): IrType { + require(this is IrTypeParameterSymbol) + return owner.representativeUpperBound + } + + override fun continuationTypeConstructor(): IrClassSymbol { + return backendContext.ir.symbols.continuationClass + } + + override fun functionNTypeConstructor(n: Int): IrClassSymbol { + return backendContext.referenceClass(backendContext.builtIns.getFunction(n)) + } } diff --git a/core/compiler.backend.common.jvm/src/org/jetbrains/kotlin/types/AbstractTypeMapper.kt b/core/compiler.backend.common.jvm/src/org/jetbrains/kotlin/types/AbstractTypeMapper.kt index dbb1e612280..2514c23fcb6 100644 --- a/core/compiler.backend.common.jvm/src/org/jetbrains/kotlin/types/AbstractTypeMapper.kt +++ b/core/compiler.backend.common.jvm/src/org/jetbrains/kotlin/types/AbstractTypeMapper.kt @@ -14,15 +14,15 @@ import org.jetbrains.kotlin.resolve.jvm.AsmTypes import org.jetbrains.kotlin.types.model.* import org.jetbrains.org.objectweb.asm.Type -interface TypeMappingContext { +interface TypeMappingContext> { val typeContext: TypeSystemCommonBackendContextForTypeMapping fun getClassInternalName(typeConstructor: TypeConstructorMarker): String - fun JvmDescriptorTypeWriter.writeGenericType(type: SimpleTypeMarker, asmType: Type, mode: TypeMappingMode) + fun Writer.writeGenericType(type: SimpleTypeMarker, asmType: Type, mode: TypeMappingMode) } object AbstractTypeMapper { - fun mapClass(context: TypeMappingContext, typeConstructor: TypeConstructorMarker): Type { + fun > mapClass(context: TypeMappingContext, typeConstructor: TypeConstructorMarker): Type { return with(context.typeContext) { when { typeConstructor.isClassTypeConstructor() -> { @@ -36,13 +36,23 @@ object AbstractTypeMapper { } } - @OptIn(ExperimentalStdlibApi::class) - fun TypeSystemCommonBackendContextForTypeMapping.mapType( - context: TypeMappingContext, - type: SimpleTypeMarker, + fun > mapType( + context: TypeMappingContext, + type: KotlinTypeMarker, mode: TypeMappingMode = TypeMappingMode.DEFAULT, - sw: JvmDescriptorTypeWriter? = null + sw: Writer? = null + ): Type = context.typeContext.mapType(context, type, mode, sw) + + @OptIn(ExperimentalStdlibApi::class) + private fun > TypeSystemCommonBackendContextForTypeMapping.mapType( + context: TypeMappingContext, + type: KotlinTypeMarker, + mode: TypeMappingMode = TypeMappingMode.DEFAULT, + sw: Writer? = null ): Type { + if (type !is SimpleTypeMarker) { + error("Unexpected type: $type (original Kotlin type=$type of ${type.let { it::class }})") + } if (type.isSuspendFunction()) { val argumentsCount = type.argumentsCount() val argumentsList = type.asArgumentList() diff --git a/core/compiler.common/src/org/jetbrains/kotlin/types/TypeSystemCommonBackendContext.kt b/core/compiler.common/src/org/jetbrains/kotlin/types/TypeSystemCommonBackendContext.kt index 08ede6e58cd..5d5c0cca33b 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/types/TypeSystemCommonBackendContext.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/types/TypeSystemCommonBackendContext.kt @@ -53,7 +53,7 @@ interface TypeSystemCommonBackendContext : TypeSystemContext { interface TypeSystemCommonBackendContextForTypeMapping : TypeSystemCommonBackendContext { fun TypeConstructorMarker.isTypeParameter(): Boolean - fun TypeConstructorMarker.defaultType(): SimpleTypeMarker + fun TypeConstructorMarker.defaultType(): KotlinTypeMarker fun SimpleTypeMarker.isSuspendFunction(): Boolean fun SimpleTypeMarker.isKClass(): Boolean @@ -70,7 +70,7 @@ interface TypeSystemCommonBackendContextForTypeMapping : TypeSystemCommonBackend return getType() } - fun TypeParameterMarker.representativeUpperBound(): SimpleTypeMarker + fun TypeParameterMarker.representativeUpperBound(): KotlinTypeMarker fun continuationTypeConstructor(): TypeConstructorMarker fun functionNTypeConstructor(n: Int): TypeConstructorMarker