diff --git a/compiler/testData/codegen/box/reflection/annotations/classLiteralWithVoidDefault.kt b/compiler/testData/codegen/box/reflection/annotations/classLiteralWithVoidDefault.kt new file mode 100644 index 00000000000..de85d4e6cbe --- /dev/null +++ b/compiler/testData/codegen/box/reflection/annotations/classLiteralWithVoidDefault.kt @@ -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" +} diff --git a/compiler/testData/loadJava/compiledJava/annotations/ClassObjectArrayInParam.java b/compiler/testData/loadJava/compiledJava/annotations/ClassObjectArrayInParam.java index 13c3dbf14a0..5a30bc50c0a 100644 --- a/compiler/testData/loadJava/compiledJava/annotations/ClassObjectArrayInParam.java +++ b/compiler/testData/loadJava/compiledJava/annotations/ClassObjectArrayInParam.java @@ -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 {} } diff --git a/compiler/testData/loadJava/compiledJava/annotations/ClassObjectArrayInParam.txt b/compiler/testData/loadJava/compiledJava/annotations/ClassObjectArrayInParam.txt index 003aaa84796..03526c73d0a 100644 --- a/compiler/testData/loadJava/compiledJava/annotations/ClassObjectArrayInParam.txt +++ b/compiler/testData/loadJava/compiledJava/annotations/ClassObjectArrayInParam.txt @@ -8,7 +8,7 @@ public open class ClassObjectArrayInParam { public final val value: kotlin.Array> } - @test.ClassObjectArrayInParam.Anno(value = {test.ClassObjectArrayInParam::class, test.ClassObjectArrayInParam.Nested::class, kotlin.String::class, kotlin.collections.MutableList::class, kotlin.Array>::class, kotlin.Array::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>::class, kotlin.Array::class, kotlin.Unit::class}) public open class Nested { public constructor Nested() } } diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index c6bc6ade710..29ed5603231 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -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"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 627cca2c805..ab296a3a137 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -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"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 7e872bc028a..cca6499a82a 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -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"); diff --git a/core/descriptors.runtime/src/kotlin/reflect/jvm/internal/components/ReflectKotlinClass.kt b/core/descriptors.runtime/src/kotlin/reflect/jvm/internal/components/ReflectKotlinClass.kt index 01a0dd862d9..491aec02d16 100644 --- a/core/descriptors.runtime/src/kotlin/reflect/jvm/internal/components/ReflectKotlinClass.kt +++ b/core/descriptors.runtime/src/kotlin/reflect/jvm/internal/components/ReflectKotlinClass.kt @@ -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)