Support array of annotation in KotlinJvmBinaryClass

KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor didn't cover the
case when the element type is an Annotation. Therefore, when the
compiler read an array of annotations from JVM binary classes built from
Kotlin sources, it got an empty array regardless of what was written in
the bytecode.

For example, Foo.value below is read as an empty array when SomeClass
resides in another Kotlin module.

  @Foo(
    value = [Bar(1), Bar(2)]
  )
  class SomeClass
This commit is contained in:
Ting-Yuan Huang
2021-03-25 22:34:47 -07:00
committed by Alexander Udalov
parent 5e392a511f
commit 6c989bfd4b
17 changed files with 133 additions and 0 deletions
@@ -56,6 +56,11 @@ public class FirLoadCompiledKotlinGenerated extends AbstractFirLoadCompiledKotli
runTest("compiler/testData/loadJava/compiledKotlin/annotations/AnnotationInAnnotationArguments.kt");
}
@TestMetadata("AnnotationInArray.kt")
public void testAnnotationInArray() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/annotations/AnnotationInArray.kt");
}
@TestMetadata("ClassLiteralArguments.kt")
public void testClassLiteralArguments() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/annotations/ClassLiteralArguments.kt");
@@ -0,0 +1,20 @@
public final annotation class Anno : R|kotlin/Annotation| {
public final val value: R|kotlin/Array<test/Bnno>|
public get(): R|kotlin/Array<test/Bnno>|
public constructor(value: R|kotlin/Array<test/Bnno>|): R|test/Anno|
}
@R|test/Anno|(value = <implicitArrayOf>(@R|test/Bnno|(value = String(x)) , @R|test/Bnno|(value = String(y)) )) public final class AnnotationInArray : R|kotlin/Any| {
public constructor(): R|test/AnnotationInArray|
}
public final annotation class Bnno : R|kotlin/Annotation| {
public final val value: R|kotlin/String|
public get(): R|kotlin/String|
public constructor(value: R|kotlin/String|): R|test/Bnno|
}
@@ -108,6 +108,17 @@ internal class AnnotationsLoader(private val session: FirSession) {
)
}
override fun visitAnnotation(classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
val list = mutableListOf<FirAnnotationCall>()
val visitor = loadAnnotation(classId, list)
return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor by visitor {
override fun visitEnd() {
visitor.visitEnd()
elements.add(list.single())
}
}
}
override fun visitEnd() {
argumentMap[name] = buildArrayOfCall {
argumentList = buildArgumentList {
@@ -200,6 +200,12 @@ public abstract class FileBasedKotlinClass implements KotlinJvmBinaryClass {
arv.visitEnum(resolveNameByDesc(desc, innerClasses), Name.identifier(value));
}
@Override
public org.jetbrains.org.objectweb.asm.AnnotationVisitor visitAnnotation(String name, @NotNull String desc) {
AnnotationArgumentVisitor aav = arv.visitAnnotation(resolveNameByDesc(desc, innerClasses));
return aav == null ? null : convertAnnotationVisitor(aav, innerClasses);
}
@Override
public void visitEnd() {
arv.visitEnd();
@@ -0,0 +1,16 @@
// ALLOW_AST_ACCESS
package test
annotation class Anno(
val value: Array<Bnno>
)
annotation class Bnno(
val value: String
)
@Anno(
value = [Bnno("x"), Bnno("y")]
)
public class AnnotationInArray
@@ -0,0 +1,17 @@
package test
public final annotation class Anno : kotlin.Annotation {
/*primary*/ public constructor Anno(/*0*/ value: kotlin.Array<test.Bnno>)
public final val value: kotlin.Array<test.Bnno>
public final fun <get-value>(): kotlin.Array<test.Bnno>
}
@test.Anno(value = {test.Bnno(value = "x"), test.Bnno(value = "y")}) public final class AnnotationInArray {
/*primary*/ public constructor AnnotationInArray()
}
public final annotation class Bnno : kotlin.Annotation {
/*primary*/ public constructor Bnno(/*0*/ value: kotlin.String)
public final val value: kotlin.String
public final fun <get-value>(): kotlin.String
}
@@ -1734,6 +1734,11 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
runTest("compiler/testData/loadJava/compiledKotlin/annotations/AnnotationInAnnotationArguments.kt");
}
@TestMetadata("AnnotationInArray.kt")
public void testAnnotationInArray() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/annotations/AnnotationInArray.kt");
}
@TestMetadata("ClassLiteralArguments.kt")
public void testClassLiteralArguments() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/annotations/ClassLiteralArguments.kt");
@@ -56,6 +56,11 @@ public class LoadKotlinWithTypeTableTestGenerated extends AbstractLoadKotlinWith
runTest("compiler/testData/loadJava/compiledKotlin/annotations/AnnotationInAnnotationArguments.kt");
}
@TestMetadata("AnnotationInArray.kt")
public void testAnnotationInArray() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/annotations/AnnotationInArray.kt");
}
@TestMetadata("ClassLiteralArguments.kt")
public void testClassLiteralArguments() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/annotations/ClassLiteralArguments.kt");
@@ -1735,6 +1735,11 @@ public class IrLoadJavaTestGenerated extends AbstractIrLoadJavaTest {
runTest("compiler/testData/loadJava/compiledKotlin/annotations/AnnotationInAnnotationArguments.kt");
}
@TestMetadata("AnnotationInArray.kt")
public void testAnnotationInArray() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/annotations/AnnotationInArray.kt");
}
@TestMetadata("ClassLiteralArguments.kt")
public void testClassLiteralArguments() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/annotations/ClassLiteralArguments.kt");
@@ -1734,6 +1734,11 @@ public class LoadJavaUsingJavacTestGenerated extends AbstractLoadJavaUsingJavacT
runTest("compiler/testData/loadJava/compiledKotlin/annotations/AnnotationInAnnotationArguments.kt");
}
@TestMetadata("AnnotationInArray.kt")
public void testAnnotationInArray() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/annotations/AnnotationInArray.kt");
}
@TestMetadata("ClassLiteralArguments.kt")
public void testClassLiteralArguments() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/annotations/ClassLiteralArguments.kt");
@@ -111,6 +111,17 @@ class BinaryClassAnnotationAndConstantLoaderImpl(
elements.add(KClassValue(value))
}
override fun visitAnnotation(classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
val list = ArrayList<AnnotationDescriptor>()
val visitor = loadAnnotation(classId, SourceElement.NO_SOURCE, list)!!
return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor by visitor {
override fun visitEnd() {
visitor.visitEnd()
elements.add(AnnotationValue(list.single()))
}
}
}
override fun visitEnd() {
val parameter = DescriptorResolverUtils.getAnnotationParameterByName(name, annotationClass)
if (parameter != null) {
@@ -293,6 +293,12 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
public void visitClassLiteral(@NotNull ClassLiteralValue classLiteralValue) {
}
@Nullable
@Override
public AnnotationArgumentVisitor visitAnnotation(@NotNull ClassId classId) {
return null;
}
@Override
public void visitEnd() {
//noinspection SSBasedInspection
@@ -243,6 +243,10 @@ private object ReflectClassStructure {
componentType == Class::class.java -> for (element in value as Array<*>) {
v.visitClassLiteral((element as Class<*>).classLiteralValue())
}
Annotation::class.java.isAssignableFrom(componentType) -> for (element in value as Array<*>) {
val vv = v.visitAnnotation(componentType.classId) ?: continue
processAnnotationArguments(vv, element as Annotation, componentType)
}
else -> for (element in value as Array<*>) {
v.visit(element)
}
@@ -58,6 +58,11 @@ public class JvmRuntimeDescriptorLoaderTestGenerated extends AbstractJvmRuntimeD
runTest("compiler/testData/loadJava/compiledKotlin/annotations/AnnotationInAnnotationArguments.kt");
}
@TestMetadata("AnnotationInArray.kt")
public void testAnnotationInArray() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/annotations/AnnotationInArray.kt");
}
@TestMetadata("ClassLiteralArguments.kt")
public void testClassLiteralArguments() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/annotations/ClassLiteralArguments.kt");
@@ -64,6 +64,8 @@ interface KotlinJvmBinaryClass {
fun visitClassLiteral(value: ClassLiteralValue)
fun visitAnnotation(classId: ClassId): AnnotationArgumentVisitor?
fun visitEnd()
}
}
@@ -56,6 +56,11 @@ public class LoadJavaClsStubTestGenerated extends AbstractLoadJavaClsStubTest {
runTest("compiler/testData/loadJava/compiledKotlin/annotations/AnnotationInAnnotationArguments.kt");
}
@TestMetadata("AnnotationInArray.kt")
public void testAnnotationInArray() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/annotations/AnnotationInArray.kt");
}
@TestMetadata("ClassLiteralArguments.kt")
public void testClassLiteralArguments() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/annotations/ClassLiteralArguments.kt");
@@ -56,6 +56,11 @@ public class ResolveByStubTestGenerated extends AbstractResolveByStubTest {
runTest("compiler/testData/loadJava/compiledKotlin/annotations/AnnotationInAnnotationArguments.kt");
}
@TestMetadata("AnnotationInArray.kt")
public void testAnnotationInArray() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/annotations/AnnotationInArray.kt");
}
@TestMetadata("ClassLiteralArguments.kt")
public void testClassLiteralArguments() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/annotations/ClassLiteralArguments.kt");