Implement support for class literals as annotation arguments...

on deserialization and reflection
This commit is contained in:
Ilya Chernikov
2018-08-27 11:49:05 +03:00
parent 68da28edb9
commit fd0eb6ee34
14 changed files with 177 additions and 11 deletions
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.load.kotlin.header.ReadKotlinClassHeaderAnnotationVisitor
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
import java.lang.reflect.Constructor
import java.lang.reflect.Field
import java.lang.reflect.Method
@@ -183,9 +184,25 @@ private object ReflectClassStructure {
visitor.visitEnd()
}
private fun Class<*>.classLiteralId(): KotlinJvmBinaryClass.ClassLiteralId {
var currentClass = this
var nestedness = 0
while (currentClass.isArray) {
nestedness++
currentClass = currentClass.componentType
}
val classId =
if (!currentClass.isPrimitive) currentClass.classId
else ClassId.topLevel(JvmPrimitiveType.get(currentClass.name).primitiveType.typeFqName)
return KotlinJvmBinaryClass.ClassLiteralId(classId, nestedness)
}
private fun processAnnotationArgumentValue(visitor: KotlinJvmBinaryClass.AnnotationArgumentVisitor, name: Name, value: Any) {
val clazz = value::class.java
when {
clazz == Class::class.java -> {
visitor.visitClassLiteral(name, (value as Class<*>).classLiteralId())
}
clazz in TYPES_ELIGIBLE_FOR_SIMPLE_VISIT -> {
visitor.visit(name, value)
}
@@ -208,6 +225,11 @@ private object ReflectClassStructure {
v.visitEnum(enumClassId, Name.identifier((element as Enum<*>).name))
}
}
else if (componentType == Class::class.java) {
for (element in value as Array<*>) {
v.visitClassLiteral((element as Class<*>).classLiteralId())
}
}
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("ClassLiteralArguments.kt")
public void testClassLiteralArguments() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/annotations/ClassLiteralArguments.kt");
}
@TestMetadata("EnumArgumentWithCustomToString.kt")
public void testEnumArgumentWithCustomToString() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlin/annotations/EnumArgumentWithCustomToString.kt");