From b89d8a65a1668868b4b4fb065658b3d6c8e3a43d Mon Sep 17 00:00:00 2001 From: "Evgeniy.Zhelenskiy" Date: Wed, 26 Jul 2023 09:04:02 +0200 Subject: [PATCH] [Reflection] Fix parsing JVM function descriptors #KT-60708 --- ...LightTreeBlackBoxCodegenTestGenerated.java | 6 ++++ ...hIrFakeOverrideGeneratorTestGenerated.java | 6 ++++ .../FirPsiBlackBoxCodegenTestGenerated.java | 6 ++++ .../box/reflection/functions/parentheses.kt | 15 ++++++++++ .../IrBlackBoxCodegenTestGenerated.java | 6 ++++ ...kBoxCodegenWithIrInlinerTestGenerated.java | 6 ++++ .../LightAnalysisModeTestGenerated.java | 5 ++++ .../jvm/internal/KDeclarationContainerImpl.kt | 29 ++++++++++--------- 8 files changed, 66 insertions(+), 13 deletions(-) create mode 100644 compiler/testData/codegen/box/reflection/functions/parentheses.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 eb688c88623..f2e2f6c0c95 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 @@ -45870,6 +45870,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr runTest("compiler/testData/codegen/box/reflection/functions/javaMethodsSmokeTest.kt"); } + @Test + @TestMetadata("parentheses.kt") + public void testParentheses() throws Exception { + runTest("compiler/testData/codegen/box/reflection/functions/parentheses.kt"); + } + @Test @TestMetadata("platformName.kt") public void testPlatformName() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java index fd969e96410..bd46db5564e 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java @@ -45870,6 +45870,12 @@ public class FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated runTest("compiler/testData/codegen/box/reflection/functions/javaMethodsSmokeTest.kt"); } + @Test + @TestMetadata("parentheses.kt") + public void testParentheses() throws Exception { + runTest("compiler/testData/codegen/box/reflection/functions/parentheses.kt"); + } + @Test @TestMetadata("platformName.kt") public void testPlatformName() 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 943b273b960..91bb1b5f2e4 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 @@ -45870,6 +45870,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo runTest("compiler/testData/codegen/box/reflection/functions/javaMethodsSmokeTest.kt"); } + @Test + @TestMetadata("parentheses.kt") + public void testParentheses() throws Exception { + runTest("compiler/testData/codegen/box/reflection/functions/parentheses.kt"); + } + @Test @TestMetadata("platformName.kt") public void testPlatformName() throws Exception { diff --git a/compiler/testData/codegen/box/reflection/functions/parentheses.kt b/compiler/testData/codegen/box/reflection/functions/parentheses.kt new file mode 100644 index 00000000000..8566549bc52 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/functions/parentheses.kt @@ -0,0 +1,15 @@ +// TARGET_BACKEND: JVM_IR +// IGNORE_DEXING + +// WITH_REFLECT + +data class `)))`(val value: Int) +interface `)` { + fun f(i1: `)))` = `)))`(1)): Int +} + +data class `))`(val x: Int): `)` { + override fun f(i1: `)))`) = x + i1.value +} + +fun box(): String = if (`))`(2)::f.callBy(mapOf()) == 3) "OK" else "NOT OK" 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 11ffe486dba..2d6d3d42427 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 @@ -45870,6 +45870,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/reflection/functions/javaMethodsSmokeTest.kt"); } + @Test + @TestMetadata("parentheses.kt") + public void testParentheses() throws Exception { + runTest("compiler/testData/codegen/box/reflection/functions/parentheses.kt"); + } + @Test @TestMetadata("platformName.kt") public void testPlatformName() 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 69acd8a41ee..d7d38c26015 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 @@ -45870,6 +45870,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack runTest("compiler/testData/codegen/box/reflection/functions/javaMethodsSmokeTest.kt"); } + @Test + @TestMetadata("parentheses.kt") + public void testParentheses() throws Exception { + runTest("compiler/testData/codegen/box/reflection/functions/parentheses.kt"); + } + @Test @TestMetadata("platformName.kt") public void testPlatformName() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 907d4982a82..ca91b14cff0 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -36502,6 +36502,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/reflection/functions/javaMethodsSmokeTest.kt"); } + @TestMetadata("parentheses.kt") + public void testParentheses() throws Exception { + runTest("compiler/testData/codegen/box/reflection/functions/parentheses.kt"); + } + @TestMetadata("platformName.kt") public void testPlatformName() throws Exception { runTest("compiler/testData/codegen/box/reflection/functions/platformName.kt"); diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KDeclarationContainerImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KDeclarationContainerImpl.kt index 7064a143bcb..82d413ec8f4 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KDeclarationContainerImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KDeclarationContainerImpl.kt @@ -212,8 +212,9 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain fun findMethodBySignature(name: String, desc: String): Method? { if (name == "") return null - val parameterTypes = loadParameterTypes(desc).toTypedArray() - val returnType = loadReturnType(desc) + val functionJvmDescriptor = parseJvmDescriptor(desc, parseReturnType = true) + val parameterTypes = functionJvmDescriptor.parameters.toTypedArray() + val returnType = functionJvmDescriptor.returnType!! methodOwner.lookupMethod(name, parameterTypes, returnType, false)?.let { return it } // Methods from java.lang.Object (equals, hashCode, toString) cannot be found in the interface via @@ -233,23 +234,24 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain // Note that this value is replaced inside the lookupMethod call below, for each class/interface in the hierarchy. parameterTypes.add(jClass) } - addParametersAndMasks(parameterTypes, desc, false) + val jvmDescriptor = parseJvmDescriptor(desc, parseReturnType = true) + addParametersAndMasks(parameterTypes, jvmDescriptor.parameters, isConstructor = false) return methodOwner.lookupMethod( - name + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, parameterTypes.toTypedArray(), loadReturnType(desc), isStaticDefault = isMember + name + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, parameterTypes.toTypedArray(), jvmDescriptor.returnType!!, isStaticDefault = isMember ) } fun findConstructorBySignature(desc: String): Constructor<*>? = - jClass.tryGetConstructor(loadParameterTypes(desc)) + jClass.tryGetConstructor(parseJvmDescriptor(desc, parseReturnType = false).parameters) fun findDefaultConstructor(desc: String): Constructor<*>? = jClass.tryGetConstructor(arrayListOf>().also { parameterTypes -> - addParametersAndMasks(parameterTypes, desc, true) + val parsedParameters = parseJvmDescriptor(desc, parseReturnType = false).parameters + addParametersAndMasks(parameterTypes, parsedParameters, isConstructor = true) }) - private fun addParametersAndMasks(result: MutableList>, desc: String, isConstructor: Boolean) { - val valueParameters = loadParameterTypes(desc) + private fun addParametersAndMasks(result: MutableList>, valueParameters: List>, isConstructor: Boolean) { result.addAll(valueParameters) repeat((valueParameters.size + Integer.SIZE - 1) / Integer.SIZE) { result.add(Integer.TYPE) @@ -265,7 +267,9 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain } else result.add(Any::class.java) } - private fun loadParameterTypes(desc: String): List> { + private class FunctionJvmDescriptor(val parameters: List>, val returnType: Class<*>?) + + private fun parseJvmDescriptor(desc: String, parseReturnType: Boolean): FunctionJvmDescriptor { val result = arrayListOf>() var begin = 1 @@ -283,7 +287,9 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain begin = end } - return result + val returnType = if (parseReturnType) parseType(desc, begin = begin + 1, end = desc.length) else null + + return FunctionJvmDescriptor(result, returnType) } private fun parseType(desc: String, begin: Int, end: Int): Class<*> = @@ -302,9 +308,6 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain else -> throw KotlinReflectionInternalError("Unknown type prefix in the method signature: $desc") } - private fun loadReturnType(desc: String): Class<*> = - parseType(desc, desc.indexOf(')') + 1, desc.length) - companion object { private val DEFAULT_CONSTRUCTOR_MARKER = Class.forName("kotlin.jvm.internal.DefaultConstructorMarker")