From 08ba63df90e177272e65559a6f453148510c5f1a Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Sat, 8 Apr 2023 22:44:37 +0200 Subject: [PATCH] Implement proper `name` interpretation for suspend functions #KT-57313 Fixed --- ...LightTreeBlackBoxCodegenTestGenerated.java | 6 +++++ .../FirPsiBlackBoxCodegenTestGenerated.java | 6 +++++ .../kotlin/ir/interpreter/state/Wrapper.kt | 16 +++++++++----- .../dumpIrAndCheck/kCallableName.kt | 5 ++++- .../box/involvesIrInterpreter/kt57313.kt | 22 +++++++++++++++++++ .../reference/functionReference.kt | 20 +++++++++++++++++ .../IrBlackBoxCodegenTestGenerated.java | 6 +++++ ...kBoxCodegenWithIrInlinerTestGenerated.java | 6 +++++ ...nterpreterAfterFirPsi2IrTestGenerated.java | 6 +++++ ...IrInterpreterAfterPsi2IrTestGenerated.java | 6 +++++ 10 files changed, 92 insertions(+), 7 deletions(-) create mode 100644 compiler/testData/codegen/box/involvesIrInterpreter/kt57313.kt create mode 100644 compiler/testData/ir/interpreter/reference/functionReference.kt diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java index f5071b902b3..acf9c1c14f5 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java @@ -28277,6 +28277,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt"); } + @Test + @TestMetadata("kt57313.kt") + public void testKt57313() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt57313.kt"); + } + @Test @TestMetadata("referenceNameFromStaticInDifferentModule.kt") public void testReferenceNameFromStaticInDifferentModule() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java index b1caaed2d9e..eb1aef458c2 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java @@ -28277,6 +28277,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt"); } + @Test + @TestMetadata("kt57313.kt") + public void testKt57313() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt57313.kt"); + } + @Test @TestMetadata("referenceNameFromStaticInDifferentModule.kt") public void testReferenceNameFromStaticInDifferentModule() throws Exception { diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Wrapper.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Wrapper.kt index 70743f4879a..6d5ff8efa09 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Wrapper.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Wrapper.kt @@ -198,6 +198,13 @@ internal class Wrapper(val value: Any, override val irClass: IrClass, environmen } } + private fun Int?.getCorrespondingFunction(): Class<*> { + return when { + this == null || this >= BuiltInFunctionArity.BIG_ARITY -> Class.forName("kotlin.jvm.functions.FunctionN") + else -> Class.forName("kotlin.jvm.functions.Function$this") + } + } + private fun IrType.getClass(asObject: Boolean): Class { val owner = this.classOrNull?.owner val fqName = owner?.fqName @@ -221,15 +228,12 @@ internal class Wrapper(val value: Any, override val irClass: IrClass, environmen notNullType.isThrowable() -> Throwable::class.java notNullType.isIterable() -> Iterable::class.java - notNullType.isKFunction() -> Class.forName("kotlin.reflect.KFunction") + notNullType.isKFunction() || notNullType.isKSuspendFunction() -> Class.forName("kotlin.reflect.KFunction") notNullType.isFunction() -> { val arity = fqName?.removePrefix("kotlin.Function")?.toIntOrNull() - return when { - arity == null || arity >= BuiltInFunctionArity.BIG_ARITY -> Class.forName("kotlin.jvm.functions.FunctionN") - else -> Class.forName("kotlin.jvm.functions.${fqName.removePrefix("kotlin.")}") - } + return arity.getCorrespondingFunction() } - //notNullType.isSuspendFunction() || notNullType.isKSuspendFunction() -> throw AssertionError() //TODO + notNullType.isSuspendFunction() -> error("Interpretation of $fqName is not supported") fqName == "kotlin.Enum" -> Enum::class.java fqName == "kotlin.collections.Collection" || fqName == "kotlin.collections.MutableCollection" -> Collection::class.java diff --git a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/kCallableName.kt b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/kCallableName.kt index fe56d499257..3fcdaf47e74 100644 --- a/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/kCallableName.kt +++ b/compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/kCallableName.kt @@ -4,19 +4,22 @@ class A(val OK: Int, val somePropertyWithLongName: String) { fun foo() {} + suspend fun bar() {} } val topLevelProp = 1 const val propertyName1 = A::OK.name const val propertyName2 = A::somePropertyWithLongName.name const val methodName = A::foo.name +const val suspendMethodName = A::bar.name const val className = ::A.name const val topLevelPropName = ::topLevelProp.name fun box(): String { if (propertyName1 != "OK") return "Fail 1" if (propertyName2 != "somePropertyWithLongName") return "Fail 2" - if (methodName != "foo") return "Fail 3" + if (methodName != "foo") return "Fail 3.1" + if (suspendMethodName != "bar") return "Fail 3.2" if (className != "") return "Fail 4" if (topLevelPropName != "topLevelProp") return "Fail 5" return "OK" diff --git a/compiler/testData/codegen/box/involvesIrInterpreter/kt57313.kt b/compiler/testData/codegen/box/involvesIrInterpreter/kt57313.kt new file mode 100644 index 00000000000..8b5a18d9434 --- /dev/null +++ b/compiler/testData/codegen/box/involvesIrInterpreter/kt57313.kt @@ -0,0 +1,22 @@ +// TARGET_BACKEND: JVM_IR + +abstract class AsyncJob { + abstract suspend fun execute(lifetime: AsyncLifetime, attempt: Int, due: DateTime, context: JobContext): JobContext +} + +class OrgBootstrapRequest +class AsyncLifetime +class DateTime +class JobContext + +class OrgBootstrapTriggerJob(val orgId: Long, val bootstrap: OrgBootstrapRequest, val jetSalesSync: Boolean?) : AsyncJob() { + override suspend fun execute(lifetime: AsyncLifetime, attempt: Int, due: DateTime, context: JobContext): JobContext { + return JobContext() + } +} + +val name = "${OrgBootstrapTriggerJob::class.simpleName}.${OrgBootstrapTriggerJob::execute.name}" + +fun box(): String { + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/ir/interpreter/reference/functionReference.kt b/compiler/testData/ir/interpreter/reference/functionReference.kt new file mode 100644 index 00000000000..fa6c528c65f --- /dev/null +++ b/compiler/testData/ir/interpreter/reference/functionReference.kt @@ -0,0 +1,20 @@ +@CompileTimeCalculation +class A(val a: Int) { + fun foo(): Int { + return a + } + + suspend fun baz(): Int { + return a + } +} + +const val functionName = A::foo.name +const val functionInvoke = A::foo.invoke(A(1)) + +const val functionWithReceiverName = A(2)::foo.name +const val functionWithReceiverInvoke = A(2)::foo.invoke() + +// THIS IS WRONG, suspend fun must be called from coroutine ot another suspend function. +// It is used here just for test purposes. +const val suspendFunctionInvoke = A::baz.invoke(A(3)) diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index cabaa96db23..c595339014c 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -28277,6 +28277,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt"); } + @Test + @TestMetadata("kt57313.kt") + public void testKt57313() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt57313.kt"); + } + @Test @TestMetadata("referenceNameFromStaticInDifferentModule.kt") public void testReferenceNameFromStaticInDifferentModule() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java index 91ede3fff91..5caf789d3c0 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java @@ -28277,6 +28277,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt56215.kt"); } + @Test + @TestMetadata("kt57313.kt") + public void testKt57313() throws Exception { + runTest("compiler/testData/codegen/box/involvesIrInterpreter/kt57313.kt"); + } + @Test @TestMetadata("referenceNameFromStaticInDifferentModule.kt") public void testReferenceNameFromStaticInDifferentModule() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/interpreter/JvmIrInterpreterAfterFirPsi2IrTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/interpreter/JvmIrInterpreterAfterFirPsi2IrTestGenerated.java index de00e4d18f6..387b6754837 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/interpreter/JvmIrInterpreterAfterFirPsi2IrTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/interpreter/JvmIrInterpreterAfterFirPsi2IrTestGenerated.java @@ -706,6 +706,12 @@ public class JvmIrInterpreterAfterFirPsi2IrTestGenerated extends AbstractJvmIrIn KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/ir/interpreter/reference"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @Test + @TestMetadata("functionReference.kt") + public void testFunctionReference() throws Exception { + runTest("compiler/testData/ir/interpreter/reference/functionReference.kt"); + } + @Test @TestMetadata("getClass.kt") public void testGetClass() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/interpreter/JvmIrInterpreterAfterPsi2IrTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/interpreter/JvmIrInterpreterAfterPsi2IrTestGenerated.java index 31172307270..98968577486 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/interpreter/JvmIrInterpreterAfterPsi2IrTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/interpreter/JvmIrInterpreterAfterPsi2IrTestGenerated.java @@ -706,6 +706,12 @@ public class JvmIrInterpreterAfterPsi2IrTestGenerated extends AbstractJvmIrInter KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/ir/interpreter/reference"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @Test + @TestMetadata("functionReference.kt") + public void testFunctionReference() throws Exception { + runTest("compiler/testData/ir/interpreter/reference/functionReference.kt"); + } + @Test @TestMetadata("getClass.kt") public void testGetClass() throws Exception {