From dd33ed92978a0aaf67635b047a5468d5ac4b43f9 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 27 Oct 2020 10:53:23 +0100 Subject: [PATCH] Fix suspend function with inline class types in reflection #KT-34024 Fixed --- .../ir/FirBlackBoxCodegenTestGenerated.java | 33 +++++++++++-- .../call/inlineClasses/suspendFunction.kt | 34 ++++++++++++++ .../inlineClassPrimaryVal.kt | 0 ...spendFunctionWithInlineClassInSignature.kt | 47 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 33 +++++++++++-- .../LightAnalysisModeTestGenerated.java | 33 +++++++++++-- .../ir/IrBlackBoxCodegenTestGenerated.java | 33 +++++++++++-- .../internal/calls/InlineClassAwareCaller.kt | 3 +- .../IrJsCodegenBoxES6TestGenerated.java | 13 +++++ .../IrJsCodegenBoxTestGenerated.java | 13 +++++ .../semantics/JsCodegenBoxTestGenerated.java | 13 +++++ 11 files changed, 234 insertions(+), 21 deletions(-) create mode 100644 compiler/testData/codegen/box/reflection/call/inlineClasses/suspendFunction.kt rename compiler/testData/codegen/box/reflection/mapping/{ => inlineClasses}/inlineClassPrimaryVal.kt (100%) create mode 100644 compiler/testData/codegen/box/reflection/mapping/inlineClasses/suspendFunctionWithInlineClassInSignature.kt diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index c7faf4b8ab5..7e1ab8de938 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -26519,6 +26519,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT public void testProperties() throws Exception { runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/properties.kt"); } + + @TestMetadata("suspendFunction.kt") + public void testSuspendFunction() throws Exception { + runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/suspendFunction.kt"); + } } } @@ -27417,11 +27422,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/reflection/mapping/functions.kt"); } - @TestMetadata("inlineClassPrimaryVal.kt") - public void testInlineClassPrimaryVal() throws Exception { - runTest("compiler/testData/codegen/box/reflection/mapping/inlineClassPrimaryVal.kt"); - } - @TestMetadata("inlineReifiedFun.kt") public void testInlineReifiedFun() throws Exception { runTest("compiler/testData/codegen/box/reflection/mapping/inlineReifiedFun.kt"); @@ -27510,6 +27510,29 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT } } + @TestMetadata("compiler/testData/codegen/box/reflection/mapping/inlineClasses") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class InlineClasses extends AbstractFirBlackBoxCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTestWithCustomIgnoreDirective(this::doTest, TargetBackend.JVM_IR, testDataFilePath, "// IGNORE_BACKEND_FIR: "); + } + + public void testAllFilesPresentInInlineClasses() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/mapping/inlineClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @TestMetadata("inlineClassPrimaryVal.kt") + public void testInlineClassPrimaryVal() throws Exception { + runTest("compiler/testData/codegen/box/reflection/mapping/inlineClasses/inlineClassPrimaryVal.kt"); + } + + @TestMetadata("suspendFunctionWithInlineClassInSignature.kt") + public void testSuspendFunctionWithInlineClassInSignature() throws Exception { + runTest("compiler/testData/codegen/box/reflection/mapping/inlineClasses/suspendFunctionWithInlineClassInSignature.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/reflection/mapping/jvmStatic") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/testData/codegen/box/reflection/call/inlineClasses/suspendFunction.kt b/compiler/testData/codegen/box/reflection/call/inlineClasses/suspendFunction.kt new file mode 100644 index 00000000000..f41c33180e6 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/call/inlineClasses/suspendFunction.kt @@ -0,0 +1,34 @@ +// TARGET_BACKEND: JVM +// WITH_REFLECT +// WITH_COROUTINES + +package test + +import kotlin.coroutines.startCoroutine +import kotlin.reflect.full.callSuspend +import helpers.* + +inline class Z(val value: String) + +class S { + private var value: Z = Z("") + + suspend fun consumeZ(z: Z) { value = z } + suspend fun produceZ(): Z = value + suspend fun consumeAndProduceZ(z: Z): Z = z +} + +private fun run0(f: suspend () -> String): String { + var result = "" + f.startCoroutine(handleResultContinuation { result = it }) + return result +} + +fun box(): String = + run0 { + val s = S() + S::consumeZ.callSuspend(s, Z("z")) + val v = S::produceZ.callSuspend(s) + if (v != Z("z")) "Fail: $v" + else S::consumeAndProduceZ.callSuspend(s, Z("OK")).value + } diff --git a/compiler/testData/codegen/box/reflection/mapping/inlineClassPrimaryVal.kt b/compiler/testData/codegen/box/reflection/mapping/inlineClasses/inlineClassPrimaryVal.kt similarity index 100% rename from compiler/testData/codegen/box/reflection/mapping/inlineClassPrimaryVal.kt rename to compiler/testData/codegen/box/reflection/mapping/inlineClasses/inlineClassPrimaryVal.kt diff --git a/compiler/testData/codegen/box/reflection/mapping/inlineClasses/suspendFunctionWithInlineClassInSignature.kt b/compiler/testData/codegen/box/reflection/mapping/inlineClasses/suspendFunctionWithInlineClassInSignature.kt new file mode 100644 index 00000000000..fea4c73c5d3 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/mapping/inlineClasses/suspendFunctionWithInlineClassInSignature.kt @@ -0,0 +1,47 @@ +// TARGET_BACKEND: JVM +// WITH_REFLECT + +package test + +import kotlin.reflect.* +import kotlin.reflect.jvm.* +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +inline class Z(val value: String) + +class S { + suspend fun consumeZ(z: Z) {} + suspend fun produceZ(): Z = Z("") + suspend fun consumeAndProduceZ(z: Z): Z = z +} + +fun box(): String { + val members = S::class.members.filterIsInstance>().associateBy(KFunction<*>::name) + + members["consumeZ"]!!.let { cz -> + val czj = cz.javaMethod!! + assertTrue(czj.name.startsWith("consumeZ-"), czj.name) + assertEquals("java.lang.String, kotlin.coroutines.Continuation", czj.parameterTypes.joinToString { it.name }) + val czjk = czj.kotlinFunction + assertEquals(cz, czjk) + } + + members["produceZ"]!!.let { pz -> + val pzj = pz.javaMethod!! + assertTrue(pzj.name.startsWith("produceZ-"), pzj.name) + assertEquals("kotlin.coroutines.Continuation", pzj.parameterTypes.joinToString { it.name }) + val pzjk = pzj!!.kotlinFunction + assertEquals(pz, pzjk) + } + + members["consumeAndProduceZ"]!!.let { cpz -> + val cpzj = cpz.javaMethod!! + assertTrue(cpzj.name.startsWith("consumeAndProduceZ-"), cpzj.name) + assertEquals("java.lang.String, kotlin.coroutines.Continuation", cpzj.parameterTypes.joinToString { it.name }) + val cpzjk = cpzj!!.kotlinFunction + assertEquals(cpz, cpzjk) + } + + return "OK" +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 3500dd6a157..d58790fb6b3 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -28290,6 +28290,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public void testProperties() throws Exception { runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/properties.kt"); } + + @TestMetadata("suspendFunction.kt") + public void testSuspendFunction() throws Exception { + runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/suspendFunction.kt"); + } } } @@ -29188,11 +29193,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/reflection/mapping/functions.kt"); } - @TestMetadata("inlineClassPrimaryVal.kt") - public void testInlineClassPrimaryVal() throws Exception { - runTest("compiler/testData/codegen/box/reflection/mapping/inlineClassPrimaryVal.kt"); - } - @TestMetadata("inlineReifiedFun.kt") public void testInlineReifiedFun() throws Exception { runTest("compiler/testData/codegen/box/reflection/mapping/inlineReifiedFun.kt"); @@ -29281,6 +29281,29 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { } } + @TestMetadata("compiler/testData/codegen/box/reflection/mapping/inlineClasses") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class InlineClasses extends AbstractBlackBoxCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInInlineClasses() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/mapping/inlineClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); + } + + @TestMetadata("inlineClassPrimaryVal.kt") + public void testInlineClassPrimaryVal() throws Exception { + runTest("compiler/testData/codegen/box/reflection/mapping/inlineClasses/inlineClassPrimaryVal.kt"); + } + + @TestMetadata("suspendFunctionWithInlineClassInSignature.kt") + public void testSuspendFunctionWithInlineClassInSignature() throws Exception { + runTest("compiler/testData/codegen/box/reflection/mapping/inlineClasses/suspendFunctionWithInlineClassInSignature.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/reflection/mapping/jvmStatic") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index b145be72620..add8f278fef 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -25924,6 +25924,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes public void testProperties() throws Exception { runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/properties.kt"); } + + @TestMetadata("suspendFunction.kt") + public void testSuspendFunction() throws Exception { + runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/suspendFunction.kt"); + } } } @@ -26822,11 +26827,6 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/reflection/mapping/functions.kt"); } - @TestMetadata("inlineClassPrimaryVal.kt") - public void testInlineClassPrimaryVal() throws Exception { - runTest("compiler/testData/codegen/box/reflection/mapping/inlineClassPrimaryVal.kt"); - } - @TestMetadata("inlineReifiedFun.kt") public void testInlineReifiedFun() throws Exception { runTest("compiler/testData/codegen/box/reflection/mapping/inlineReifiedFun.kt"); @@ -26915,6 +26915,29 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes } } + @TestMetadata("compiler/testData/codegen/box/reflection/mapping/inlineClasses") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class InlineClasses extends AbstractLightAnalysisModeTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInInlineClasses() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/mapping/inlineClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); + } + + @TestMetadata("inlineClassPrimaryVal.kt") + public void testInlineClassPrimaryVal() throws Exception { + runTest("compiler/testData/codegen/box/reflection/mapping/inlineClasses/inlineClassPrimaryVal.kt"); + } + + @TestMetadata("suspendFunctionWithInlineClassInSignature.kt") + public void testSuspendFunctionWithInlineClassInSignature() throws Exception { + runTest("compiler/testData/codegen/box/reflection/mapping/inlineClasses/suspendFunctionWithInlineClassInSignature.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/reflection/mapping/jvmStatic") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index ba0ab6c634a..a457b3f505e 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -26519,6 +26519,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes public void testProperties() throws Exception { runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/properties.kt"); } + + @TestMetadata("suspendFunction.kt") + public void testSuspendFunction() throws Exception { + runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/suspendFunction.kt"); + } } } @@ -27417,11 +27422,6 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/reflection/mapping/functions.kt"); } - @TestMetadata("inlineClassPrimaryVal.kt") - public void testInlineClassPrimaryVal() throws Exception { - runTest("compiler/testData/codegen/box/reflection/mapping/inlineClassPrimaryVal.kt"); - } - @TestMetadata("inlineReifiedFun.kt") public void testInlineReifiedFun() throws Exception { runTest("compiler/testData/codegen/box/reflection/mapping/inlineReifiedFun.kt"); @@ -27510,6 +27510,29 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes } } + @TestMetadata("compiler/testData/codegen/box/reflection/mapping/inlineClasses") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class InlineClasses extends AbstractIrBlackBoxCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath); + } + + public void testAllFilesPresentInInlineClasses() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/mapping/inlineClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @TestMetadata("inlineClassPrimaryVal.kt") + public void testInlineClassPrimaryVal() throws Exception { + runTest("compiler/testData/codegen/box/reflection/mapping/inlineClasses/inlineClassPrimaryVal.kt"); + } + + @TestMetadata("suspendFunctionWithInlineClassInSignature.kt") + public void testSuspendFunctionWithInlineClassInSignature() throws Exception { + runTest("compiler/testData/codegen/box/reflection/mapping/inlineClasses/suspendFunctionWithInlineClassInSignature.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/reflection/mapping/jvmStatic") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/calls/InlineClassAwareCaller.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/calls/InlineClassAwareCaller.kt index 4e867a5bbf7..6e3187ec6fa 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/calls/InlineClassAwareCaller.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/calls/InlineClassAwareCaller.kt @@ -76,7 +76,8 @@ internal class InlineClassAwareCaller( else -> 0 } - val extraArgumentsTail = if (isDefault) 2 else 0 + val extraArgumentsTail = (if (isDefault) 2 else 0) + + (if (descriptor is FunctionDescriptor && descriptor.isSuspend) 1 else 0) val kotlinParameterTypes: List = ArrayList().also { kotlinParameterTypes -> val extensionReceiverType = descriptor.extensionReceiverParameter?.type diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index 5d8bda37417..e2df4a2414b 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -22851,6 +22851,19 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes } } + @TestMetadata("compiler/testData/codegen/box/reflection/mapping/inlineClasses") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class InlineClasses extends AbstractIrJsCodegenBoxES6Test { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath); + } + + public void testAllFilesPresentInInlineClasses() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/mapping/inlineClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true); + } + } + @TestMetadata("compiler/testData/codegen/box/reflection/mapping/jvmStatic") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 6b192e22270..85ffe0ed91a 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -22851,6 +22851,19 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { } } + @TestMetadata("compiler/testData/codegen/box/reflection/mapping/inlineClasses") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class InlineClasses extends AbstractIrJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath); + } + + public void testAllFilesPresentInInlineClasses() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/mapping/inlineClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); + } + } + @TestMetadata("compiler/testData/codegen/box/reflection/mapping/jvmStatic") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.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 efa7d0f8bef..e700002ce15 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 @@ -22866,6 +22866,19 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { } } + @TestMetadata("compiler/testData/codegen/box/reflection/mapping/inlineClasses") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class InlineClasses extends AbstractJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath); + } + + public void testAllFilesPresentInInlineClasses() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/mapping/inlineClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); + } + } + @TestMetadata("compiler/testData/codegen/box/reflection/mapping/jvmStatic") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)