Fix loading class literal value void.class in reflection
#KT-27878 Fixed
This commit is contained in:
+29
@@ -0,0 +1,29 @@
|
||||
// WITH_REFLECT
|
||||
// TARGET_BACKEND: JVM
|
||||
// FILE: Anno.java
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Anno {
|
||||
Class<?> value() default void.class;
|
||||
}
|
||||
|
||||
// FILE: test.kt
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class C {
|
||||
@Anno
|
||||
fun f1() {}
|
||||
|
||||
@Anno(Void::class)
|
||||
fun f2() {}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals("[@Anno(value=void)]", C::f1.annotations.toString())
|
||||
assertEquals("[@Anno(value=class java.lang.Void)]", C::f2.annotations.toString())
|
||||
return "OK"
|
||||
}
|
||||
+9
-1
@@ -5,6 +5,14 @@ public class ClassObjectArrayInParam {
|
||||
Class<?>[] value();
|
||||
}
|
||||
|
||||
@Anno({ClassObjectArrayInParam.class, Nested.class, String.class, java.util.List.class, String[][].class, int[][].class})
|
||||
@Anno({
|
||||
ClassObjectArrayInParam.class,
|
||||
Nested.class,
|
||||
String.class,
|
||||
java.util.List.class,
|
||||
String[][].class,
|
||||
int[][].class,
|
||||
void.class
|
||||
})
|
||||
public static class Nested {}
|
||||
}
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ public open class ClassObjectArrayInParam {
|
||||
public final val value: kotlin.Array<kotlin.reflect.KClass<*>>
|
||||
}
|
||||
|
||||
@test.ClassObjectArrayInParam.Anno(value = {test.ClassObjectArrayInParam::class, test.ClassObjectArrayInParam.Nested::class, kotlin.String::class, kotlin.collections.MutableList::class, kotlin.Array<kotlin.Array<kotlin.String>>::class, kotlin.Array<kotlin.IntArray>::class}) public open class Nested {
|
||||
@test.ClassObjectArrayInParam.Anno(value = {test.ClassObjectArrayInParam::class, test.ClassObjectArrayInParam.Nested::class, kotlin.String::class, kotlin.collections.MutableList::class, kotlin.Array<kotlin.Array<kotlin.String>>::class, kotlin.Array<kotlin.IntArray>::class, kotlin.Unit::class}) public open class Nested {
|
||||
public constructor Nested()
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -18914,6 +18914,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/reflection/annotations/annotationsOnJavaMembers.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("classLiteralWithVoidDefault.kt")
|
||||
public void testClassLiteralWithVoidDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/annotations/classLiteralWithVoidDefault.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("findAnnotation.kt")
|
||||
public void testFindAnnotation() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/annotations/findAnnotation.kt");
|
||||
|
||||
+5
@@ -18914,6 +18914,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/reflection/annotations/annotationsOnJavaMembers.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("classLiteralWithVoidDefault.kt")
|
||||
public void testClassLiteralWithVoidDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/annotations/classLiteralWithVoidDefault.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("findAnnotation.kt")
|
||||
public void testFindAnnotation() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/annotations/findAnnotation.kt");
|
||||
|
||||
+5
@@ -18919,6 +18919,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/reflection/annotations/annotationsOnJavaMembers.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("classLiteralWithVoidDefault.kt")
|
||||
public void testClassLiteralWithVoidDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/annotations/classLiteralWithVoidDefault.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("findAnnotation.kt")
|
||||
public void testFindAnnotation() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/annotations/findAnnotation.kt");
|
||||
|
||||
+7
@@ -16,11 +16,13 @@
|
||||
|
||||
package kotlin.reflect.jvm.internal.components
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
|
||||
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.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.constants.ClassLiteralValue
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
||||
@@ -195,6 +197,11 @@ private object ReflectClassStructure {
|
||||
currentClass = currentClass.componentType
|
||||
}
|
||||
if (currentClass.isPrimitive) {
|
||||
if (currentClass == Void.TYPE) {
|
||||
// void.class is not representable in Kotlin, we approximate it by Unit::class
|
||||
return ClassLiteralValue(ClassId.topLevel(KotlinBuiltIns.FQ_NAMES.unit.toSafe()), dimensions)
|
||||
}
|
||||
|
||||
val primitiveType = JvmPrimitiveType.get(currentClass.name).primitiveType
|
||||
if (dimensions > 0) {
|
||||
return ClassLiteralValue(ClassId.topLevel(primitiveType.arrayTypeFqName), dimensions - 1)
|
||||
|
||||
Reference in New Issue
Block a user