JVM IR: do not use KotlinTypeMapper in IrTypeMapper.mapType
This commit is contained in:
@@ -1433,7 +1433,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
||||
private fun hasNothingInNonContravariantPosition(kotlinType: KotlinType): Boolean =
|
||||
SimpleClassicTypeSystemContext.hasNothingInNonContravariantPosition(kotlinType)
|
||||
|
||||
private fun TypeSystemContext.hasNothingInNonContravariantPosition(type: KotlinTypeMarker): Boolean {
|
||||
fun TypeSystemContext.hasNothingInNonContravariantPosition(type: KotlinTypeMarker): Boolean {
|
||||
val typeConstructor = type.typeConstructor()
|
||||
|
||||
for (i in 0 until type.argumentsCount()) {
|
||||
|
||||
+213
-13
@@ -6,40 +6,65 @@
|
||||
package org.jetbrains.kotlin.backend.jvm.codegen
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
|
||||
import org.jetbrains.kotlin.builtins.isSuspendFunctionType
|
||||
import org.jetbrains.kotlin.builtins.transformSuspendFunctionToRuntimeFunctionType
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilderMode
|
||||
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
|
||||
import org.jetbrains.kotlin.codegen.OwnerKind
|
||||
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.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
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.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
||||
import org.jetbrains.kotlin.load.kotlin.computeExpandedTypeForInlineClass
|
||||
import org.jetbrains.kotlin.load.kotlin.mapBuiltInType
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||
|
||||
class IrTypeMapper(private val context: JvmBackendContext) {
|
||||
val kotlinTypeMapper: KotlinTypeMapper = context.state.typeMapper
|
||||
private val typeSystem = IrTypeCheckerContext(context.irBuiltIns)
|
||||
|
||||
val classBuilderMode get() = kotlinTypeMapper.classBuilderMode
|
||||
val classBuilderMode: ClassBuilderMode
|
||||
get() = kotlinTypeMapper.classBuilderMode
|
||||
|
||||
fun classInternalName(irClass: IrClass) = kotlinTypeMapper.classInternalName(irClass.descriptor)
|
||||
fun classInternalName(irClass: IrClass): String =
|
||||
context.getLocalClassInfo(irClass)?.internalName
|
||||
?: JvmCodegenUtil.sanitizeNameIfNeeded(computeInternalName(irClass), context.state.languageVersionSettings)
|
||||
|
||||
fun mapAsmMethod(irFunction: IrFunction) = kotlinTypeMapper.mapAsmMethod(irFunction.descriptor)
|
||||
fun mapAsmMethod(irFunction: IrFunction): Method =
|
||||
kotlinTypeMapper.mapAsmMethod(irFunction.descriptor)
|
||||
|
||||
fun mapFieldSignature(irField: IrField) =
|
||||
kotlinTypeMapper.mapFieldSignature(irField.type.toKotlinType(), irField.descriptor)
|
||||
|
||||
fun mapFunctionName(irReturnTarget: IrReturnTarget, ownerKind: OwnerKind) =
|
||||
fun mapFunctionName(irReturnTarget: IrReturnTarget, ownerKind: OwnerKind): String =
|
||||
kotlinTypeMapper.mapFunctionName(irReturnTarget.descriptor, ownerKind)
|
||||
|
||||
fun mapImplementationOwner(irDeclaration: IrDeclaration) = kotlinTypeMapper.mapImplementationOwner(irDeclaration.descriptor)
|
||||
fun mapImplementationOwner(irDeclaration: IrDeclaration): Type =
|
||||
kotlinTypeMapper.mapImplementationOwner(irDeclaration.descriptor)
|
||||
|
||||
fun mapReturnType(irReturnTarget: IrReturnTarget) = kotlinTypeMapper.mapReturnType(irReturnTarget.descriptor)
|
||||
fun mapReturnType(irReturnTarget: IrReturnTarget): Type =
|
||||
kotlinTypeMapper.mapReturnType(irReturnTarget.descriptor)
|
||||
|
||||
fun mapSignatureSkipGeneric(f: IrFunction, kind: OwnerKind = OwnerKind.IMPLEMENTATION) =
|
||||
fun mapSignatureSkipGeneric(f: IrFunction, kind: OwnerKind = OwnerKind.IMPLEMENTATION): JvmMethodSignature =
|
||||
kotlinTypeMapper.mapSignatureSkipGeneric(f.descriptor, kind)
|
||||
|
||||
fun mapSignatureWithGeneric(f: IrFunction, kind: OwnerKind) = kotlinTypeMapper.mapSignatureWithGeneric(f.descriptor, kind)
|
||||
fun mapSignatureWithGeneric(f: IrFunction, kind: OwnerKind): JvmMethodGenericSignature =
|
||||
kotlinTypeMapper.mapSignatureWithGeneric(f.descriptor, kind)
|
||||
|
||||
fun mapToCallableMethod(f: IrFunction, superCall: Boolean, kind: OwnerKind? = null, resolvedCall: ResolvedCall<*>? = null) =
|
||||
kotlinTypeMapper.mapToCallableMethod(f.descriptor, superCall, kind, resolvedCall)
|
||||
@@ -47,13 +72,188 @@ class IrTypeMapper(private val context: JvmBackendContext) {
|
||||
fun writeFormalTypeParameters(irParameters: List<IrTypeParameter>, sw: JvmSignatureWriter) =
|
||||
kotlinTypeMapper.writeFormalTypeParameters(irParameters.map { it.descriptor }, sw)
|
||||
|
||||
fun boxType(irType: IrType) =
|
||||
fun boxType(irType: IrType): Type =
|
||||
AsmUtil.boxType(mapType(irType), irType.toKotlinType(), kotlinTypeMapper)
|
||||
|
||||
fun mapType(
|
||||
type: IrType,
|
||||
mode: TypeMappingMode = TypeMappingMode.DEFAULT,
|
||||
sw: JvmSignatureWriter? = null
|
||||
): Type =
|
||||
kotlinTypeMapper.mapType(type.toKotlinType(), sw, mode)
|
||||
): Type {
|
||||
if (type !is IrSimpleType) {
|
||||
val kotlinType = type.originalKotlinType
|
||||
error("Unexpected type: $type (original Kotlin type=$kotlinType of ${kotlinType?.let { it::class }})")
|
||||
}
|
||||
|
||||
// TODO: rewrite this part to produce the correct Type without the fake descriptor
|
||||
if (type.toKotlinType().isSuspendFunctionType) {
|
||||
return kotlinTypeMapper.mapType(
|
||||
transformSuspendFunctionToRuntimeFunctionType(type.toKotlinType(), isReleaseCoroutines = true), sw, mode
|
||||
)
|
||||
}
|
||||
|
||||
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), 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")
|
||||
}
|
||||
}
|
||||
|
||||
private fun computeInternalName(klass: IrClass): String {
|
||||
val className = SpecialNames.safeIdentifier(klass.name).identifier
|
||||
return when (val parent = klass.parent) {
|
||||
is IrPackageFragment -> {
|
||||
val fqName = parent.fqName
|
||||
val prefix = if (fqName.isRoot) "" else fqName.asString().replace('.', '/') + "/"
|
||||
prefix + className
|
||||
}
|
||||
is IrClass -> {
|
||||
computeInternalName(parent) + "$" + className
|
||||
}
|
||||
else -> error(
|
||||
"Local class should have its name computed in InventNamesForLocalClasses: ${klass.fqNameWhenAvailable}\n" +
|
||||
"Ensure that any lowering that transforms elements with local class info (classes, function references, " +
|
||||
"IrTypeOperatorCall for SAM conversions) invokes `copyAttributes` on the transformed element."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Copied from KotlinTypeMapper.writeGenericType.
|
||||
private fun JvmSignatureWriter.writeGenericType(type: IrSimpleType, asmType: Type, mode: TypeMappingMode) {
|
||||
if (skipGenericSignature() || hasNothingInNonContravariantPosition(type) || type.arguments.isEmpty()) {
|
||||
writeAsmType(asmType)
|
||||
return
|
||||
}
|
||||
|
||||
val possiblyInnerType = type.buildPossiblyInnerType() ?: error("possiblyInnerType with arguments should not be null")
|
||||
|
||||
val innerTypesAsList = possiblyInnerType.segments()
|
||||
|
||||
val indexOfParameterizedType = innerTypesAsList.indexOfFirst { innerPart -> innerPart.arguments.isNotEmpty() }
|
||||
if (indexOfParameterizedType < 0 || innerTypesAsList.size == 1) {
|
||||
writeClassBegin(asmType)
|
||||
writeGenericArguments(this, possiblyInnerType, mode)
|
||||
} else {
|
||||
val outerType = innerTypesAsList[indexOfParameterizedType]
|
||||
|
||||
writeOuterClassBegin(asmType, mapType(outerType.classifier.defaultType).internalName)
|
||||
writeGenericArguments(this, outerType, mode)
|
||||
|
||||
writeInnerParts(
|
||||
innerTypesAsList,
|
||||
this,
|
||||
mode,
|
||||
indexOfParameterizedType + 1
|
||||
) // inner parts separated by `.`
|
||||
}
|
||||
|
||||
writeClassEnd()
|
||||
}
|
||||
|
||||
private fun hasNothingInNonContravariantPosition(irType: IrType): Boolean = with(KotlinTypeMapper) {
|
||||
typeSystem.hasNothingInNonContravariantPosition(irType)
|
||||
}
|
||||
|
||||
private fun writeInnerParts(
|
||||
innerTypesAsList: List<PossiblyInnerIrType>,
|
||||
sw: JvmSignatureWriter,
|
||||
mode: TypeMappingMode,
|
||||
index: Int
|
||||
) {
|
||||
for (innerPart in innerTypesAsList.subList(index, innerTypesAsList.size)) {
|
||||
sw.writeInnerClass(getJvmShortName(innerPart.classifier))
|
||||
writeGenericArguments(sw, innerPart, mode)
|
||||
}
|
||||
}
|
||||
|
||||
// Copied from KotlinTypeMapper.writeGenericArguments.
|
||||
private fun writeGenericArguments(
|
||||
sw: JvmSignatureWriter,
|
||||
type: PossiblyInnerIrType,
|
||||
mode: TypeMappingMode
|
||||
) {
|
||||
val classifier = type.classifier
|
||||
val parameters = classifier.typeParameters.map(IrTypeParameter::symbol)
|
||||
val arguments = type.arguments
|
||||
|
||||
// TODO: get rid of descriptor here
|
||||
val classDescriptor = classifier.descriptor
|
||||
if (classDescriptor is FunctionClassDescriptor) {
|
||||
if (classDescriptor.hasBigArity ||
|
||||
classDescriptor.functionKind == FunctionClassDescriptor.Kind.KFunction ||
|
||||
classDescriptor.functionKind == FunctionClassDescriptor.Kind.KSuspendFunction
|
||||
) {
|
||||
writeGenericArguments(sw, listOf(arguments.last()), listOf(parameters.last()), mode)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
writeGenericArguments(sw, arguments, parameters, mode)
|
||||
}
|
||||
|
||||
private fun writeGenericArguments(
|
||||
sw: JvmSignatureWriter,
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
private fun boxTypeIfNeeded(possiblyPrimitiveType: Type, needBoxedType: Boolean): Type =
|
||||
if (needBoxedType) AsmUtil.boxType(possiblyPrimitiveType) else possiblyPrimitiveType
|
||||
}
|
||||
|
||||
+54
-4
@@ -5,14 +5,20 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.codegen
|
||||
|
||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrField
|
||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.IrTypeArgument
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||
import org.jetbrains.kotlin.ir.util.isLocalClass
|
||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
fun IrTypeMapper.mapType(irVariable: IrVariable): Type =
|
||||
@@ -35,3 +41,47 @@ fun IrTypeMapper.mapTypeAsDeclaration(irType: IrType): Type =
|
||||
|
||||
fun IrTypeMapper.mapTypeParameter(irType: IrType, sw: JvmSignatureWriter): Type =
|
||||
mapType(irType, TypeMappingMode.GENERIC_ARGUMENT, sw)
|
||||
|
||||
internal fun getJvmShortName(klass: IrClass): String =
|
||||
klass.fqNameWhenAvailable?.toUnsafe()?.let { JavaToKotlinClassMap.mapKotlinToJava(it)?.shortClassName?.asString() }
|
||||
?: SpecialNames.safeIdentifier(klass.name).identifier
|
||||
|
||||
internal class PossiblyInnerIrType(
|
||||
val classifier: IrClass,
|
||||
val arguments: List<IrTypeArgument>,
|
||||
private val outerType: PossiblyInnerIrType?
|
||||
) {
|
||||
fun segments(): List<PossiblyInnerIrType> = outerType?.segments().orEmpty() + this
|
||||
}
|
||||
|
||||
internal fun IrSimpleType.buildPossiblyInnerType(): PossiblyInnerIrType? =
|
||||
buildPossiblyInnerType(classOrNull?.owner, 0)
|
||||
|
||||
private fun IrSimpleType.buildPossiblyInnerType(classifier: IrClass?, index: Int): PossiblyInnerIrType? {
|
||||
if (classifier == null) return null
|
||||
|
||||
val toIndex = classifier.typeParameters.size + index
|
||||
if (!classifier.isInner) {
|
||||
assert(toIndex == arguments.size || classifier.isLocalClass()) {
|
||||
"${arguments.size - toIndex} trailing arguments were found in $this type"
|
||||
}
|
||||
|
||||
return PossiblyInnerIrType(classifier, arguments.subList(index, arguments.size), null)
|
||||
}
|
||||
|
||||
val argumentsSubList = arguments.subList(index, toIndex)
|
||||
return PossiblyInnerIrType(
|
||||
classifier, argumentsSubList,
|
||||
buildPossiblyInnerType(classifier.parentAsClass, toIndex)
|
||||
)
|
||||
}
|
||||
|
||||
internal val IrTypeParameter.representativeUpperBound: IrType
|
||||
get() {
|
||||
assert(superTypes.isNotEmpty()) { "Upper bounds should not be empty: $this" }
|
||||
|
||||
return superTypes.firstOrNull {
|
||||
val irClass = it.classOrNull?.owner ?: return@firstOrNull false
|
||||
irClass.kind != ClassKind.INTERFACE && irClass.kind != ClassKind.ANNOTATION_CLASS
|
||||
} ?: superTypes.first()
|
||||
}
|
||||
|
||||
+10
-3
@@ -5,7 +5,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.*
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.BlockInfo
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.PromisedValue
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.coerce
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
|
||||
/**
|
||||
@@ -19,10 +22,14 @@ object UnsafeCoerce : IntrinsicMethod() {
|
||||
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? {
|
||||
val from = expression.getTypeArgument(0)!!
|
||||
val to = expression.getTypeArgument(1)!!
|
||||
require(with(codegen) { typeMapper.mapType(from) == typeMapper.mapType(to) })
|
||||
val fromType = codegen.typeMapper.mapType(from)
|
||||
val toType = codegen.typeMapper.mapType(to)
|
||||
require(fromType == toType) {
|
||||
"Inline class types should have the same representation: $fromType != $toType"
|
||||
}
|
||||
val arg = expression.getValueArgument(0)!!
|
||||
val result = arg.accept(codegen, data)
|
||||
return object : PromisedValue(codegen, codegen.typeMapper.mapType(to), to) {
|
||||
return object : PromisedValue(codegen, toType, to) {
|
||||
override fun materialize() = result.coerce(from).materialize()
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -84,8 +84,8 @@ private class FunctionNVarargInvokeLowering(var context: JvmBackendContext) : Cl
|
||||
symbol = IrValueParameterSymbolImpl(varargParameterDescriptor),
|
||||
name = Name.identifier("args"),
|
||||
index = 0,
|
||||
type = context.irBuiltIns.arrayClass.typeWith(),
|
||||
varargElementType = context.irBuiltIns.anyClass.typeWith(),
|
||||
type = context.irBuiltIns.arrayClass.typeWith(context.irBuiltIns.anyNType),
|
||||
varargElementType = context.irBuiltIns.anyNType,
|
||||
isCrossinline = false,
|
||||
isNoinline = false
|
||||
).apply {
|
||||
|
||||
+7
-15
@@ -7,8 +7,11 @@ package org.jetbrains.kotlin.ir.symbols
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName
|
||||
import org.jetbrains.kotlin.ir.declarations.IrPackageFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner
|
||||
import org.jetbrains.kotlin.ir.util.isLocalClass
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
@@ -31,7 +34,7 @@ object FqNameEqualityChecker : IrClassifierEqualityChecker {
|
||||
override fun getHashCode(symbol: IrClassifierSymbol): Int {
|
||||
if (symbol.isBound) {
|
||||
val owner = symbol.owner
|
||||
if (owner is IrClass && !isLocalClass(owner)) {
|
||||
if (owner is IrClass && !owner.isLocalClass()) {
|
||||
return owner.fqName.hashCode()
|
||||
}
|
||||
return owner.hashCode()
|
||||
@@ -54,20 +57,9 @@ object FqNameEqualityChecker : IrClassifierEqualityChecker {
|
||||
return parentFqName?.child(name)
|
||||
}
|
||||
|
||||
private fun isLocalClass(declaration: IrClass): Boolean {
|
||||
var current: IrDeclarationParent? = declaration
|
||||
while (current != null && current !is IrPackageFragment) {
|
||||
if (current is IrDeclarationWithVisibility && current.visibility == Visibilities.LOCAL)
|
||||
return true
|
||||
current = (current as? IrDeclaration)?.parent
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun checkViaDeclarations(c1: IrSymbolOwner, c2: IrSymbolOwner): Boolean {
|
||||
if (c1 is IrClass && c2 is IrClass) {
|
||||
if (isLocalClass(c1) || isLocalClass(c2))
|
||||
if (c1.isLocalClass() || c2.isLocalClass())
|
||||
return c1 === c2 // Local declarations should be identical
|
||||
|
||||
return c1.fqName == c2.fqName
|
||||
|
||||
@@ -6,22 +6,30 @@
|
||||
package org.jetbrains.kotlin.ir.types
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConst
|
||||
import org.jetbrains.kotlin.ir.symbols.FqNameEqualityChecker
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
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.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.checker.convertVariance
|
||||
import org.jetbrains.kotlin.types.model.*
|
||||
import org.jetbrains.kotlin.ir.types.isPrimitiveType as irTypePredicates_isPrimitiveType
|
||||
|
||||
interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesContext {
|
||||
interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesContext, TypeSystemCommonBackendContext {
|
||||
|
||||
val irBuiltIns: IrBuiltIns
|
||||
|
||||
@@ -247,6 +255,67 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
|
||||
|
||||
override fun createErrorTypeWithCustomConstructor(debugName: String, constructor: TypeConstructorMarker): KotlinTypeMarker =
|
||||
TODO("IrTypeSystemContext doesn't support constraint system resolution")
|
||||
|
||||
override fun TypeConstructorMarker.isFinalClassOrEnumEntryOrAnnotationClassConstructor(): Boolean {
|
||||
val symbol = this as IrClassifierSymbol
|
||||
return symbol is IrClassSymbol && symbol.owner.let {
|
||||
it.modality == Modality.FINAL && !it.isEnumClass
|
||||
}
|
||||
}
|
||||
|
||||
override fun KotlinTypeMarker.hasAnnotation(fqName: FqName): Boolean =
|
||||
// TODO: don't fall back to KotlinType to check annotations. Currently testIdentityEquals fails on JVM without it
|
||||
(this as IrAnnotationContainer).hasAnnotation(fqName) ||
|
||||
(this as IrType).toKotlinType().annotations.hasAnnotation(fqName)
|
||||
|
||||
override fun KotlinTypeMarker.getAnnotationFirstArgumentValue(fqName: FqName): Any? =
|
||||
(this as? IrType)?.annotations?.firstOrNull { annotation ->
|
||||
annotation.symbol.owner.parentAsClass.descriptor.fqNameSafe == fqName
|
||||
}?.run {
|
||||
if (valueArgumentsCount > 0) (getValueArgument(0) as? IrConst<*>)?.value else null
|
||||
}
|
||||
|
||||
override fun TypeConstructorMarker.getTypeParameterClassifier(): TypeParameterMarker? =
|
||||
this as? IrTypeParameterSymbol
|
||||
|
||||
override fun TypeConstructorMarker.isInlineClass(): Boolean =
|
||||
(this as? IrClassSymbol)?.owner?.isInline == true
|
||||
|
||||
override fun TypeParameterMarker.getRepresentativeUpperBound(): KotlinTypeMarker =
|
||||
(this as IrTypeParameterSymbol).owner.superTypes.firstOrNull {
|
||||
val irClass = it.classOrNull?.owner ?: return@firstOrNull false
|
||||
irClass.kind != ClassKind.INTERFACE && irClass.kind != ClassKind.ANNOTATION_CLASS
|
||||
} ?: owner.superTypes.first()
|
||||
|
||||
override fun KotlinTypeMarker.getSubstitutedUnderlyingType(): KotlinTypeMarker? {
|
||||
// Code in inlineClassesUtils.kt loads the property with the same name and takes its type. This should have the same effect.
|
||||
val irClass = (this as? IrType)?.classOrNull?.owner ?: return null
|
||||
return irClass.primaryConstructor?.valueParameters?.singleOrNull()?.type
|
||||
}
|
||||
|
||||
override fun TypeConstructorMarker.getPrimitiveType(): PrimitiveType? {
|
||||
// TODO: get rid of descriptor
|
||||
return KotlinBuiltIns.getPrimitiveType((this as IrClassifierSymbol).descriptor as ClassDescriptor)
|
||||
}
|
||||
|
||||
override fun TypeConstructorMarker.getPrimitiveArrayType(): PrimitiveType? {
|
||||
// TODO: get rid of descriptor
|
||||
return KotlinBuiltIns.getPrimitiveArrayType((this as IrClassifierSymbol).descriptor as ClassDescriptor)
|
||||
}
|
||||
|
||||
override fun TypeConstructorMarker.isUnderKotlinPackage(): Boolean {
|
||||
var declaration: IrDeclaration = (this as? IrClassifierSymbol)?.owner as? IrClass ?: return false
|
||||
while (true) {
|
||||
val parent = declaration.parent
|
||||
if (parent is IrPackageFragment) {
|
||||
return parent.fqName.startsWith(KotlinBuiltIns.BUILT_INS_PACKAGE_NAME)
|
||||
}
|
||||
declaration = parent as? IrDeclaration ?: return false
|
||||
}
|
||||
}
|
||||
|
||||
override fun TypeConstructorMarker.getClassFqNameUnsafe(): FqNameUnsafe? =
|
||||
(this as IrClassSymbol).owner.fqNameWhenAvailable?.toUnsafe()
|
||||
}
|
||||
|
||||
fun extractTypeParameters(klass: IrDeclarationParent): List<IrTypeParameter> {
|
||||
|
||||
@@ -304,6 +304,17 @@ val IrDeclarationWithName.fqNameWhenAvailable: FqName?
|
||||
|
||||
val IrDeclaration.parentAsClass get() = parent as IrClass
|
||||
|
||||
fun IrClass.isLocalClass(): Boolean {
|
||||
var current: IrDeclarationParent? = this
|
||||
while (current != null && current !is IrPackageFragment) {
|
||||
if (current is IrDeclarationWithVisibility && current.visibility == Visibilities.LOCAL)
|
||||
return true
|
||||
current = (current as? IrDeclaration)?.parent
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
tailrec fun IrElement.getPackageFragment(): IrPackageFragment? {
|
||||
if (this is IrPackageFragment) return this
|
||||
val vParent = (this as? IrDeclaration)?.parent
|
||||
|
||||
Reference in New Issue
Block a user