JVM IR: do not use descriptors in IrTypeMapper.writeFormalTypeParameters
This commit is contained in:
@@ -55,7 +55,10 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils.*
|
||||
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.VarargValueArgument
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.*
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isPublishedApi
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.DEFAULT_CONSTRUCTOR_MARKER
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
@@ -967,47 +970,13 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
||||
fun writeFormalTypeParameters(typeParameters: List<TypeParameterDescriptor>, sw: JvmSignatureWriter) {
|
||||
if (sw.skipGenericSignature()) return
|
||||
for (typeParameter in typeParameters) {
|
||||
writeFormalTypeParameter(typeParameter, sw)
|
||||
}
|
||||
}
|
||||
|
||||
private fun writeFormalTypeParameter(typeParameterDescriptor: TypeParameterDescriptor, sw: JvmSignatureWriter) {
|
||||
if (!classBuilderMode.generateBodies && typeParameterDescriptor.name.isSpecial) {
|
||||
// If a type parameter has no name, the code below fails, but it should recover in case of light classes
|
||||
return
|
||||
}
|
||||
|
||||
sw.writeFormalTypeParameter(typeParameterDescriptor.name.asString())
|
||||
|
||||
sw.writeClassBound()
|
||||
|
||||
for (type in typeParameterDescriptor.upperBounds) {
|
||||
if (type.constructor.declarationDescriptor is ClassDescriptor && !isJvmInterface(type)) {
|
||||
mapType(type, sw, TypeMappingMode.GENERIC_ARGUMENT)
|
||||
break
|
||||
if (!classBuilderMode.generateBodies && typeParameter.name.isSpecial) {
|
||||
// If a type parameter has no name, the code below fails, but it should recover in case of light classes
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// "extends Object" is optional according to ClassFileFormat-Java5.pdf
|
||||
// but javac complaints to signature:
|
||||
// <P:>Ljava/lang/Object;
|
||||
// TODO: avoid writing java/lang/Object if interface list is not empty
|
||||
|
||||
sw.writeClassBoundEnd()
|
||||
|
||||
for (type in typeParameterDescriptor.upperBounds) {
|
||||
when (val classifier = type.constructor.declarationDescriptor) {
|
||||
is ClassDescriptor -> if (isJvmInterface(type)) {
|
||||
sw.writeInterfaceBound()
|
||||
mapType(type, sw, TypeMappingMode.GENERIC_ARGUMENT)
|
||||
sw.writeInterfaceBoundEnd()
|
||||
}
|
||||
is TypeParameterDescriptor -> {
|
||||
sw.writeInterfaceBound()
|
||||
mapType(type, sw, TypeMappingMode.GENERIC_ARGUMENT)
|
||||
sw.writeInterfaceBoundEnd()
|
||||
}
|
||||
else -> throw UnsupportedOperationException("Unknown classifier: $classifier")
|
||||
SimpleClassicTypeSystemContext.writeFormalTypeParameter(typeParameter, sw) { type, mode ->
|
||||
mapType(type as KotlinType, sw, mode)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1661,5 +1630,40 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
||||
sw.writeAsmType(type)
|
||||
sw.writeParameterTypeEnd()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun TypeSystemCommonBackendContext.writeFormalTypeParameter(
|
||||
typeParameter: TypeParameterMarker,
|
||||
sw: JvmSignatureWriter,
|
||||
mapType: (KotlinTypeMarker, TypeMappingMode) -> Type
|
||||
) {
|
||||
sw.writeFormalTypeParameter(typeParameter.getName().asString())
|
||||
|
||||
sw.writeClassBound()
|
||||
|
||||
for (i in 0 until typeParameter.upperBoundCount()) {
|
||||
val type = typeParameter.getUpperBound(i)
|
||||
if (type.typeConstructor().getTypeParameterClassifier() == null && !type.isInterfaceOrAnnotationClass()) {
|
||||
mapType(type, TypeMappingMode.GENERIC_ARGUMENT)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// "extends Object" is optional according to ClassFileFormat-Java5.pdf
|
||||
// but javac complaints to signature:
|
||||
// <P:>Ljava/lang/Object;
|
||||
// TODO: avoid writing java/lang/Object if interface list is not empty
|
||||
|
||||
sw.writeClassBoundEnd()
|
||||
|
||||
for (i in 0 until typeParameter.upperBoundCount()) {
|
||||
val type = typeParameter.getUpperBound(i)
|
||||
if (type.typeConstructor().getTypeParameterClassifier() != null || type.isInterfaceOrAnnotationClass()) {
|
||||
sw.writeInterfaceBound()
|
||||
mapType(type, TypeMappingMode.GENERIC_ARGUMENT)
|
||||
sw.writeInterfaceBoundEnd()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
-2
@@ -42,8 +42,16 @@ class IrTypeMapper(private val context: JvmBackendContext) {
|
||||
context.getLocalClassInfo(irClass)?.internalName
|
||||
?: JvmCodegenUtil.sanitizeNameIfNeeded(computeInternalName(irClass), context.state.languageVersionSettings)
|
||||
|
||||
fun writeFormalTypeParameters(irParameters: List<IrTypeParameter>, sw: JvmSignatureWriter) =
|
||||
kotlinTypeMapper.writeFormalTypeParameters(irParameters.map { it.descriptor }, sw)
|
||||
fun writeFormalTypeParameters(irParameters: List<IrTypeParameter>, sw: JvmSignatureWriter) {
|
||||
if (sw.skipGenericSignature()) return
|
||||
with(KotlinTypeMapper) {
|
||||
for (typeParameter in irParameters) {
|
||||
typeSystem.writeFormalTypeParameter(typeParameter.symbol, sw) { type, mode ->
|
||||
mapType(type as IrType, mode, sw)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun boxType(irType: IrType): Type =
|
||||
AsmUtil.boxType(mapType(irType), irType.toKotlinType(), kotlinTypeMapper)
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.types.impl.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
@@ -325,6 +326,14 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
|
||||
|
||||
override fun TypeConstructorMarker.getClassFqNameUnsafe(): FqNameUnsafe? =
|
||||
(this as IrClassSymbol).owner.fqNameWhenAvailable?.toUnsafe()
|
||||
|
||||
override fun TypeParameterMarker.getName(): Name =
|
||||
(this as IrTypeParameterSymbol).owner.name
|
||||
|
||||
override fun KotlinTypeMarker.isInterfaceOrAnnotationClass(): Boolean {
|
||||
val irClass = (this as IrType).classOrNull?.owner
|
||||
return irClass != null && (irClass.isInterface || irClass.isAnnotationClass)
|
||||
}
|
||||
}
|
||||
|
||||
fun extractTypeParameters(klass: IrDeclarationParent): List<IrTypeParameter> {
|
||||
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.types
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.model.*
|
||||
|
||||
interface TypeSystemCommonBackendContext : TypeSystemContext {
|
||||
@@ -41,4 +42,8 @@ interface TypeSystemCommonBackendContext : TypeSystemContext {
|
||||
|
||||
fun TypeConstructorMarker.isUnderKotlinPackage(): Boolean
|
||||
fun TypeConstructorMarker.getClassFqNameUnsafe(): FqNameUnsafe?
|
||||
|
||||
fun TypeParameterMarker.getName(): Name
|
||||
|
||||
fun KotlinTypeMarker.isInterfaceOrAnnotationClass(): Boolean
|
||||
}
|
||||
|
||||
+12
-1
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.CapturedType
|
||||
import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||
@@ -27,7 +28,6 @@ import org.jetbrains.kotlin.types.typeUtil.contains
|
||||
import org.jetbrains.kotlin.types.typeUtil.representativeUpperBound
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.math.max
|
||||
|
||||
interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSystemCommonBackendContext {
|
||||
override fun TypeConstructorMarker.isDenotable(): Boolean {
|
||||
@@ -541,6 +541,17 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
|
||||
require(this is TypeConstructor, this::errorMessage)
|
||||
return (declarationDescriptor as ClassDescriptor).fqNameUnsafe
|
||||
}
|
||||
|
||||
override fun TypeParameterMarker.getName(): Name {
|
||||
require(this is TypeParameterDescriptor, this::errorMessage)
|
||||
return name
|
||||
}
|
||||
|
||||
override fun KotlinTypeMarker.isInterfaceOrAnnotationClass(): Boolean {
|
||||
require(this is KotlinType, this::errorMessage)
|
||||
val descriptor = constructor.declarationDescriptor
|
||||
return descriptor is ClassDescriptor && (descriptor.kind == ClassKind.INTERFACE || descriptor.kind == ClassKind.ANNOTATION_CLASS)
|
||||
}
|
||||
}
|
||||
|
||||
fun TypeVariance.convertVariance(): Variance {
|
||||
|
||||
Reference in New Issue
Block a user