Support annotations as annotation arguments in reflection, add test
A follow-up to 281acb8 where this was supported in the compiler
This commit is contained in:
+12
@@ -0,0 +1,12 @@
|
||||
// ALLOW_AST_ACCESS
|
||||
package test
|
||||
|
||||
enum class E { ENTRY }
|
||||
|
||||
annotation class StringOptions(vararg val option: String)
|
||||
annotation class EnumOption(val option: E)
|
||||
|
||||
annotation class OptionGroups(val o1: StringOptions, val o2: EnumOption)
|
||||
|
||||
OptionGroups(StringOptions("abc", "d", "ef"), EnumOption(E.ENTRY))
|
||||
public class AnnotationInAnnotationArguments
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package test
|
||||
|
||||
test.OptionGroups(o1 = test.StringOptions(option = {"abc", "d", "ef"}: kotlin.Array<out kotlin.String>): test.StringOptions, o2 = test.EnumOption(option = E.ENTRY: test.E): test.EnumOption) public final class AnnotationInAnnotationArguments {
|
||||
/*primary*/ public constructor AnnotationInAnnotationArguments()
|
||||
}
|
||||
|
||||
internal final enum class E : kotlin.Enum<test.E> {
|
||||
public enum entry ENTRY : test.E {
|
||||
/*primary*/ private constructor ENTRY()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: test.E): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
}
|
||||
|
||||
/*primary*/ private constructor E()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: test.E): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.E
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<test.E>
|
||||
}
|
||||
|
||||
internal final annotation class EnumOption : kotlin.Annotation {
|
||||
/*primary*/ public constructor EnumOption(/*0*/ option: test.E)
|
||||
internal final val option: test.E
|
||||
internal final fun <get-option>(): test.E
|
||||
}
|
||||
|
||||
internal final annotation class OptionGroups : kotlin.Annotation {
|
||||
/*primary*/ public constructor OptionGroups(/*0*/ o1: test.StringOptions, /*1*/ o2: test.EnumOption)
|
||||
internal final val o1: test.StringOptions
|
||||
internal final fun <get-o1>(): test.StringOptions
|
||||
internal final val o2: test.EnumOption
|
||||
internal final fun <get-o2>(): test.EnumOption
|
||||
}
|
||||
|
||||
internal final annotation class StringOptions : kotlin.Annotation {
|
||||
/*primary*/ public constructor StringOptions(/*0*/ vararg option: kotlin.String /*kotlin.Array<out kotlin.String>*/)
|
||||
internal final val option: kotlin.Array<out kotlin.String>
|
||||
internal final fun <get-option>(): kotlin.Array<out kotlin.String>
|
||||
}
|
||||
@@ -1900,6 +1900,12 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
|
||||
doTestCompiledKotlin(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("AnnotationInAnnotationArguments.kt")
|
||||
public void testAnnotationInAnnotationArguments() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/AnnotationInAnnotationArguments.kt");
|
||||
doTestCompiledKotlin(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("EnumArgumentWithCustomToString.kt")
|
||||
public void testEnumArgumentWithCustomToString() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/EnumArgumentWithCustomToString.kt");
|
||||
|
||||
+6
@@ -57,6 +57,12 @@ public class JvmRuntimeDescriptorLoaderTestGenerated extends AbstractJvmRuntimeD
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("AnnotationInAnnotationArguments.kt")
|
||||
public void testAnnotationInAnnotationArguments() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/AnnotationInAnnotationArguments.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("EnumArgumentWithCustomToString.kt")
|
||||
public void testEnumArgumentWithCustomToString() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/EnumArgumentWithCustomToString.kt");
|
||||
|
||||
+1
-1
@@ -62,7 +62,7 @@ public interface KotlinJvmBinaryClass {
|
||||
}
|
||||
|
||||
interface AnnotationArgumentVisitor {
|
||||
// TODO: annotations, java.lang.Class
|
||||
// TODO: class literals
|
||||
void visit(@Nullable Name name, @Nullable Object value);
|
||||
|
||||
void visitEnum(@NotNull Name name, @NotNull ClassId enumClassId, @NotNull Name enumEntryName);
|
||||
|
||||
+8
-7
@@ -182,25 +182,26 @@ private object ReflectClassStructure {
|
||||
val classId = (if (clazz.isEnum()) clazz else clazz.getEnclosingClass()).classId
|
||||
visitor.visitEnum(name, classId, Name.identifier((value as Enum<*>).name()))
|
||||
}
|
||||
clazz.isAnnotation() -> {
|
||||
// TODO: support values of annotation types
|
||||
throw UnsupportedOperationException("Values of annotation types are not yet supported in Kotlin reflection: $value")
|
||||
javaClass<Annotation>().isAssignableFrom(clazz) -> {
|
||||
val annotationClass = clazz.getInterfaces().single()
|
||||
val v = visitor.visitAnnotation(name, annotationClass.classId) ?: return
|
||||
processAnnotationArguments(v, value as Annotation, annotationClass)
|
||||
}
|
||||
clazz.isArray() -> {
|
||||
val elementVisitor = visitor.visitArray(name) ?: return
|
||||
val v = visitor.visitArray(name) ?: return
|
||||
val componentType = clazz.getComponentType()
|
||||
if (componentType.isEnum()) {
|
||||
val enumClassId = componentType.classId
|
||||
for (element in value as Array<*>) {
|
||||
elementVisitor.visitEnum(enumClassId, Name.identifier((element as Enum<*>).name()))
|
||||
v.visitEnum(enumClassId, Name.identifier((element as Enum<*>).name()))
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (element in value as Array<*>) {
|
||||
elementVisitor.visit(element)
|
||||
v.visit(element)
|
||||
}
|
||||
}
|
||||
elementVisitor.visitEnd()
|
||||
v.visitEnd()
|
||||
}
|
||||
else -> {
|
||||
throw UnsupportedOperationException("Unsupported annotation argument value ($clazz): $value")
|
||||
|
||||
@@ -55,6 +55,12 @@ public class ResolveByStubTestGenerated extends AbstractResolveByStubTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("AnnotationInAnnotationArguments.kt")
|
||||
public void testAnnotationInAnnotationArguments() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/AnnotationInAnnotationArguments.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("EnumArgumentWithCustomToString.kt")
|
||||
public void testEnumArgumentWithCustomToString() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/annotations/EnumArgumentWithCustomToString.kt");
|
||||
|
||||
Reference in New Issue
Block a user