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:
committed by
Alexander Udalov
parent
5e392a511f
commit
6c989bfd4b
+5
@@ -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");
|
||||
|
||||
+20
@@ -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|
|
||||
|
||||
}
|
||||
+11
@@ -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
|
||||
}
|
||||
+5
@@ -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");
|
||||
|
||||
Generated
+5
@@ -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");
|
||||
|
||||
+5
@@ -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");
|
||||
|
||||
Generated
+5
@@ -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");
|
||||
|
||||
+11
@@ -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) {
|
||||
|
||||
+6
@@ -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
|
||||
|
||||
+4
@@ -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)
|
||||
}
|
||||
|
||||
+5
@@ -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");
|
||||
|
||||
+2
@@ -64,6 +64,8 @@ interface KotlinJvmBinaryClass {
|
||||
|
||||
fun visitClassLiteral(value: ClassLiteralValue)
|
||||
|
||||
fun visitAnnotation(classId: ClassId): AnnotationArgumentVisitor?
|
||||
|
||||
fun visitEnd()
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+5
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user