[Reflection] Support callBy for inline class interface functions with default parameters

#KT-57972
This commit is contained in:
Evgeniy.Zhelenskiy
2024-01-29 04:04:59 +00:00
committed by Space Team
parent 1e7cc00dcb
commit b0367d9399
18 changed files with 691 additions and 13 deletions
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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"
}
@@ -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"
}
@@ -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"
}
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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