diff --git a/compiler/testData/codegen/box/classLiteral/java/javaPrimitiveType.kt b/compiler/testData/codegen/box/classLiteral/java/javaPrimitiveType.kt index c413aee39c2..b9d1e2c4630 100644 --- a/compiler/testData/codegen/box/classLiteral/java/javaPrimitiveType.kt +++ b/compiler/testData/codegen/box/classLiteral/java/javaPrimitiveType.kt @@ -50,14 +50,15 @@ fun box(): String { check(Double::class.javaPrimitiveType, "double") check(Double::class, "double") + check(Void::class.javaPrimitiveType, "void") + check(Void::class, "void") + checkNull(String::class.javaPrimitiveType) checkNull(String::class) - checkNull(Nothing::class.javaPrimitiveType) - checkNull(Nothing::class) - - checkNull(Void::class.javaPrimitiveType) - checkNull(Void::class) + // TODO: KT-15518 + check(Nothing::class.javaPrimitiveType, "void") + check(Nothing::class, "void") return "OK" } diff --git a/compiler/testData/codegen/box/classLiteral/java/javaPrimitiveTypeReified.kt b/compiler/testData/codegen/box/classLiteral/java/javaPrimitiveTypeReified.kt index c9b71561637..8ee0447e02f 100644 --- a/compiler/testData/codegen/box/classLiteral/java/javaPrimitiveTypeReified.kt +++ b/compiler/testData/codegen/box/classLiteral/java/javaPrimitiveTypeReified.kt @@ -26,9 +26,9 @@ fun box(): String { check("float") check("long") check("double") + check("void") checkNull() - checkNull() return "OK" } diff --git a/compiler/testData/codegen/box/reflection/classes/javaVoid.kt b/compiler/testData/codegen/box/reflection/classes/javaVoid.kt new file mode 100644 index 00000000000..f0212d92b69 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/classes/javaVoid.kt @@ -0,0 +1,17 @@ +// IGNORE_BACKEND: JS, NATIVE +// WITH_REFLECT + +import kotlin.reflect.KClass +import kotlin.test.assertEquals + +fun box(): String { + assertEquals(Void::class, Void.TYPE.kotlin) + assertEquals(Void.TYPE.kotlin, Void::class) + + assertEquals(Void.TYPE, Void::class.javaPrimitiveType) + assertEquals(Void::class.java, Void::class.javaObjectType) + assertEquals(Void.TYPE, Void.TYPE.kotlin.javaPrimitiveType) + assertEquals(Void::class.java, Void.TYPE.kotlin.javaObjectType) + + return "OK" +} diff --git a/compiler/testData/codegen/box/reflection/noReflectAtRuntime/javaVoid.kt b/compiler/testData/codegen/box/reflection/noReflectAtRuntime/javaVoid.kt new file mode 100644 index 00000000000..53822ca1628 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/noReflectAtRuntime/javaVoid.kt @@ -0,0 +1,17 @@ +// IGNORE_BACKEND: JS, NATIVE +// WITH_RUNTIME + +import kotlin.reflect.KClass +import kotlin.test.assertEquals + +fun box(): String { + assertEquals(Void::class, Void.TYPE.kotlin) + assertEquals(Void.TYPE.kotlin, Void::class) + + assertEquals(Void.TYPE, Void::class.javaPrimitiveType) + assertEquals(Void::class.java, Void::class.javaObjectType) + assertEquals(Void.TYPE, Void.TYPE.kotlin.javaPrimitiveType) + assertEquals(Void::class.java, Void.TYPE.kotlin.javaObjectType) + + return "OK" +} diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 49d1033ea28..56a1718d050 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -16249,6 +16249,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("javaVoid.kt") + public void testJavaVoid() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/classes/javaVoid.kt"); + doTest(fileName); + } + @TestMetadata("jvmName.kt") public void testJvmName() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/classes/jvmName.kt"); @@ -17275,6 +17281,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("javaVoid.kt") + public void testJavaVoid() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/noReflectAtRuntime/javaVoid.kt"); + doTest(fileName); + } + @TestMetadata("primitiveJavaClass.kt") public void testPrimitiveJavaClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/noReflectAtRuntime/primitiveJavaClass.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index ac5c4ec7d32..55cd45a07fa 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -16249,6 +16249,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("javaVoid.kt") + public void testJavaVoid() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/classes/javaVoid.kt"); + doTest(fileName); + } + @TestMetadata("jvmName.kt") public void testJvmName() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/classes/jvmName.kt"); @@ -17275,6 +17281,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("javaVoid.kt") + public void testJavaVoid() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/noReflectAtRuntime/javaVoid.kt"); + doTest(fileName); + } + @TestMetadata("primitiveJavaClass.kt") public void testPrimitiveJavaClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/noReflectAtRuntime/primitiveJavaClass.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 896b3289e55..eaf5febfcc0 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -16249,6 +16249,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes doTest(fileName); } + @TestMetadata("javaVoid.kt") + public void testJavaVoid() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/classes/javaVoid.kt"); + doTest(fileName); + } + @TestMetadata("jvmName.kt") public void testJvmName() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/classes/jvmName.kt"); @@ -17275,6 +17281,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes doTest(fileName); } + @TestMetadata("javaVoid.kt") + public void testJavaVoid() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/noReflectAtRuntime/javaVoid.kt"); + doTest(fileName); + } + @TestMetadata("primitiveJavaClass.kt") public void testPrimitiveJavaClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/noReflectAtRuntime/primitiveJavaClass.kt"); diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/RuntimeTypeMapper.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/RuntimeTypeMapper.kt index 426664aa843..eb30cf58137 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/RuntimeTypeMapper.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/RuntimeTypeMapper.kt @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor import org.jetbrains.kotlin.load.java.sources.JavaSourceElement import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.NameUtils import org.jetbrains.kotlin.platform.JavaToKotlinClassMap import org.jetbrains.kotlin.resolve.DescriptorUtils @@ -156,6 +157,8 @@ private val Method.signature: String returnType.desc internal object RuntimeTypeMapper { + private val JAVA_LANG_VOID = ClassId.topLevel(FqName("java.lang.Void")) + fun mapSignature(possiblySubstitutedFunction: FunctionDescriptor): JvmFunctionSignature { // Fake overrides don't have a source element, so we need to take a declaration. // TODO: support the case when a fake override overrides several declarations with different signatures @@ -263,6 +266,8 @@ internal object RuntimeTypeMapper { return ClassId.topLevel(KotlinBuiltIns.FQ_NAMES.array.toSafe()) } + if (klass == Void.TYPE) return JAVA_LANG_VOID + klass.primitiveType?.let { return ClassId(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME, it.typeName) } diff --git a/core/runtime.jvm/src/kotlin/jvm/JvmClassMapping.kt b/core/runtime.jvm/src/kotlin/jvm/JvmClassMapping.kt index 01eebf819c7..1a2193c68ad 100644 --- a/core/runtime.jvm/src/kotlin/jvm/JvmClassMapping.kt +++ b/core/runtime.jvm/src/kotlin/jvm/JvmClassMapping.kt @@ -55,6 +55,7 @@ public val KClass.javaPrimitiveType: Class? "java.lang.Float" -> Float::class.java "java.lang.Long" -> Long::class.java "java.lang.Double" -> Double::class.java + "java.lang.Void" -> Void.TYPE else -> null } as Class? } @@ -77,6 +78,7 @@ public val KClass.javaObjectType: Class "float" -> JavaLangFloat::class.java "long" -> JavaLangLong::class.java "double" -> JavaLangDouble::class.java + "void" -> Void::class.java else -> thisJClass } as Class } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 56c724ec904..85e83aaf63d 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -18193,6 +18193,18 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); } + @TestMetadata("javaVoid.kt") + public void testJavaVoid() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/classes/javaVoid.kt"); + try { + doTest(fileName); + } + catch (Throwable ignore) { + return; + } + throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); + } + @TestMetadata("jvmName.kt") public void testJvmName() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/classes/jvmName.kt"); @@ -20065,6 +20077,18 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); } + @TestMetadata("javaVoid.kt") + public void testJavaVoid() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/noReflectAtRuntime/javaVoid.kt"); + try { + doTest(fileName); + } + catch (Throwable ignore) { + return; + } + throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); + } + @TestMetadata("primitiveJavaClass.kt") public void testPrimitiveJavaClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/noReflectAtRuntime/primitiveJavaClass.kt");