JVM IR: generate InnerClasses attribute for nested classes in annotation arguments

#KT-38853
This commit is contained in:
Alexander Udalov
2020-05-14 13:58:04 +02:00
parent 2793187bda
commit 77e479fda8
4 changed files with 23 additions and 9 deletions
@@ -241,8 +241,10 @@ abstract class AnnotationCodegen(
val callee = value.symbol.owner val callee = value.symbol.owner
when { when {
callee.parentAsClass.isAnnotationClass -> { callee.parentAsClass.isAnnotationClass -> {
val internalAnnName = typeMapper.mapType(callee.returnType).descriptor val annotationClassType = callee.returnType
val internalAnnName = typeMapper.mapType(annotationClassType).descriptor
val visitor = annotationVisitor.visitAnnotation(name, internalAnnName) val visitor = annotationVisitor.visitAnnotation(name, internalAnnName)
annotationClassType.classOrNull?.owner?.let(innerClassConsumer::addInnerClassInfoFromAnnotation)
genAnnotationArguments(value, visitor) genAnnotationArguments(value, visitor)
visitor.visitEnd() visitor.visitEnd()
} }
@@ -250,9 +252,10 @@ abstract class AnnotationCodegen(
} }
} }
is IrGetEnumValue -> { is IrGetEnumValue -> {
val enumClassInternalName = typeMapper.mapClass(value.symbol.owner.parentAsClass).descriptor val enumEntry = value.symbol.owner
val enumEntryName = value.symbol.owner.name val enumClass = enumEntry.parentAsClass
annotationVisitor.visitEnum(name, enumClassInternalName, enumEntryName.asString()) innerClassConsumer.addInnerClassInfoFromAnnotation(enumClass)
annotationVisitor.visitEnum(name, typeMapper.mapClass(enumClass).descriptor, enumEntry.name.asString())
} }
is IrVararg -> { // array constructor is IrVararg -> { // array constructor
val visitor = annotationVisitor.visitArray(name) val visitor = annotationVisitor.visitArray(name)
@@ -262,7 +265,9 @@ abstract class AnnotationCodegen(
visitor.visitEnd() visitor.visitEnd()
} }
is IrClassReference -> { is IrClassReference -> {
annotationVisitor.visit(name, typeMapper.mapType(value.classType)) val classType = value.classType
classType.classOrNull?.owner?.let(innerClassConsumer::addInnerClassInfoFromAnnotation)
annotationVisitor.visit(name, typeMapper.mapType(classType))
} }
is IrErrorExpression -> error("Don't know how to compile annotation value ${ir2string(value)}") is IrErrorExpression -> error("Don't know how to compile annotation value ${ir2string(value)}")
else -> error("Unsupported compile-time value ${ir2string(value)}") else -> error("Unsupported compile-time value ${ir2string(value)}")
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.lower.MultifileFacadeFileEntry import org.jetbrains.kotlin.backend.jvm.lower.MultifileFacadeFileEntry
import org.jetbrains.kotlin.backend.jvm.lower.buildAssertionsDisabledField import org.jetbrains.kotlin.backend.jvm.lower.buildAssertionsDisabledField
import org.jetbrains.kotlin.backend.jvm.lower.hasAssertionsDisabledField import org.jetbrains.kotlin.backend.jvm.lower.hasAssertionsDisabledField
import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.inline.* import org.jetbrains.kotlin.codegen.inline.*
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
@@ -93,6 +93,8 @@ abstract class ClassCodegen protected constructor(
) )
} }
private val innerClasses = linkedSetOf<IrClass>()
private var regeneratedObjectNameGenerators = mutableMapOf<String, NameGenerator>() private var regeneratedObjectNameGenerators = mutableMapOf<String, NameGenerator>()
fun getRegeneratedObjectNameGenerator(function: IrFunction): NameGenerator { fun getRegeneratedObjectNameGenerator(function: IrFunction): NameGenerator {
@@ -155,6 +157,9 @@ abstract class ClassCodegen protected constructor(
visitor.done() visitor.done()
jvmSignatureClashDetector.reportErrors(classOrigin) jvmSignatureClashDetector.reportErrors(classOrigin)
generateInnerClasses()
return reifiedTypeParametersUsages return reifiedTypeParametersUsages
} }
@@ -335,10 +340,16 @@ abstract class ClassCodegen protected constructor(
// See FileBasedKotlinClass.convertAnnotationVisitor // See FileBasedKotlinClass.convertAnnotationVisitor
generateSequence<IrDeclaration>(innerClass) { it.parent as? IrDeclaration }.takeWhile { !it.isTopLevelDeclaration }.forEach { generateSequence<IrDeclaration>(innerClass) { it.parent as? IrDeclaration }.takeWhile { !it.isTopLevelDeclaration }.forEach {
if (it is IrClass) { if (it is IrClass) {
writeInnerClass(it, typeMapper, context, visitor) innerClasses.add(it)
} }
} }
} }
private fun generateInnerClasses() {
for (klass in innerClasses) {
writeInnerClass(klass, typeMapper, context, visitor)
}
}
} }
private val IrClass.flags: Int private val IrClass.flags: Int
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// FILE: annotations.kt // FILE: annotations.kt
import kotlin.reflect.* import kotlin.reflect.*
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// FILE: 1.kt // FILE: 1.kt
import kotlin.reflect.* import kotlin.reflect.*