[Reflection] Support callBy for inline class interface functions with default parameters
#KT-57972
This commit is contained in:
committed by
Space Team
parent
1e7cc00dcb
commit
b0367d9399
+36
@@ -46667,6 +46667,18 @@ public class LLFirBlackBoxCodegenBasedTestGenerated extends AbstractLLFirBlackBo
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/boundJvmStaticInObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("brokenDefaultParametersFromDifferentFunctions.kt")
|
||||
public void testBrokenDefaultParametersFromDifferentFunctions() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/brokenDefaultParametersFromDifferentFunctions.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("brokenDefaultParametersFromDifferentFunctionsJvmDefault.kt")
|
||||
public void testBrokenDefaultParametersFromDifferentFunctionsJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/brokenDefaultParametersFromDifferentFunctionsJvmDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("companionObject.kt")
|
||||
public void testCompanionObject() throws Exception {
|
||||
@@ -46715,6 +46727,18 @@ public class LLFirBlackBoxCodegenBasedTestGenerated extends AbstractLLFirBlackBo
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassFunctionsAndConstructors.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClassInterface.kt")
|
||||
public void testInlineClassInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClassInterfaceJvmDefault.kt")
|
||||
public void testInlineClassInterfaceJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassInterfaceJvmDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClassMembers.kt")
|
||||
public void testInlineClassMembers() throws Exception {
|
||||
@@ -46781,6 +46805,18 @@ public class LLFirBlackBoxCodegenBasedTestGenerated extends AbstractLLFirBlackBo
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcFunctionsAndConstructors.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcInterface.kt")
|
||||
public void testMfvcInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcInterfaceJvmDefault.kt")
|
||||
public void testMfvcInterfaceJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcInterfaceJvmDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcKt61304.kt")
|
||||
public void testMfvcKt61304() throws Exception {
|
||||
|
||||
+36
@@ -46667,6 +46667,18 @@ public class LLFirReversedBlackBoxCodegenBasedTestGenerated extends AbstractLLFi
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/boundJvmStaticInObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("brokenDefaultParametersFromDifferentFunctions.kt")
|
||||
public void testBrokenDefaultParametersFromDifferentFunctions() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/brokenDefaultParametersFromDifferentFunctions.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("brokenDefaultParametersFromDifferentFunctionsJvmDefault.kt")
|
||||
public void testBrokenDefaultParametersFromDifferentFunctionsJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/brokenDefaultParametersFromDifferentFunctionsJvmDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("companionObject.kt")
|
||||
public void testCompanionObject() throws Exception {
|
||||
@@ -46715,6 +46727,18 @@ public class LLFirReversedBlackBoxCodegenBasedTestGenerated extends AbstractLLFi
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassFunctionsAndConstructors.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClassInterface.kt")
|
||||
public void testInlineClassInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClassInterfaceJvmDefault.kt")
|
||||
public void testInlineClassInterfaceJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassInterfaceJvmDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClassMembers.kt")
|
||||
public void testInlineClassMembers() throws Exception {
|
||||
@@ -46781,6 +46805,18 @@ public class LLFirReversedBlackBoxCodegenBasedTestGenerated extends AbstractLLFi
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcFunctionsAndConstructors.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcInterface.kt")
|
||||
public void testMfvcInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcInterfaceJvmDefault.kt")
|
||||
public void testMfvcInterfaceJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcInterfaceJvmDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcKt61304.kt")
|
||||
public void testMfvcKt61304() throws Exception {
|
||||
|
||||
+36
@@ -46264,6 +46264,18 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/boundJvmStaticInObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("brokenDefaultParametersFromDifferentFunctions.kt")
|
||||
public void testBrokenDefaultParametersFromDifferentFunctions() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/brokenDefaultParametersFromDifferentFunctions.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("brokenDefaultParametersFromDifferentFunctionsJvmDefault.kt")
|
||||
public void testBrokenDefaultParametersFromDifferentFunctionsJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/brokenDefaultParametersFromDifferentFunctionsJvmDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("companionObject.kt")
|
||||
public void testCompanionObject() throws Exception {
|
||||
@@ -46312,6 +46324,18 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassFunctionsAndConstructors.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClassInterface.kt")
|
||||
public void testInlineClassInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClassInterfaceJvmDefault.kt")
|
||||
public void testInlineClassInterfaceJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassInterfaceJvmDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClassMembers.kt")
|
||||
public void testInlineClassMembers() throws Exception {
|
||||
@@ -46378,6 +46402,18 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcFunctionsAndConstructors.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcInterface.kt")
|
||||
public void testMfvcInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcInterfaceJvmDefault.kt")
|
||||
public void testMfvcInterfaceJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcInterfaceJvmDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcKt61304.kt")
|
||||
public void testMfvcKt61304() throws Exception {
|
||||
|
||||
+36
@@ -46264,6 +46264,18 @@ public class FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/boundJvmStaticInObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("brokenDefaultParametersFromDifferentFunctions.kt")
|
||||
public void testBrokenDefaultParametersFromDifferentFunctions() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/brokenDefaultParametersFromDifferentFunctions.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("brokenDefaultParametersFromDifferentFunctionsJvmDefault.kt")
|
||||
public void testBrokenDefaultParametersFromDifferentFunctionsJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/brokenDefaultParametersFromDifferentFunctionsJvmDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("companionObject.kt")
|
||||
public void testCompanionObject() throws Exception {
|
||||
@@ -46312,6 +46324,18 @@ public class FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassFunctionsAndConstructors.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClassInterface.kt")
|
||||
public void testInlineClassInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClassInterfaceJvmDefault.kt")
|
||||
public void testInlineClassInterfaceJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassInterfaceJvmDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClassMembers.kt")
|
||||
public void testInlineClassMembers() throws Exception {
|
||||
@@ -46378,6 +46402,18 @@ public class FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcFunctionsAndConstructors.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcInterface.kt")
|
||||
public void testMfvcInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcInterfaceJvmDefault.kt")
|
||||
public void testMfvcInterfaceJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcInterfaceJvmDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcKt61304.kt")
|
||||
public void testMfvcKt61304() throws Exception {
|
||||
|
||||
+36
@@ -46264,6 +46264,18 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/boundJvmStaticInObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("brokenDefaultParametersFromDifferentFunctions.kt")
|
||||
public void testBrokenDefaultParametersFromDifferentFunctions() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/brokenDefaultParametersFromDifferentFunctions.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("brokenDefaultParametersFromDifferentFunctionsJvmDefault.kt")
|
||||
public void testBrokenDefaultParametersFromDifferentFunctionsJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/brokenDefaultParametersFromDifferentFunctionsJvmDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("companionObject.kt")
|
||||
public void testCompanionObject() throws Exception {
|
||||
@@ -46312,6 +46324,18 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassFunctionsAndConstructors.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClassInterface.kt")
|
||||
public void testInlineClassInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClassInterfaceJvmDefault.kt")
|
||||
public void testInlineClassInterfaceJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassInterfaceJvmDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClassMembers.kt")
|
||||
public void testInlineClassMembers() throws Exception {
|
||||
@@ -46378,6 +46402,18 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcFunctionsAndConstructors.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcInterface.kt")
|
||||
public void testMfvcInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcInterfaceJvmDefault.kt")
|
||||
public void testMfvcInterfaceJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcInterfaceJvmDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcKt61304.kt")
|
||||
public void testMfvcKt61304() throws Exception {
|
||||
|
||||
Vendored
+60
@@ -0,0 +1,60 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// WITH_REFLECT
|
||||
// LANGUAGE: +ValueClasses
|
||||
// !JVM_DEFAULT_MODE: disable
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.reflect.full.instanceParameter
|
||||
|
||||
interface I1 {
|
||||
fun f(i1: Int = 1, i2: Int): Int
|
||||
}
|
||||
|
||||
interface I2 {
|
||||
fun f(i1: Int, i2: Int = 2): Int
|
||||
}
|
||||
|
||||
data class DC(val x: Int, val y: Int) : I1, I2 {
|
||||
override fun f(i1: Int, i2: Int) = x + y + i1
|
||||
}
|
||||
|
||||
fun dataClass() {
|
||||
val unbounded = DC::f
|
||||
assertEquals(111, unbounded.callBy(mapOf(unbounded.instanceParameter!! to DC(10, 100))))
|
||||
|
||||
val bounded = DC(10, 100)::f
|
||||
assertEquals(111, bounded.callBy(mapOf()))
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class VC(val x: Int, val y: Int) : I1, I2 {
|
||||
override fun f(i1: Int, i2: Int) = x + y + i1
|
||||
}
|
||||
|
||||
fun valueClass() {
|
||||
val unbounded = VC::f
|
||||
assertEquals(111, unbounded.callBy(mapOf(unbounded.instanceParameter!! to VC(10, 100))))
|
||||
|
||||
val bounded = VC(10, 100)::f
|
||||
assertEquals(111, bounded.callBy(mapOf()))
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class IC(val x: Int) : I1, I2 {
|
||||
override fun f(i1: Int, i2: Int) = x + i1
|
||||
}
|
||||
|
||||
fun inlineClass() {
|
||||
val unbounded = IC::f
|
||||
assertEquals(11, unbounded.callBy(mapOf(unbounded.instanceParameter!! to IC(10))))
|
||||
|
||||
val bounded = IC(10)::f
|
||||
assertEquals(11, bounded.callBy(mapOf()))
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
dataClass()
|
||||
inlineClass()
|
||||
valueClass()
|
||||
return "OK"
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// WITH_REFLECT
|
||||
// LANGUAGE: +ValueClasses
|
||||
// !JVM_DEFAULT_MODE: all
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.reflect.full.instanceParameter
|
||||
|
||||
interface I1 {
|
||||
fun f(i1: Int = 1, i2: Int): Int
|
||||
}
|
||||
|
||||
interface I2 {
|
||||
fun f(i1: Int, i2: Int = 2): Int
|
||||
}
|
||||
|
||||
data class DC(val x: Int, val y: Int) : I1, I2 {
|
||||
override fun f(i1: Int, i2: Int) = x + y + i1
|
||||
}
|
||||
|
||||
fun dataClass() {
|
||||
val unbounded = DC::f
|
||||
assertEquals(111, unbounded.callBy(mapOf(unbounded.instanceParameter!! to DC(10, 100))))
|
||||
|
||||
val bounded = DC(10, 100)::f
|
||||
assertEquals(111, bounded.callBy(mapOf()))
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class VC(val x: Int, val y: Int) : I1, I2 {
|
||||
override fun f(i1: Int, i2: Int) = x + y + i1
|
||||
}
|
||||
|
||||
fun valueClass() {
|
||||
val unbounded = VC::f
|
||||
assertEquals(111, unbounded.callBy(mapOf(unbounded.instanceParameter!! to VC(10, 100))))
|
||||
|
||||
val bounded = VC(10, 100)::f
|
||||
assertEquals(111, bounded.callBy(mapOf()))
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class IC(val x: Int) : I1, I2 {
|
||||
override fun f(i1: Int, i2: Int) = x + i1
|
||||
}
|
||||
|
||||
fun inlineClass() {
|
||||
val unbounded = IC::f
|
||||
assertEquals(11, unbounded.callBy(mapOf(unbounded.instanceParameter!! to IC(10))))
|
||||
|
||||
val bounded = IC(10)::f
|
||||
assertEquals(11, bounded.callBy(mapOf()))
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
dataClass()
|
||||
inlineClass()
|
||||
valueClass()
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// WITH_REFLECT
|
||||
// !JVM_DEFAULT_MODE: disable
|
||||
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.reflect.full.instanceParameter
|
||||
|
||||
|
||||
interface IIC {
|
||||
fun f(i1: Int = 1): Int
|
||||
}
|
||||
|
||||
inline class IC(val x: Int) : IIC {
|
||||
override fun f(i1: Int) = x + i1
|
||||
}
|
||||
|
||||
interface Outer {
|
||||
@JvmInline
|
||||
value class DefaultImpls(val x: Int) {
|
||||
fun f(i1: Int = 1) = x + i1
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val unbounded1 = IC::f
|
||||
assertEquals(3, unbounded1.callBy(mapOf(unbounded1.instanceParameter!! to IC(2))))
|
||||
assertEquals(7, unbounded1.callBy(mapOf(unbounded1.instanceParameter!! to IC(2), unbounded1.parameters[1] to 5)))
|
||||
|
||||
val bounded1 = IC(2)::f
|
||||
assertEquals(3, bounded1.callBy(mapOf()))
|
||||
assertEquals(7, bounded1.callBy(mapOf(bounded1.parameters.first() to 5)))
|
||||
|
||||
|
||||
val unbounded2 = Outer.DefaultImpls::f
|
||||
assertEquals(3, unbounded2.callBy(mapOf(unbounded2.instanceParameter!! to Outer.DefaultImpls(2))))
|
||||
assertEquals(7, unbounded2.callBy(mapOf(unbounded2.instanceParameter!! to Outer.DefaultImpls(2), unbounded2.parameters[1] to 5)))
|
||||
|
||||
val bounded2 = Outer.DefaultImpls(2)::f
|
||||
assertEquals(3, bounded2.callBy(mapOf()))
|
||||
assertEquals(7, bounded2.callBy(mapOf(bounded2.parameters.first() to 5)))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// WITH_REFLECT
|
||||
// !JVM_DEFAULT_MODE: all
|
||||
// IGNORE_BACKEND: ANDROID
|
||||
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.reflect.full.instanceParameter
|
||||
|
||||
|
||||
interface IIC {
|
||||
fun f(i1: Int = 1): Int
|
||||
}
|
||||
|
||||
inline class IC(val x: Int) : IIC {
|
||||
override fun f(i1: Int) = x + i1
|
||||
}
|
||||
|
||||
interface Outer {
|
||||
@JvmInline
|
||||
value class DefaultImpls(val x: Int) {
|
||||
fun f(i1: Int = 1) = x + i1
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val unbounded1 = IC::f
|
||||
assertEquals(3, unbounded1.callBy(mapOf(unbounded1.instanceParameter!! to IC(2))))
|
||||
assertEquals(7, unbounded1.callBy(mapOf(unbounded1.instanceParameter!! to IC(2), unbounded1.parameters[1] to 5)))
|
||||
|
||||
val bounded1 = IC(2)::f
|
||||
assertEquals(3, bounded1.callBy(mapOf()))
|
||||
assertEquals(7, bounded1.callBy(mapOf(bounded1.parameters.first() to 5)))
|
||||
|
||||
|
||||
val unbounded2 = Outer.DefaultImpls::f
|
||||
assertEquals(3, unbounded2.callBy(mapOf(unbounded2.instanceParameter!! to Outer.DefaultImpls(2))))
|
||||
assertEquals(7, unbounded2.callBy(mapOf(unbounded2.instanceParameter!! to Outer.DefaultImpls(2), unbounded2.parameters[1] to 5)))
|
||||
|
||||
val bounded2 = Outer.DefaultImpls(2)::f
|
||||
assertEquals(3, bounded2.callBy(mapOf()))
|
||||
assertEquals(7, bounded2.callBy(mapOf(bounded2.parameters.first() to 5)))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// WITH_REFLECT
|
||||
// LANGUAGE: +ValueClasses
|
||||
// !JVM_DEFAULT_MODE: disable
|
||||
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.reflect.full.instanceParameter
|
||||
|
||||
interface IVC {
|
||||
fun f(i1: Int = 1): Int
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class VC(val x: Int, val y: Int) : IVC {
|
||||
override fun f(i1: Int) = x + y + i1
|
||||
}
|
||||
|
||||
interface Outer {
|
||||
@JvmInline
|
||||
value class DefaultImpls(val x: Int, val y: Int) {
|
||||
fun f(i1: Int = 1) = x + y + i1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun box(): String {
|
||||
val unbounded1 = VC::f
|
||||
assertEquals(8, unbounded1.callBy(mapOf(unbounded1.instanceParameter!! to VC(2, 5))))
|
||||
assertEquals(12, unbounded1.callBy(mapOf(unbounded1.instanceParameter!! to VC(2, 5), unbounded1.parameters[1] to 5)))
|
||||
|
||||
val bounded1 = VC(2, 5)::f
|
||||
assertEquals(8, bounded1.callBy(mapOf()))
|
||||
assertEquals(12, bounded1.callBy(mapOf(bounded1.parameters.first() to 5)))
|
||||
|
||||
|
||||
val unbounded2 = Outer.DefaultImpls::f
|
||||
assertEquals(8, unbounded2.callBy(mapOf(unbounded2.instanceParameter!! to Outer.DefaultImpls(2, 5))))
|
||||
assertEquals(12, unbounded2.callBy(mapOf(unbounded2.instanceParameter!! to Outer.DefaultImpls(2, 5), unbounded2.parameters[1] to 5)))
|
||||
|
||||
val bounded2 = Outer.DefaultImpls(2, 5)::f
|
||||
assertEquals(8, bounded2.callBy(mapOf()))
|
||||
assertEquals(12, bounded2.callBy(mapOf(bounded2.parameters.first() to 5)))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// WITH_REFLECT
|
||||
// LANGUAGE: +ValueClasses
|
||||
// !JVM_DEFAULT_MODE: all
|
||||
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.reflect.full.instanceParameter
|
||||
|
||||
interface IVC {
|
||||
fun f(i1: Int = 1): Int
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class VC(val x: Int, val y: Int) : IVC {
|
||||
override fun f(i1: Int) = x + y + i1
|
||||
}
|
||||
|
||||
interface Outer {
|
||||
@JvmInline
|
||||
value class DefaultImpls(val x: Int, val y: Int) {
|
||||
fun f(i1: Int = 1) = x + y + i1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun box(): String {
|
||||
val unbounded1 = VC::f
|
||||
assertEquals(8, unbounded1.callBy(mapOf(unbounded1.instanceParameter!! to VC(2, 5))))
|
||||
assertEquals(12, unbounded1.callBy(mapOf(unbounded1.instanceParameter!! to VC(2, 5), unbounded1.parameters[1] to 5)))
|
||||
|
||||
val bounded1 = VC(2, 5)::f
|
||||
assertEquals(8, bounded1.callBy(mapOf()))
|
||||
assertEquals(12, bounded1.callBy(mapOf(bounded1.parameters.first() to 5)))
|
||||
|
||||
|
||||
val unbounded2 = Outer.DefaultImpls::f
|
||||
assertEquals(8, unbounded2.callBy(mapOf(unbounded2.instanceParameter!! to Outer.DefaultImpls(2, 5))))
|
||||
assertEquals(12, unbounded2.callBy(mapOf(unbounded2.instanceParameter!! to Outer.DefaultImpls(2, 5), unbounded2.parameters[1] to 5)))
|
||||
|
||||
val bounded2 = Outer.DefaultImpls(2, 5)::f
|
||||
assertEquals(8, bounded2.callBy(mapOf()))
|
||||
assertEquals(12, bounded2.callBy(mapOf(bounded2.parameters.first() to 5)))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+36
@@ -45580,6 +45580,18 @@ public class JvmAbiConsistencyTestBoxGenerated extends AbstractJvmAbiConsistency
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/boundJvmStaticInObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("brokenDefaultParametersFromDifferentFunctions.kt")
|
||||
public void testBrokenDefaultParametersFromDifferentFunctions() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/brokenDefaultParametersFromDifferentFunctions.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("brokenDefaultParametersFromDifferentFunctionsJvmDefault.kt")
|
||||
public void testBrokenDefaultParametersFromDifferentFunctionsJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/brokenDefaultParametersFromDifferentFunctionsJvmDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("companionObject.kt")
|
||||
public void testCompanionObject() throws Exception {
|
||||
@@ -45628,6 +45640,18 @@ public class JvmAbiConsistencyTestBoxGenerated extends AbstractJvmAbiConsistency
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassFunctionsAndConstructors.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClassInterface.kt")
|
||||
public void testInlineClassInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClassInterfaceJvmDefault.kt")
|
||||
public void testInlineClassInterfaceJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassInterfaceJvmDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClassMembers.kt")
|
||||
public void testInlineClassMembers() throws Exception {
|
||||
@@ -45694,6 +45718,18 @@ public class JvmAbiConsistencyTestBoxGenerated extends AbstractJvmAbiConsistency
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcFunctionsAndConstructors.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcInterface.kt")
|
||||
public void testMfvcInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcInterfaceJvmDefault.kt")
|
||||
public void testMfvcInterfaceJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcInterfaceJvmDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcKt61304.kt")
|
||||
public void testMfvcKt61304() throws Exception {
|
||||
|
||||
+36
@@ -45580,6 +45580,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/boundJvmStaticInObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("brokenDefaultParametersFromDifferentFunctions.kt")
|
||||
public void testBrokenDefaultParametersFromDifferentFunctions() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/brokenDefaultParametersFromDifferentFunctions.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("brokenDefaultParametersFromDifferentFunctionsJvmDefault.kt")
|
||||
public void testBrokenDefaultParametersFromDifferentFunctionsJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/brokenDefaultParametersFromDifferentFunctionsJvmDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("companionObject.kt")
|
||||
public void testCompanionObject() throws Exception {
|
||||
@@ -45628,6 +45640,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassFunctionsAndConstructors.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClassInterface.kt")
|
||||
public void testInlineClassInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClassInterfaceJvmDefault.kt")
|
||||
public void testInlineClassInterfaceJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassInterfaceJvmDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClassMembers.kt")
|
||||
public void testInlineClassMembers() throws Exception {
|
||||
@@ -45694,6 +45718,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcFunctionsAndConstructors.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcInterface.kt")
|
||||
public void testMfvcInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcInterfaceJvmDefault.kt")
|
||||
public void testMfvcInterfaceJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcInterfaceJvmDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcKt61304.kt")
|
||||
public void testMfvcKt61304() throws Exception {
|
||||
|
||||
+36
@@ -45580,6 +45580,18 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/boundJvmStaticInObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("brokenDefaultParametersFromDifferentFunctions.kt")
|
||||
public void testBrokenDefaultParametersFromDifferentFunctions() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/brokenDefaultParametersFromDifferentFunctions.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("brokenDefaultParametersFromDifferentFunctionsJvmDefault.kt")
|
||||
public void testBrokenDefaultParametersFromDifferentFunctionsJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/brokenDefaultParametersFromDifferentFunctionsJvmDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("companionObject.kt")
|
||||
public void testCompanionObject() throws Exception {
|
||||
@@ -45628,6 +45640,18 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassFunctionsAndConstructors.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClassInterface.kt")
|
||||
public void testInlineClassInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClassInterfaceJvmDefault.kt")
|
||||
public void testInlineClassInterfaceJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassInterfaceJvmDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClassMembers.kt")
|
||||
public void testInlineClassMembers() throws Exception {
|
||||
@@ -45694,6 +45718,18 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcFunctionsAndConstructors.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcInterface.kt")
|
||||
public void testMfvcInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcInterfaceJvmDefault.kt")
|
||||
public void testMfvcInterfaceJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcInterfaceJvmDefault.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mfvcKt61304.kt")
|
||||
public void testMfvcKt61304() throws Exception {
|
||||
|
||||
+30
@@ -36279,6 +36279,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/boundJvmStaticInObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("brokenDefaultParametersFromDifferentFunctions.kt")
|
||||
public void testBrokenDefaultParametersFromDifferentFunctions() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/brokenDefaultParametersFromDifferentFunctions.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("brokenDefaultParametersFromDifferentFunctionsJvmDefault.kt")
|
||||
public void testBrokenDefaultParametersFromDifferentFunctionsJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/brokenDefaultParametersFromDifferentFunctionsJvmDefault.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("companionObject.kt")
|
||||
public void testCompanionObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/companionObject.kt");
|
||||
@@ -36319,6 +36329,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassFunctionsAndConstructors.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineClassInterface.kt")
|
||||
public void testInlineClassInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassInterface.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineClassInterfaceJvmDefault.kt")
|
||||
public void testInlineClassInterfaceJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassInterfaceJvmDefault.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineClassMembers.kt")
|
||||
public void testInlineClassMembers() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/inlineClassMembers.kt");
|
||||
@@ -36374,6 +36394,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcFunctionsAndConstructors.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("mfvcInterface.kt")
|
||||
public void testMfvcInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcInterface.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("mfvcInterfaceJvmDefault.kt")
|
||||
public void testMfvcInterfaceJvmDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcInterfaceJvmDefault.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("mfvcKt61304.kt")
|
||||
public void testMfvcKt61304() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/callBy/mfvcKt61304.kt");
|
||||
|
||||
@@ -19,7 +19,10 @@ package kotlin.reflect.jvm.internal
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.overriddenTreeAsSequence
|
||||
import org.jetbrains.kotlin.resolve.isInlineClassType
|
||||
import org.jetbrains.kotlin.resolve.isMultiFieldValueClass
|
||||
import org.jetbrains.kotlin.resolve.isValueClass
|
||||
import org.jetbrains.kotlin.resolve.jvm.shouldHideConstructorDueToValueClassTypeValueParameters
|
||||
import java.lang.reflect.Constructor
|
||||
import java.lang.reflect.Member
|
||||
@@ -100,12 +103,17 @@ internal class KFunctionImpl private constructor(
|
||||
}
|
||||
|
||||
override val defaultCaller: Caller<*>? by lazy(PUBLICATION) defaultCaller@{
|
||||
val jvmSignature = RuntimeTypeMapper.mapSignature(descriptor)
|
||||
val member: Member? = when (jvmSignature) {
|
||||
is KotlinFunction -> {
|
||||
val member: Member? = when (val jvmSignature = RuntimeTypeMapper.mapSignature(descriptor)) {
|
||||
is KotlinFunction -> run {
|
||||
if (descriptor.let { it.containingDeclaration.isMultiFieldValueClass() && it is ConstructorDescriptor && it.isPrimary }) {
|
||||
throw KotlinReflectionInternalError("${descriptor.containingDeclaration} cannot have default arguments")
|
||||
}
|
||||
|
||||
getFunctionWithDefaultParametersForValueClassOverride(descriptor)?.let { defaultImplsFunction ->
|
||||
val replacingJvmSignature = RuntimeTypeMapper.mapSignature(defaultImplsFunction) as KotlinFunction
|
||||
return@run container.findDefaultMethod(replacingJvmSignature.methodName, replacingJvmSignature.methodDesc, true)
|
||||
}
|
||||
|
||||
container.findDefaultMethod(jvmSignature.methodName, jvmSignature.methodDesc, !Modifier.isStatic(caller.member!!.modifiers))
|
||||
}
|
||||
is KotlinConstructor -> {
|
||||
@@ -141,11 +149,32 @@ internal class KFunctionImpl private constructor(
|
||||
}?.createValueClassAwareCallerIfNeeded(descriptor, isDefault = true)
|
||||
}
|
||||
|
||||
private fun getFunctionWithDefaultParametersForValueClassOverride(descriptor: FunctionDescriptor): FunctionDescriptor? {
|
||||
if (
|
||||
descriptor.valueParameters.none { it.declaresDefaultValue() } &&
|
||||
descriptor.containingDeclaration.isValueClass() &&
|
||||
Modifier.isStatic(caller.member!!.modifiers)
|
||||
) {
|
||||
// firstOrNull is used to mimic the wrong behaviour of regular class reflection as KT-40327 is not fixed.
|
||||
// The behaviours equality is currently backed by codegen/box/reflection/callBy/brokenDefaultParametersFromDifferentFunctions.kt.
|
||||
return descriptor.overriddenTreeAsSequence(useOriginal = false)
|
||||
.firstOrNull { function -> function.valueParameters.any { it.declaresDefaultValue() } } as? FunctionDescriptor
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private val boundReceiver
|
||||
get() = rawBoundReceiver.coerceToExpectedReceiverType(descriptor)
|
||||
|
||||
// boundReceiver is unboxed receiver when the receiver is inline class.
|
||||
// However, when the expected dispatch receiver type is an interface,
|
||||
// the member belongs to the interface/DefaultImpls, so the receiver should not be unboxed.
|
||||
private fun useBoxedBoundReceiver(member: Method) =
|
||||
descriptor.dispatchReceiverParameter?.type?.isInlineClassType() == true && member.parameterTypes.firstOrNull()?.isInterface == true
|
||||
|
||||
private fun createStaticMethodCaller(member: Method) =
|
||||
if (isBound) CallerImpl.Method.BoundStatic(member, boundReceiver) else CallerImpl.Method.Static(member)
|
||||
if (isBound) CallerImpl.Method.BoundStatic(member, if (useBoxedBoundReceiver(member)) rawBoundReceiver else boundReceiver)
|
||||
else CallerImpl.Method.Static(member)
|
||||
|
||||
private fun createJvmStaticInObjectCaller(member: Method) =
|
||||
if (isBound) CallerImpl.Method.BoundJvmStaticInObject(member) else CallerImpl.Method.JvmStaticInObject(member)
|
||||
|
||||
@@ -27,7 +27,7 @@ internal class KParameterImpl(
|
||||
val callable: KCallableImpl<*>,
|
||||
override val index: Int,
|
||||
override val kind: KParameter.Kind,
|
||||
computeDescriptor: () -> ParameterDescriptor
|
||||
computeDescriptor: () -> ParameterDescriptor,
|
||||
) : KParameter {
|
||||
private val descriptor: ParameterDescriptor by ReflectProperties.lazySoft(computeDescriptor)
|
||||
|
||||
@@ -78,8 +78,14 @@ internal class KParameterImpl(
|
||||
} else {
|
||||
when (val caller = callable.caller) {
|
||||
is ValueClassAwareCaller -> {
|
||||
val slice = caller.getRealSlicesOfParameters(index)
|
||||
val parameterTypes = caller.parameterTypes.slice(slice)
|
||||
val parameterTypes = if (callable.isBound) {
|
||||
val slice = caller.getRealSlicesOfParameters(index + 1)
|
||||
val offset = caller.getRealSlicesOfParameters(0).last + 1
|
||||
caller.parameterTypes.slice((slice.first - offset)..(slice.last - offset))
|
||||
} else {
|
||||
val slice = caller.getRealSlicesOfParameters(index)
|
||||
caller.parameterTypes.slice(slice)
|
||||
}
|
||||
compoundType(*parameterTypes.toTypedArray())
|
||||
}
|
||||
is ValueClassAwareCaller.MultiFieldValueClassPrimaryConstructorCaller ->
|
||||
|
||||
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.SimpleType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.asSimpleType
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||
import java.lang.reflect.Member
|
||||
import java.lang.reflect.Method
|
||||
import java.lang.reflect.Type
|
||||
@@ -28,7 +29,7 @@ import kotlin.reflect.jvm.internal.toJavaClass
|
||||
|
||||
/**
|
||||
* A caller that is used whenever the declaration has value classes in its parameter types or inline class in return type.
|
||||
* Each argument of an value class type is unboxed, and the return value (if it's of an inline class type) is boxed.
|
||||
* Each argument of a value class type is unboxed, and the return value (if it's of an inline class type) is boxed.
|
||||
*/
|
||||
internal class ValueClassAwareCaller<out M : Member?>(
|
||||
descriptor: CallableMemberDescriptor,
|
||||
@@ -38,7 +39,11 @@ internal class ValueClassAwareCaller<out M : Member?>(
|
||||
|
||||
private val caller: Caller<M> = if (oldCaller is CallerImpl.Method.BoundStatic) {
|
||||
val receiverType = (descriptor.extensionReceiverParameter ?: descriptor.dispatchReceiverParameter)?.type
|
||||
if (receiverType != null && receiverType.needsMfvcFlattening()) {
|
||||
if (
|
||||
receiverType != null &&
|
||||
receiverType.needsMfvcFlattening() &&
|
||||
(!isDefault || descriptor.valueParameters.any { it.declaresDefaultValue() })
|
||||
) {
|
||||
val unboxMethods = getMfvcUnboxMethods(receiverType.asSimpleType())!!
|
||||
val boundReceiverComponents = unboxMethods.map { it.invoke(oldCaller.boundReceiver) }.toTypedArray()
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@@ -103,7 +108,7 @@ internal class ValueClassAwareCaller<out M : Member?>(
|
||||
|
||||
val flattenedShift = if (caller is CallerImpl.Method.BoundStaticMultiFieldValueClass) -caller.receiverComponentsCount else shift
|
||||
|
||||
val kotlinParameterTypes: List<KotlinType> = makeKotlinParameterTypes(descriptor) { isValueClass() }
|
||||
val kotlinParameterTypes: List<KotlinType> = makeKotlinParameterTypes(descriptor, caller.member) { isValueClass() }
|
||||
|
||||
fun typeSize(type: KotlinType): Int = getMfvcUnboxMethods(type.asSimpleType())?.size ?: 1
|
||||
|
||||
@@ -184,7 +189,7 @@ internal class ValueClassAwareCaller<out M : Member?>(
|
||||
if (index in range) {
|
||||
val method = unbox[index]?.single()
|
||||
val arg = args[index]
|
||||
// Note that arg may be null in case we're calling a $default method, and it's an optional parameter of a inline class type
|
||||
// Note that arg may be null in case we're calling a $default method, and it's an optional parameter of an inline class type
|
||||
when {
|
||||
method == null -> arg
|
||||
arg != null -> method.invoke(arg)
|
||||
@@ -270,7 +275,7 @@ private fun Caller<*>.checkParametersSize(
|
||||
}
|
||||
|
||||
private fun makeKotlinParameterTypes(
|
||||
descriptor: CallableMemberDescriptor, isSpecificClass: ClassDescriptor.() -> Boolean
|
||||
descriptor: CallableMemberDescriptor, member: Member?, isSpecificClass: ClassDescriptor.() -> Boolean
|
||||
): List<KotlinType> = ArrayList<KotlinType>().also { kotlinParameterTypes ->
|
||||
val extensionReceiverType = descriptor.extensionReceiverParameter?.type
|
||||
if (extensionReceiverType != null) {
|
||||
@@ -283,13 +288,32 @@ private fun makeKotlinParameterTypes(
|
||||
} else {
|
||||
val containingDeclaration = descriptor.containingDeclaration
|
||||
if (containingDeclaration is ClassDescriptor && containingDeclaration.isSpecificClass()) {
|
||||
kotlinParameterTypes.add(containingDeclaration.defaultType)
|
||||
if (member?.acceptsBoxedReceiverParameter() == true) {
|
||||
// hack to forbid unboxing dispatchReceiver if it is used upcasted
|
||||
// kotlinParameterTypes are used to determine shifts and calls according to whether type is MFVC/IC or not.
|
||||
// If it is a MFVC/IC, boxes are unboxed. If the actual called member lies in the interface/DefaultImpls class,
|
||||
// it accepts a boxed parameter as ex-dispatch receiver. Making the type nullable allows to prevent unboxing in this case.
|
||||
kotlinParameterTypes.add(containingDeclaration.defaultType.makeNullable())
|
||||
} else {
|
||||
kotlinParameterTypes.add(containingDeclaration.defaultType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
descriptor.valueParameters.mapTo(kotlinParameterTypes, ValueParameterDescriptor::getType)
|
||||
}
|
||||
|
||||
private fun Member.acceptsBoxedReceiverParameter(): Boolean {
|
||||
// Method implementation can be placed either in
|
||||
// * the value class itself,
|
||||
// * interface$DefaultImpls,
|
||||
// * interface default method (Java 8+).
|
||||
// Here we need to understand that it is the second or the third case. Both of the cases cannot be value classes,
|
||||
// so the simplest solution is to check declaringClass for being a value class.
|
||||
val clazz = declaringClass ?: return false
|
||||
return !clazz.kotlin.isValue
|
||||
}
|
||||
|
||||
internal fun <M : Member?> Caller<M>.createValueClassAwareCallerIfNeeded(
|
||||
descriptor: CallableMemberDescriptor,
|
||||
isDefault: Boolean = false
|
||||
|
||||
Reference in New Issue
Block a user