Make IrTypeMapper delegate to AbstractTypeMapper
This commit is contained in:
+83
-95
@@ -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<JvmSignatureWriter> {
|
||||
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<IrTypeArgument>,
|
||||
parameters: List<IrTypeParameterSymbol>,
|
||||
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<KotlinTypeMarker>): IrSimpleType {
|
||||
require(this is IrClassSymbol)
|
||||
arguments.forEach {
|
||||
require(it is IrType)
|
||||
}
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return typeWith(arguments as List<IrType>)
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
+18
-8
@@ -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<Writer : JvmDescriptorTypeWriter<Type>> {
|
||||
val typeContext: TypeSystemCommonBackendContextForTypeMapping
|
||||
|
||||
fun getClassInternalName(typeConstructor: TypeConstructorMarker): String
|
||||
fun JvmDescriptorTypeWriter<Type>.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 <Writer : JvmDescriptorTypeWriter<Type>> mapClass(context: TypeMappingContext<Writer>, 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 <Writer : JvmDescriptorTypeWriter<Type>> mapType(
|
||||
context: TypeMappingContext<Writer>,
|
||||
type: KotlinTypeMarker,
|
||||
mode: TypeMappingMode = TypeMappingMode.DEFAULT,
|
||||
sw: JvmDescriptorTypeWriter<Type>? = null
|
||||
sw: Writer? = null
|
||||
): Type = context.typeContext.mapType(context, type, mode, sw)
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
private fun <Writer : JvmDescriptorTypeWriter<Type>> TypeSystemCommonBackendContextForTypeMapping.mapType(
|
||||
context: TypeMappingContext<Writer>,
|
||||
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()
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user