[Reflection] Fix parsing JVM function descriptors
#KT-60708
This commit is contained in:
committed by
Space Team
parent
df14f044cd
commit
b89d8a65a1
+6
@@ -45870,6 +45870,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
|
|||||||
runTest("compiler/testData/codegen/box/reflection/functions/javaMethodsSmokeTest.kt");
|
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
|
@Test
|
||||||
@TestMetadata("platformName.kt")
|
@TestMetadata("platformName.kt")
|
||||||
public void testPlatformName() throws Exception {
|
public void testPlatformName() throws Exception {
|
||||||
|
|||||||
+6
@@ -45870,6 +45870,12 @@ public class FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated
|
|||||||
runTest("compiler/testData/codegen/box/reflection/functions/javaMethodsSmokeTest.kt");
|
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
|
@Test
|
||||||
@TestMetadata("platformName.kt")
|
@TestMetadata("platformName.kt")
|
||||||
public void testPlatformName() throws Exception {
|
public void testPlatformName() throws Exception {
|
||||||
|
|||||||
+6
@@ -45870,6 +45870,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
|
|||||||
runTest("compiler/testData/codegen/box/reflection/functions/javaMethodsSmokeTest.kt");
|
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
|
@Test
|
||||||
@TestMetadata("platformName.kt")
|
@TestMetadata("platformName.kt")
|
||||||
public void testPlatformName() throws Exception {
|
public void testPlatformName() throws Exception {
|
||||||
|
|||||||
@@ -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"
|
||||||
+6
@@ -45870,6 +45870,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/reflection/functions/javaMethodsSmokeTest.kt");
|
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
|
@Test
|
||||||
@TestMetadata("platformName.kt")
|
@TestMetadata("platformName.kt")
|
||||||
public void testPlatformName() throws Exception {
|
public void testPlatformName() throws Exception {
|
||||||
|
|||||||
+6
@@ -45870,6 +45870,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
|
|||||||
runTest("compiler/testData/codegen/box/reflection/functions/javaMethodsSmokeTest.kt");
|
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
|
@Test
|
||||||
@TestMetadata("platformName.kt")
|
@TestMetadata("platformName.kt")
|
||||||
public void testPlatformName() throws Exception {
|
public void testPlatformName() throws Exception {
|
||||||
|
|||||||
+5
@@ -36502,6 +36502,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/reflection/functions/javaMethodsSmokeTest.kt");
|
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")
|
@TestMetadata("platformName.kt")
|
||||||
public void testPlatformName() throws Exception {
|
public void testPlatformName() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reflection/functions/platformName.kt");
|
runTest("compiler/testData/codegen/box/reflection/functions/platformName.kt");
|
||||||
|
|||||||
@@ -212,8 +212,9 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
|
|||||||
fun findMethodBySignature(name: String, desc: String): Method? {
|
fun findMethodBySignature(name: String, desc: String): Method? {
|
||||||
if (name == "<init>") return null
|
if (name == "<init>") return null
|
||||||
|
|
||||||
val parameterTypes = loadParameterTypes(desc).toTypedArray()
|
val functionJvmDescriptor = parseJvmDescriptor(desc, parseReturnType = true)
|
||||||
val returnType = loadReturnType(desc)
|
val parameterTypes = functionJvmDescriptor.parameters.toTypedArray()
|
||||||
|
val returnType = functionJvmDescriptor.returnType!!
|
||||||
methodOwner.lookupMethod(name, parameterTypes, returnType, false)?.let { return it }
|
methodOwner.lookupMethod(name, parameterTypes, returnType, false)?.let { return it }
|
||||||
|
|
||||||
// Methods from java.lang.Object (equals, hashCode, toString) cannot be found in the interface via
|
// 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.
|
// Note that this value is replaced inside the lookupMethod call below, for each class/interface in the hierarchy.
|
||||||
parameterTypes.add(jClass)
|
parameterTypes.add(jClass)
|
||||||
}
|
}
|
||||||
addParametersAndMasks(parameterTypes, desc, false)
|
val jvmDescriptor = parseJvmDescriptor(desc, parseReturnType = true)
|
||||||
|
addParametersAndMasks(parameterTypes, jvmDescriptor.parameters, isConstructor = false)
|
||||||
|
|
||||||
return methodOwner.lookupMethod(
|
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<*>? =
|
fun findConstructorBySignature(desc: String): Constructor<*>? =
|
||||||
jClass.tryGetConstructor(loadParameterTypes(desc))
|
jClass.tryGetConstructor(parseJvmDescriptor(desc, parseReturnType = false).parameters)
|
||||||
|
|
||||||
fun findDefaultConstructor(desc: String): Constructor<*>? =
|
fun findDefaultConstructor(desc: String): Constructor<*>? =
|
||||||
jClass.tryGetConstructor(arrayListOf<Class<*>>().also { parameterTypes ->
|
jClass.tryGetConstructor(arrayListOf<Class<*>>().also { parameterTypes ->
|
||||||
addParametersAndMasks(parameterTypes, desc, true)
|
val parsedParameters = parseJvmDescriptor(desc, parseReturnType = false).parameters
|
||||||
|
addParametersAndMasks(parameterTypes, parsedParameters, isConstructor = true)
|
||||||
})
|
})
|
||||||
|
|
||||||
private fun addParametersAndMasks(result: MutableList<Class<*>>, desc: String, isConstructor: Boolean) {
|
private fun addParametersAndMasks(result: MutableList<Class<*>>, valueParameters: List<Class<*>>, isConstructor: Boolean) {
|
||||||
val valueParameters = loadParameterTypes(desc)
|
|
||||||
result.addAll(valueParameters)
|
result.addAll(valueParameters)
|
||||||
repeat((valueParameters.size + Integer.SIZE - 1) / Integer.SIZE) {
|
repeat((valueParameters.size + Integer.SIZE - 1) / Integer.SIZE) {
|
||||||
result.add(Integer.TYPE)
|
result.add(Integer.TYPE)
|
||||||
@@ -265,7 +267,9 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
|
|||||||
} else result.add(Any::class.java)
|
} else result.add(Any::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadParameterTypes(desc: String): List<Class<*>> {
|
private class FunctionJvmDescriptor(val parameters: List<Class<*>>, val returnType: Class<*>?)
|
||||||
|
|
||||||
|
private fun parseJvmDescriptor(desc: String, parseReturnType: Boolean): FunctionJvmDescriptor {
|
||||||
val result = arrayListOf<Class<*>>()
|
val result = arrayListOf<Class<*>>()
|
||||||
|
|
||||||
var begin = 1
|
var begin = 1
|
||||||
@@ -283,7 +287,9 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
|
|||||||
begin = end
|
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<*> =
|
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")
|
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 {
|
companion object {
|
||||||
private val DEFAULT_CONSTRUCTOR_MARKER = Class.forName("kotlin.jvm.internal.DefaultConstructorMarker")
|
private val DEFAULT_CONSTRUCTOR_MARKER = Class.forName("kotlin.jvm.internal.DefaultConstructorMarker")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user