JVM reorganize AbstractTypeMapper.mapType

This commit is contained in:
Dmitry Petrov
2022-02-10 15:47:41 +03:00
committed by Space
parent 7b18d69f5f
commit 54299e83e8
@@ -25,7 +25,10 @@ interface TypeMappingContext<Writer : JvmDescriptorTypeWriter<Type>> {
} }
object AbstractTypeMapper { object AbstractTypeMapper {
fun <Writer : JvmDescriptorTypeWriter<Type>> mapClass(context: TypeMappingContext<Writer>, typeConstructor: TypeConstructorMarker): Type { fun <Writer : JvmDescriptorTypeWriter<Type>> mapClass(
context: TypeMappingContext<Writer>,
typeConstructor: TypeConstructorMarker
): Type {
return with(context.typeContext) { return with(context.typeContext) {
when { when {
typeConstructor.isClassTypeConstructor() -> { typeConstructor.isClassTypeConstructor() -> {
@@ -47,21 +50,66 @@ object AbstractTypeMapper {
): Type = context.typeContext.mapType(context, type, mode, sw) ): Type = context.typeContext.mapType(context, type, mode, sw)
// NB: The counterpart, [descriptorBasedTypeSignatureMapping#mapType] doesn't have restriction on [type]. // NB: The counterpart, [descriptorBasedTypeSignatureMapping#mapType] doesn't have restriction on [type].
@OptIn(ExperimentalStdlibApi::class)
private fun <Writer : JvmDescriptorTypeWriter<Type>> TypeSystemCommonBackendContextForTypeMapping.mapType( private fun <Writer : JvmDescriptorTypeWriter<Type>> TypeSystemCommonBackendContextForTypeMapping.mapType(
context: TypeMappingContext<Writer>, context: TypeMappingContext<Writer>,
type: KotlinTypeMarker, type: KotlinTypeMarker,
mode: TypeMappingMode = TypeMappingMode.DEFAULT, mode: TypeMappingMode = TypeMappingMode.DEFAULT,
sw: Writer? = null sw: Writer? = null
): Type { ): Type {
if (type is DefinitelyNotNullTypeMarker) { val typeConstructor = type.typeConstructor()
return mapType(context, type.original(), mode, sw)
if (type is SimpleTypeMarker) {
val builtInType = mapBuiltInType(type, AsmTypeFactory, mode)
if (builtInType != null) {
val asmType = boxTypeIfNeeded(builtInType, mode.needPrimitiveBoxing)
with(context) { sw?.writeGenericType(type, asmType, mode) }
return asmType
} }
if (type is SimpleTypeMarker && type.isSuspendFunction()) { if (type.isSuspendFunction()) {
return mapSuspendFunctionType(type, context, mode, sw)
}
if (type.isArrayOrNullableArray()) {
return mapArrayType(type, sw, context, mode)
}
if (typeConstructor.isClassTypeConstructor()) {
return mapClassType(typeConstructor, mode, type, context, sw)
}
}
return when {
typeConstructor.isTypeParameter() -> {
val typeParameter = typeConstructor.asTypeParameter()
val asmType = mapType(context, typeParameter.representativeUpperBound(), mode, null)
sw?.writeTypeVariable(typeParameter.getName(), asmType)
asmType
}
type.isFlexible() -> {
mapType(context, type.upperBoundIfFlexible(), mode, sw)
}
type is DefinitelyNotNullTypeMarker ->
mapType(context, type.original(), mode, sw)
typeConstructor.isScript() ->
Type.getObjectType(context.getScriptInternalName(typeConstructor))
else ->
throw UnsupportedOperationException("Unknown type $type")
}
}
private fun <Writer : JvmDescriptorTypeWriter<Type>> TypeSystemCommonBackendContextForTypeMapping.mapSuspendFunctionType(
type: SimpleTypeMarker,
context: TypeMappingContext<Writer>,
mode: TypeMappingMode,
sw: Writer?
): Type {
val argumentsCount = type.argumentsCount() val argumentsCount = type.argumentsCount()
val argumentsList = type.asArgumentList() val argumentsList = type.asArgumentList()
val arguments = buildList { val arguments = buildList {
for (i in 0 until (argumentsCount - 1)) { for (i in 0 until (argumentsCount - 1)) {
this += argumentsList[i].adjustedType() this += argumentsList[i].adjustedType()
@@ -73,16 +121,12 @@ object AbstractTypeMapper {
return mapType(context, runtimeFunctionType, mode, sw) return mapType(context, runtimeFunctionType, mode, sw)
} }
mapBuiltInType(type, AsmTypeFactory, mode)?.let { builtInType -> private fun <Writer : JvmDescriptorTypeWriter<Type>> TypeSystemCommonBackendContextForTypeMapping.mapArrayType(
return boxTypeIfNeeded(builtInType, mode.needPrimitiveBoxing).also { asmType -> type: SimpleTypeMarker,
with(context) { sw?.writeGenericType(type, asmType, mode) } sw: Writer?,
} context: TypeMappingContext<Writer>,
} mode: TypeMappingMode
): Type {
val typeConstructor = type.typeConstructor()
when {
type is SimpleTypeMarker && type.isArrayOrNullableArray() -> {
val typeArgument = type.asArgumentList()[0] val typeArgument = type.asArgumentList()[0]
val (variance, memberType) = when { val (variance, memberType) = when {
typeArgument.isStarProjection() -> Variance.OUT_VARIANCE to nullableAnyType() typeArgument.isStarProjection() -> Variance.OUT_VARIANCE to nullableAnyType()
@@ -102,7 +146,13 @@ object AbstractTypeMapper {
return AsmUtil.getArrayType(arrayElementType) return AsmUtil.getArrayType(arrayElementType)
} }
type is SimpleTypeMarker && typeConstructor.isClassTypeConstructor() -> { private fun <Writer : JvmDescriptorTypeWriter<Type>> TypeSystemCommonBackendContextForTypeMapping.mapClassType(
typeConstructor: TypeConstructorMarker,
mode: TypeMappingMode,
type: SimpleTypeMarker,
context: TypeMappingContext<Writer>,
sw: Writer?
): Type {
if (typeConstructor.isInlineClass() && !mode.needInlineClassWrapping) { if (typeConstructor.isInlineClass() && !mode.needInlineClassWrapping) {
val expandedType = computeExpandedTypeForInlineClass(type) val expandedType = computeExpandedTypeForInlineClass(type)
require(expandedType is SimpleTypeMarker?) require(expandedType is SimpleTypeMarker?)
@@ -120,25 +170,6 @@ object AbstractTypeMapper {
return asmType return asmType
} }
typeConstructor.isScript() -> {
return Type.getObjectType(context.getScriptInternalName(typeConstructor))
}
typeConstructor.isTypeParameter() -> {
val typeParameter = typeConstructor.asTypeParameter()
return mapType(context, typeParameter.representativeUpperBound(), mode, null).also { asmType ->
sw?.writeTypeVariable(typeParameter.getName(), asmType)
}
}
type.isFlexible() -> {
return mapType(context, type.upperBoundIfFlexible(), mode, sw)
}
else -> throw UnsupportedOperationException("Unknown type $type")
}
}
private fun boxTypeIfNeeded(possiblyPrimitiveType: Type, needBoxedType: Boolean): Type = private fun boxTypeIfNeeded(possiblyPrimitiveType: Type, needBoxedType: Boolean): Type =
if (needBoxedType) AsmUtil.boxType(possiblyPrimitiveType) else possiblyPrimitiveType if (needBoxedType) AsmUtil.boxType(possiblyPrimitiveType) else possiblyPrimitiveType