JVM_IR. Support type annotations

This commit is contained in:
Mikhael Bogdanov
2020-01-28 13:06:22 +01:00
parent e4258e528f
commit 6c07dbf351
14 changed files with 191 additions and 70 deletions
@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.types.FlexibleType;
import org.jetbrains.kotlin.types.FlexibleTypesKt; import org.jetbrains.kotlin.types.FlexibleTypesKt;
import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.TypeUtils; import org.jetbrains.kotlin.types.TypeUtils;
import org.jetbrains.kotlin.types.checker.SimpleClassicTypeSystemContext;
import org.jetbrains.org.objectweb.asm.*; import org.jetbrains.org.objectweb.asm.*;
import java.lang.annotation.*; import java.lang.annotation.*;
@@ -675,9 +676,9 @@ public abstract class AnnotationCodegen {
return; return;
} }
Iterable<TypePathInfo> infos = Iterable<TypePathInfo<AnnotationDescriptor>> infos =
new TypeAnnotationCollector().collectTypeAnnotations(type, TypeReference.METHOD_FORMAL_PARAMETER); new PsiTypeAnnotationCollector().collectTypeAnnotations(type);
for (TypePathInfo info : infos) { for (TypePathInfo<AnnotationDescriptor> info : infos) {
for (AnnotationDescriptor annotationDescriptor : info.getAnnotations()) { for (AnnotationDescriptor annotationDescriptor : info.getAnnotations()) {
genAnnotation(annotationDescriptor, info.getPath(), true); genAnnotation(annotationDescriptor, info.getPath(), true);
} }
@@ -5,26 +5,29 @@
package org.jetbrains.kotlin.codegen package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.load.kotlin.FileBasedKotlinClass import org.jetbrains.kotlin.load.kotlin.FileBasedKotlinClass
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
import org.jetbrains.kotlin.types.checker.SimpleClassicTypeSystemContext
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.model.TypeVariance
import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.TypePath import org.jetbrains.org.objectweb.asm.TypePath
class TypePathInfo( class TypePathInfo<T>(
val path: TypePath?, val path: TypePath?,
val annotations: List<AnnotationDescriptor> val annotations: List<T>
) )
private class State(val type: Int, val path: MutableList<String>) { private class State<T>(val path: MutableList<String>) {
val results = arrayListOf<TypePathInfo>() val results = arrayListOf<TypePathInfo<T>>()
fun addStep(step: String) { fun addStep(step: String) {
@@ -35,56 +38,69 @@ private class State(val type: Int, val path: MutableList<String>) {
path.removeAt(path.lastIndex) path.removeAt(path.lastIndex)
} }
fun rememberAnnotations(annotations: List<AnnotationDescriptor>) { fun rememberAnnotations(annotations: List<T>) {
results.add(TypePathInfo(TypePath.fromString(path.joinToString("")), annotations)) results.add(TypePathInfo(TypePath.fromString(path.joinToString("")), annotations))
} }
} }
class TypeAnnotationCollector { class PsiTypeAnnotationCollector : TypeAnnotationCollector<AnnotationDescriptor>(SimpleClassicTypeSystemContext) {
private lateinit var state: State override fun KotlinTypeMarker.extractAnnotations(): List<AnnotationDescriptor> {
require(this is KotlinType)
return annotations.filter {
//We only generate annotations which have the TYPE_USE Java target.
// Those are type annotations which were compiled with JVM target bytecode version 1.8 or greater
isCompiledToJvm8OrHigher(it.annotationClass)
}
}
}
fun collectTypeAnnotations(kotlinType: KotlinType, annotationType: Int): ArrayList<TypePathInfo> { abstract class TypeAnnotationCollector<T>(val context: TypeSystemCommonBackendContext) {
state = State(annotationType, arrayListOf())
kotlinType.collectTypeAnnotations() private lateinit var state: State<T>
fun collectTypeAnnotations(kotlinType: KotlinTypeMarker): ArrayList<TypePathInfo<T>> {
state = State(arrayListOf())
kotlinType.gatherTypeAnnotations()
return state.results return state.results
} }
private fun KotlinType.collectTypeAnnotations() { private fun KotlinTypeMarker.gatherTypeAnnotations() {
if (isFlexible()) { with(context) {
return upperIfFlexible().collectTypeAnnotations() if (isFlexible()) {
} else if ((this.constructor.declarationDescriptor as? ClassDescriptor)?.isInner == true) { return upperBoundIfFlexible().gatherTypeAnnotations()
//skip inner classes for now it's not clear should type annotations on outer be supported or not } else if (typeConstructor().isInnerClass()) {
return //skip inner classes for now it's not clear should type annotations on outer be supported or not
} return
}
typeAnnotations.takeIf { it.isNotEmpty() }?.let { state.rememberAnnotations(it) } extractAnnotations().takeIf { it.isNotEmpty() }?.let { state.rememberAnnotations(it) }
arguments.forEachIndexed { index, type -> for (index in 0 until argumentsCount()) {
//skip in/out variance for now it's not clear should type annotations on wildcard bound be supported or not val type = getArgument(index)
if (type.projectionKind == Variance.INVARIANT) { //skip in/out variance for now it's not clear should type annotations on wildcard bound be supported or not
when { if (type.getVariance() == TypeVariance.INV) {
KotlinBuiltIns.isArray(this) -> type.type.process("[") when {
else -> type.type.process("$index;") this@gatherTypeAnnotations.isArrayOrNullableArray() -> type.getType().process("[")
else -> type.getType().process("$index;")
}
} }
} }
} }
} }
fun KotlinType.process(step: String) { fun KotlinTypeMarker.process(step: String) {
state.addStep(step) state.addStep(step)
this.collectTypeAnnotations() this.gatherTypeAnnotations()
state.removeStep(step) state.removeStep(step)
} }
private val KotlinType.typeAnnotations abstract fun KotlinTypeMarker.extractAnnotations(): List<T>
get() = annotations.filter {
//We only generate annotations which have the TYPE_USE Java target. fun isCompiledToJvm8OrHigher(descriptor: ClassDescriptor?): Boolean =
// Those are type annotations which were compiled with JVM target bytecode version 1.8 or greater (descriptor as? DeserializedClassDescriptor)?.let { classDescriptor ->
(it.annotationClass as? DeserializedClassDescriptor)?.let { classDescriptor -> ((classDescriptor.source as? KotlinJvmBinarySourceElement)?.binaryClass as? FileBasedKotlinClass)?.classVersion ?: 0 >= Opcodes.V1_8
((classDescriptor.source as? KotlinJvmBinarySourceElement)?.binaryClass as? FileBasedKotlinClass)?.classVersion ?: 0 >= Opcodes.V1_8 } ?: true
} ?: true
}
} }
@@ -461,6 +461,10 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
return toFirRegularClass()?.isInline == true return toFirRegularClass()?.isInline == true
} }
override fun TypeConstructorMarker.isInnerClass(): Boolean {
return toFirRegularClass()?.isInner == true
}
override fun TypeParameterMarker.getRepresentativeUpperBound(): KotlinTypeMarker { override fun TypeParameterMarker.getRepresentativeUpperBound(): KotlinTypeMarker {
require(this is FirTypeParameterSymbol) require(this is FirTypeParameterSymbol)
return this.fir.bounds.getOrNull(0)?.let { (it as? FirResolvedTypeRef)?.type } return this.fir.bounds.getOrNull(0)?.let { (it as? FirResolvedTypeRef)?.type }
@@ -23,6 +23,10 @@ import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.TypeAnnotationCollector
import org.jetbrains.kotlin.codegen.TypePathInfo
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.JvmTarget.JVM_1_6
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
@@ -33,18 +37,21 @@ import org.jetbrains.kotlin.ir.types.classifierOrNull
import org.jetbrains.kotlin.ir.types.isMarkedNullable import org.jetbrains.kotlin.ir.types.isMarkedNullable
import org.jetbrains.kotlin.ir.types.isNullable import org.jetbrains.kotlin.ir.types.isNullable
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.load.kotlin.FileBasedKotlinClass
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
import org.jetbrains.kotlin.synthetic.isVisibleOutside import org.jetbrains.kotlin.synthetic.isVisibleOutside
import org.jetbrains.org.objectweb.asm.AnnotationVisitor import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.org.objectweb.asm.*
import java.lang.annotation.RetentionPolicy import java.lang.annotation.RetentionPolicy
class AnnotationCodegen( abstract class AnnotationCodegen(
private val innerClassConsumer: InnerClassConsumer, private val innerClassConsumer: InnerClassConsumer,
context: JvmBackendContext, private val context: JvmBackendContext
private val visitAnnotation: (descriptor: String, visible: Boolean) -> AnnotationVisitor
) { ) {
private val typeMapper = context.typeMapper private val typeMapper = context.typeMapper
private val methodSignatureMapper = context.methodSignatureMapper private val methodSignatureMapper = context.methodSignatureMapper
@@ -52,7 +59,7 @@ class AnnotationCodegen(
/** /**
* @param returnType can be null if not applicable (e.g. [annotated] is a class) * @param returnType can be null if not applicable (e.g. [annotated] is a class)
*/ */
fun genAnnotations(annotated: IrAnnotationContainer?, returnType: Type?) { fun genAnnotations(annotated: IrAnnotationContainer?, returnType: Type?, typeForTypeAnnotations: IrType?) {
if (annotated == null) return if (annotated == null) return
val annotationDescriptorsAlreadyPresent = mutableSetOf<String>() val annotationDescriptorsAlreadyPresent = mutableSetOf<String>()
@@ -84,14 +91,26 @@ class AnnotationCodegen(
} }
} }
genAnnotation(annotation)?.let { descriptor -> genAnnotation(annotation, null, false)?.let { descriptor ->
annotationDescriptorsAlreadyPresent.add(descriptor) annotationDescriptorsAlreadyPresent.add(descriptor)
} }
} }
generateAdditionalAnnotations(annotated, returnType, annotationDescriptorsAlreadyPresent) generateAdditionalAnnotations(annotated, returnType, annotationDescriptorsAlreadyPresent)
generateTypeAnnotations(annotated, typeForTypeAnnotations)
} }
abstract fun visitAnnotation(descr: String?, visible: Boolean): AnnotationVisitor
open fun visitTypeAnnotation(
descr: String?,
path: TypePath?,
visible: Boolean,
): AnnotationVisitor {
throw RuntimeException("Not implemented")
}
private fun generateAdditionalAnnotations( private fun generateAdditionalAnnotations(
annotated: IrAnnotationContainer, annotated: IrAnnotationContainer,
returnType: Type?, returnType: Type?,
@@ -152,7 +171,7 @@ class AnnotationCodegen(
visitor.visitEnd() visitor.visitEnd()
} }
private fun genAnnotation(annotation: IrConstructorCall): String? { private fun genAnnotation(annotation: IrConstructorCall, path: TypePath?, isTypeAnnotation: Boolean): String? {
val annotationClass = annotation.annotationClass val annotationClass = annotation.annotationClass
val retentionPolicy = getRetentionPolicy(annotationClass) val retentionPolicy = getRetentionPolicy(annotationClass)
if (retentionPolicy == RetentionPolicy.SOURCE) return null if (retentionPolicy == RetentionPolicy.SOURCE) return null
@@ -167,7 +186,9 @@ class AnnotationCodegen(
innerClassConsumer.addInnerClassInfoFromAnnotation(annotationClass) innerClassConsumer.addInnerClassInfoFromAnnotation(annotationClass)
val asmTypeDescriptor = typeMapper.mapType(annotation.type).descriptor val asmTypeDescriptor = typeMapper.mapType(annotation.type).descriptor
val annotationVisitor = visitAnnotation(asmTypeDescriptor, retentionPolicy == RetentionPolicy.RUNTIME) val annotationVisitor =
if (!isTypeAnnotation) visitAnnotation(asmTypeDescriptor, retentionPolicy == RetentionPolicy.RUNTIME) else
visitTypeAnnotation(asmTypeDescriptor, path, retentionPolicy == RetentionPolicy.RUNTIME)
genAnnotationArguments(annotation, annotationVisitor) genAnnotationArguments(annotation, annotationVisitor)
annotationVisitor.visitEnd() annotationVisitor.visitEnd()
@@ -281,6 +302,40 @@ class AnnotationCodegen(
val IrConstructorCall.annotationClass get() = symbol.owner.parentAsClass val IrConstructorCall.annotationClass get() = symbol.owner.parentAsClass
} }
private fun generateTypeAnnotations(
annotated: IrAnnotationContainer,
type: IrType?
) {
if ((annotated as? IrDeclaration)?.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR ||
type == null || context.state.target === JVM_1_6 ||
!context.state.configuration.getBoolean(JVMConfigurationKeys.EMIT_JVM_TYPE_ANNOTATIONS)
) {
return
}
val infos: Iterable<TypePathInfo<IrConstructorCall>> =
IrTypeAnnotationCollector(context.typeMapper.typeSystem).collectTypeAnnotations(type)
for (info in infos) {
for (annotation in info.annotations) {
genAnnotation(annotation, info.path, true)
}
}
}
private class IrTypeAnnotationCollector(context: TypeSystemCommonBackendContext) : TypeAnnotationCollector<IrConstructorCall>(context) {
override fun KotlinTypeMarker.extractAnnotations(): List<IrConstructorCall> {
require(this is IrType)
return annotations.filter {
//We only generate annotations which have the TYPE_USE Java target.
// Those are type annotations which were compiled with JVM target bytecode version 1.8 or greater
(it.annotationClass.origin != IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB &&
it.annotationClass.origin != IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB) ||
isCompiledToJvm8OrHigher(it.annotationClass.descriptor)
}
}
}
} }
interface InnerClassConsumer { interface InnerClassConsumer {
@@ -45,8 +45,7 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmClassSignature import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmClassSignature
import org.jetbrains.kotlin.serialization.DescriptorSerializer import org.jetbrains.kotlin.serialization.DescriptorSerializer
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.*
import org.jetbrains.org.objectweb.asm.Type
import java.io.File import java.io.File
open class ClassCodegen protected constructor( open class ClassCodegen protected constructor(
@@ -125,7 +124,15 @@ open class ClassCodegen protected constructor(
signature.superclassName, signature.superclassName,
signature.interfaces.toTypedArray() signature.interfaces.toTypedArray()
) )
AnnotationCodegen(this, context, visitor.visitor::visitAnnotation).genAnnotations(irClass, null) object : AnnotationCodegen(this@ClassCodegen, context) {
override fun visitAnnotation(descr: String?, visible: Boolean): AnnotationVisitor {
return visitor.visitor.visitAnnotation(descr, visible)
}
}.genAnnotations(
irClass,
null,
null
)
val nestedClasses = irClass.declarations.mapNotNull { declaration -> val nestedClasses = irClass.declarations.mapNotNull { declaration ->
if (declaration is IrClass) { if (declaration is IrClass) {
@@ -328,7 +335,15 @@ open class ClassCodegen protected constructor(
fieldSignature, (field.initializer?.expression as? IrConst<*>)?.value fieldSignature, (field.initializer?.expression as? IrConst<*>)?.value
) )
AnnotationCodegen(this, context, fv::visitAnnotation).genAnnotations(field, fieldType) object : AnnotationCodegen(this@ClassCodegen, context) {
override fun visitAnnotation(descr: String?, visible: Boolean): AnnotationVisitor {
return fv.visitAnnotation(descr, visible)
}
override fun visitTypeAnnotation(descr: String?, path: TypePath?, visible: Boolean): AnnotationVisitor {
return fv.visitTypeAnnotation(TypeReference.newTypeReference(TypeReference.FIELD).value,path, descr, visible)
}
}.genAnnotations(field, fieldType, field.type)
val descriptor = field.metadata?.descriptor val descriptor = field.metadata?.descriptor
if (descriptor != null) { if (descriptor != null) {
@@ -34,14 +34,13 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.kotlin.utils.sure import org.jetbrains.kotlin.utils.sure
import org.jetbrains.org.objectweb.asm.MethodVisitor import org.jetbrains.org.objectweb.asm.*
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
open class FunctionCodegen( open class FunctionCodegen(
private val irFunction: IrFunction, private val irFunction: IrFunction,
private val classCodegen: ClassCodegen, private val classCodegen: ClassCodegen,
private val inlinedInto: ExpressionCodegen? = null private val inlinedInto: ExpressionCodegen? = null,
) { ) {
val context = classCodegen.context val context = classCodegen.context
val state = classCodegen.state val state = classCodegen.state
@@ -65,9 +64,20 @@ open class FunctionCodegen(
} }
if (irFunction.origin != IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER) { if (irFunction.origin != IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER) {
AnnotationCodegen(classCodegen, context, methodVisitor::visitAnnotation).genAnnotations( object : AnnotationCodegen(classCodegen, context) {
override fun visitAnnotation(descr: String?, visible: Boolean): AnnotationVisitor {
return methodVisitor.visitAnnotation(descr, visible)
}
override fun visitTypeAnnotation(descr: String?, path: TypePath?, visible: Boolean): AnnotationVisitor {
return methodVisitor.visitTypeAnnotation(
TypeReference.newTypeReference(TypeReference.METHOD_RETURN).value, path, descr, visible
)
}
}.genAnnotations(
functionView, functionView,
signature.asmMethod.returnType signature.asmMethod.returnType,
irFunction.returnType
) )
// Not generating parameter annotations for default stubs fixes KT-7892, though // Not generating parameter annotations for default stubs fixes KT-7892, though
// this certainly looks like a workaround for a javac bug. // this certainly looks like a workaround for a javac bug.
@@ -216,7 +226,14 @@ open class FunctionCodegen(
private fun generateAnnotationDefaultValueIfNeeded(methodVisitor: MethodVisitor) { private fun generateAnnotationDefaultValueIfNeeded(methodVisitor: MethodVisitor) {
getAnnotationDefaultValueExpression()?.let { defaultValueExpression -> getAnnotationDefaultValueExpression()?.let { defaultValueExpression ->
val annotationCodegen = AnnotationCodegen(classCodegen, context) { _, _ -> methodVisitor.visitAnnotationDefault() } val annotationCodegen = object: AnnotationCodegen(
classCodegen,
context
) {
override fun visitAnnotation(descr: String?, visible: Boolean): AnnotationVisitor {
return methodVisitor.visitAnnotationDefault()
}
}
annotationCodegen.generateAnnotationDefaultValue(defaultValueExpression) annotationCodegen.generateAnnotationDefaultValue(defaultValueExpression)
} }
} }
@@ -282,13 +299,22 @@ private fun generateParameterAnnotations(
} }
if (!kind.isSkippedInGenericSignature) { if (!kind.isSkippedInGenericSignature) {
AnnotationCodegen(innerClassConsumer, context) { descriptor, visible -> object : AnnotationCodegen(innerClassConsumer, context) {
mv.visitParameterAnnotation( override fun visitAnnotation(descr: String?, visible: Boolean): AnnotationVisitor {
i - syntheticParameterCount, return mv.visitParameterAnnotation(
descriptor, i - syntheticParameterCount,
visible descr,
) visible
}.genAnnotations(annotated, parameterSignature.asmType) )
}
override fun visitTypeAnnotation(descr: String?, path: TypePath?, visible: Boolean): AnnotationVisitor {
return mv.visitTypeAnnotation(
TypeReference.newFormalParameterReference(i - syntheticParameterCount).value,
path, descr, visible
)
}
}.genAnnotations(annotated, parameterSignature.asmType, annotated?.type)
} }
} }
} }
@@ -310,6 +310,9 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
override fun TypeConstructorMarker.isInlineClass(): Boolean = override fun TypeConstructorMarker.isInlineClass(): Boolean =
(this as? IrClassSymbol)?.owner?.isInline == true (this as? IrClassSymbol)?.owner?.isInline == true
override fun TypeConstructorMarker.isInnerClass(): Boolean =
(this as? IrClassSymbol)?.owner?.isInner == true
override fun TypeParameterMarker.getRepresentativeUpperBound(): KotlinTypeMarker = override fun TypeParameterMarker.getRepresentativeUpperBound(): KotlinTypeMarker =
(this as IrTypeParameterSymbol).owner.superTypes.firstOrNull { (this as IrTypeParameterSymbol).owner.superTypes.firstOrNull {
val irClass = it.classOrNull?.owner ?: return@firstOrNull false val irClass = it.classOrNull?.owner ?: return@firstOrNull false
@@ -1,7 +1,6 @@
// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS // KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// IGNORE_BACKEND_FIR: JVM_IR // IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM_IR
// JVM_TARGET: 1.8 // JVM_TARGET: 1.8
// WITH_REFLECT // WITH_REFLECT
// FULL_JDK // FULL_JDK
@@ -1,7 +1,6 @@
// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS // KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// IGNORE_BACKEND_FIR: JVM_IR // IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM_IR
// JVM_TARGET: 1.8 // JVM_TARGET: 1.8
// WITH_REFLECT // WITH_REFLECT
// FULL_JDK // FULL_JDK
@@ -1,7 +1,6 @@
// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS // KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// IGNORE_BACKEND_FIR: JVM_IR // IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM_IR
// JVM_TARGET: 1.8 // JVM_TARGET: 1.8
// WITH_REFLECT // WITH_REFLECT
// FULL_JDK // FULL_JDK
@@ -1,7 +1,6 @@
// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS // KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// IGNORE_BACKEND_FIR: JVM_IR // IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM_IR
// JVM_TARGET: 1.8 // JVM_TARGET: 1.8
// WITH_REFLECT // WITH_REFLECT
// FULL_JDK // FULL_JDK
@@ -1,7 +1,6 @@
// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS // KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS
// TARGET_BACKEND: JVM // TARGET_BACKEND: JVM
// IGNORE_BACKEND_FIR: JVM_IR // IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM_IR
// JVM_TARGET: 1.8 // JVM_TARGET: 1.8
// WITH_REFLECT // WITH_REFLECT
// FULL_JDK // FULL_JDK
@@ -32,6 +32,7 @@ interface TypeSystemCommonBackendContext : TypeSystemContext {
fun TypeConstructorMarker.getTypeParameterClassifier(): TypeParameterMarker? fun TypeConstructorMarker.getTypeParameterClassifier(): TypeParameterMarker?
fun TypeConstructorMarker.isInlineClass(): Boolean fun TypeConstructorMarker.isInlineClass(): Boolean
fun TypeConstructorMarker.isInnerClass(): Boolean
fun TypeParameterMarker.getRepresentativeUpperBound(): KotlinTypeMarker fun TypeParameterMarker.getRepresentativeUpperBound(): KotlinTypeMarker
fun KotlinTypeMarker.getSubstitutedUnderlyingType(): KotlinTypeMarker? fun KotlinTypeMarker.getSubstitutedUnderlyingType(): KotlinTypeMarker?
@@ -556,6 +556,11 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
return (declarationDescriptor as? ClassDescriptor)?.isInline == true return (declarationDescriptor as? ClassDescriptor)?.isInline == true
} }
override fun TypeConstructorMarker.isInnerClass(): Boolean {
require(this is TypeConstructor, this::errorMessage)
return (declarationDescriptor as? ClassDescriptor)?.isInner == true
}
override fun TypeParameterMarker.getRepresentativeUpperBound(): KotlinTypeMarker { override fun TypeParameterMarker.getRepresentativeUpperBound(): KotlinTypeMarker {
require(this is TypeParameterDescriptor, this::errorMessage) require(this is TypeParameterDescriptor, this::errorMessage)
return representativeUpperBound return representativeUpperBound