diff --git a/compiler/testData/codegen/box/reflection/callBy/manyArgumentsNoneDefaultConstructor.kt b/compiler/testData/codegen/box/reflection/callBy/manyArgumentsNoneDefaultConstructor.kt new file mode 100644 index 00000000000..1a99569f436 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/callBy/manyArgumentsNoneDefaultConstructor.kt @@ -0,0 +1,99 @@ +// IGNORE_BACKEND: JS, NATIVE +// WITH_REFLECT + +import kotlin.test.assertEquals + +// Generate: +// (1..70).map { " p${"%02d".format(it)}: Int," }.joinToString("\n") + +class A( + p01: Int, + p02: Int, + p03: Int, + p04: Int, + p05: Int, + p06: Int, + p07: Int, + p08: Int, + p09: Int, + p10: Int, + p11: Int, + p12: Int, + p13: Int, + p14: Int, + p15: Int, + p16: Int, + p17: Int, + p18: Int, + p19: Int, + p20: Int, + p21: Int, + p22: Int, + p23: Int, + p24: Int, + p25: Int, + p26: Int, + p27: Int, + p28: Int, + p29: Int, + p30: Int, + p31: Int, + p32: Int, + p33: Int, + p34: Int, + p35: Int, + p36: Int, + p37: Int, + p38: Int, + p39: Int, + p40: Int, + p41: Int, + p42: Int, + p43: Int, + p44: Int, + p45: Int, + p46: Int, + p47: Int, + p48: Int, + p49: Int, + p50: Int, + p51: Int, + p52: Int, + p53: Int, + p54: Int, + p55: Int, + p56: Int, + p57: Int, + p58: Int, + p59: Int, + p60: Int, + p61: Int, + p62: Int, + p63: Int, + p64: Int, + p65: Int, + p66: Int, + p67: Int, + p68: Int, + p69: Int, + p70: Int +) { + init { + assertEquals(1, p01) + assertEquals(41, p41) + assertEquals(42, p42) + assertEquals(43, p43) + assertEquals(70, p70) + } +} + +fun box(): String { + val f = A::class.constructors.single() + val parameters = f.parameters + + f.callBy(mapOf( + *((1..70)).map { i -> parameters[i - 1] to i }.toTypedArray() + )) + + return "OK" +} diff --git a/compiler/testData/codegen/box/reflection/callBy/manyArgumentsNoneDefaultFunction.kt b/compiler/testData/codegen/box/reflection/callBy/manyArgumentsNoneDefaultFunction.kt new file mode 100644 index 00000000000..e316997b26f --- /dev/null +++ b/compiler/testData/codegen/box/reflection/callBy/manyArgumentsNoneDefaultFunction.kt @@ -0,0 +1,100 @@ +// IGNORE_BACKEND: JS, NATIVE +// WITH_REFLECT + +import kotlin.test.assertEquals + +// Generate: +// (1..70).map { " p${"%02d".format(it)}: Int," }.joinToString("\n") + +class A { + fun foo( + p01: Int, + p02: Int, + p03: Int, + p04: Int, + p05: Int, + p06: Int, + p07: Int, + p08: Int, + p09: Int, + p10: Int, + p11: Int, + p12: Int, + p13: Int, + p14: Int, + p15: Int, + p16: Int, + p17: Int, + p18: Int, + p19: Int, + p20: Int, + p21: Int, + p22: Int, + p23: Int, + p24: Int, + p25: Int, + p26: Int, + p27: Int, + p28: Int, + p29: Int, + p30: Int, + p31: Int, + p32: Int, + p33: Int, + p34: Int, + p35: Int, + p36: Int, + p37: Int, + p38: Int, + p39: Int, + p40: Int, + p41: Int, + p42: Int, + p43: Int, + p44: Int, + p45: Int, + p46: Int, + p47: Int, + p48: Int, + p49: Int, + p50: Int, + p51: Int, + p52: Int, + p53: Int, + p54: Int, + p55: Int, + p56: Int, + p57: Int, + p58: Int, + p59: Int, + p60: Int, + p61: Int, + p62: Int, + p63: Int, + p64: Int, + p65: Int, + p66: Int, + p67: Int, + p68: Int, + p69: Int, + p70: Int + ) { + assertEquals(1, p01) + assertEquals(41, p41) + assertEquals(42, p42) + assertEquals(43, p43) + assertEquals(70, p70) + } +} + +fun box(): String { + val f = A::class.members.single { it.name == "foo" } + val parameters = f.parameters + + f.callBy(mapOf( + parameters.first() to A(), + *((1..70)).map { i -> parameters[i] to i }.toTypedArray() + )) + + return "OK" +} diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index ea6d4ee56ea..5402f760d3a 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -14176,6 +14176,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("manyArgumentsNoneDefaultConstructor.kt") + public void testManyArgumentsNoneDefaultConstructor() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/callBy/manyArgumentsNoneDefaultConstructor.kt"); + doTest(fileName); + } + + @TestMetadata("manyArgumentsNoneDefaultFunction.kt") + public void testManyArgumentsNoneDefaultFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/callBy/manyArgumentsNoneDefaultFunction.kt"); + doTest(fileName); + } + @TestMetadata("manyArgumentsOnlyOneDefault.kt") public void testManyArgumentsOnlyOneDefault() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/callBy/manyArgumentsOnlyOneDefault.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 657f7f7447e..04f6b2e6851 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -14176,6 +14176,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("manyArgumentsNoneDefaultConstructor.kt") + public void testManyArgumentsNoneDefaultConstructor() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/callBy/manyArgumentsNoneDefaultConstructor.kt"); + doTest(fileName); + } + + @TestMetadata("manyArgumentsNoneDefaultFunction.kt") + public void testManyArgumentsNoneDefaultFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/callBy/manyArgumentsNoneDefaultFunction.kt"); + doTest(fileName); + } + @TestMetadata("manyArgumentsOnlyOneDefault.kt") public void testManyArgumentsOnlyOneDefault() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/callBy/manyArgumentsOnlyOneDefault.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 6c263635ada..2a0f9f9c5e7 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -14176,6 +14176,18 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes doTest(fileName); } + @TestMetadata("manyArgumentsNoneDefaultConstructor.kt") + public void testManyArgumentsNoneDefaultConstructor() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/callBy/manyArgumentsNoneDefaultConstructor.kt"); + doTest(fileName); + } + + @TestMetadata("manyArgumentsNoneDefaultFunction.kt") + public void testManyArgumentsNoneDefaultFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/callBy/manyArgumentsNoneDefaultFunction.kt"); + doTest(fileName); + } + @TestMetadata("manyArgumentsOnlyOneDefault.kt") public void testManyArgumentsOnlyOneDefault() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/callBy/manyArgumentsOnlyOneDefault.kt"); diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KCallableImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KCallableImpl.kt index cc648a1489e..96f215593c4 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KCallableImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KCallableImpl.kt @@ -118,6 +118,7 @@ internal abstract class KCallableImpl : KCallable { var mask = 0 val masks = ArrayList(1) var index = 0 + var anyOptional = false for (parameter in parameters) { if (index != 0 && index % Integer.SIZE == 0) { @@ -132,6 +133,7 @@ internal abstract class KCallableImpl : KCallable { parameter.isOptional -> { arguments.add(defaultPrimitiveValue(parameter.type.javaType)) mask = mask or (1 shl (index % Integer.SIZE)) + anyOptional = true } else -> { throw IllegalArgumentException("No argument provided for a required parameter: $parameter") @@ -143,7 +145,7 @@ internal abstract class KCallableImpl : KCallable { } } - if (mask == 0 && masks.isEmpty()) { + if (!anyOptional) { return call(*arguments.toTypedArray()) } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 7717bc597dc..d2b3b149800 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -16306,6 +16306,30 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); } + @TestMetadata("manyArgumentsNoneDefaultConstructor.kt") + public void testManyArgumentsNoneDefaultConstructor() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/callBy/manyArgumentsNoneDefaultConstructor.kt"); + try { + doTest(fileName); + } + catch (Throwable ignore) { + return; + } + throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); + } + + @TestMetadata("manyArgumentsNoneDefaultFunction.kt") + public void testManyArgumentsNoneDefaultFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/callBy/manyArgumentsNoneDefaultFunction.kt"); + try { + doTest(fileName); + } + catch (Throwable ignore) { + return; + } + throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); + } + @TestMetadata("manyArgumentsOnlyOneDefault.kt") public void testManyArgumentsOnlyOneDefault() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/callBy/manyArgumentsOnlyOneDefault.kt");