KT-37779 Treat named value arguments in vararg as arguments with '*'
This commit is contained in:
@@ -3141,15 +3141,16 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
List<ValueArgument> arguments = valueArgument.getArguments();
|
List<ValueArgument> arguments = valueArgument.getArguments();
|
||||||
int size = arguments.size();
|
int size = arguments.size();
|
||||||
|
|
||||||
boolean hasSpread = false;
|
// Named arguments in vararg are treated as having an implicit spread operator.
|
||||||
for (int i = 0; i != size; ++i) {
|
// There can be only single such argument for a given vararg parameter, but here it doesn't really matter:
|
||||||
if (arguments.get(i).getSpreadElement() != null) {
|
// we'll just build a copy of array as if an array argument was passed as positional with an explicit spread operator.
|
||||||
hasSpread = true;
|
boolean hasSpreadOperator =
|
||||||
break;
|
state.getLanguageVersionSettings()
|
||||||
}
|
.supportsFeature(LanguageFeature.AllowAssigningArrayElementsToVarargsInNamedFormForFunctions)
|
||||||
}
|
? arguments.stream().anyMatch(argument -> argument.getSpreadElement() != null || argument.isNamed())
|
||||||
|
: arguments.stream().anyMatch(argument -> argument.getSpreadElement() != null);
|
||||||
|
|
||||||
if (hasSpread) {
|
if (hasSpreadOperator) {
|
||||||
boolean arrayOfReferences = KotlinBuiltIns.isArray(outType);
|
boolean arrayOfReferences = KotlinBuiltIns.isArray(outType);
|
||||||
if (size == 1) {
|
if (size == 1) {
|
||||||
Type arrayType = getArrayType(arrayOfReferences ? AsmTypes.OBJECT_TYPE : elementType);
|
Type arrayType = getArrayType(arrayOfReferences ? AsmTypes.OBJECT_TYPE : elementType);
|
||||||
|
|||||||
Generated
+5
@@ -27974,6 +27974,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/vararg/kt1978.kt");
|
runTest("compiler/testData/codegen/box/vararg/kt1978.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt37779.kt")
|
||||||
|
public void testKt37779() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/vararg/kt37779.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt581.kt")
|
@TestMetadata("kt581.kt")
|
||||||
public void testKt581() throws Exception {
|
public void testKt581() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/vararg/kt581.kt");
|
runTest("compiler/testData/codegen/box/vararg/kt581.kt");
|
||||||
|
|||||||
+5
@@ -1087,6 +1087,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
|
|||||||
runTest("compiler/testData/ir/irText/expressions/kt37570.kt");
|
runTest("compiler/testData/ir/irText/expressions/kt37570.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt37779.kt")
|
||||||
|
public void testKt37779() throws Exception {
|
||||||
|
runTest("compiler/testData/ir/irText/expressions/kt37779.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("lambdaInCAO.kt")
|
@TestMetadata("lambdaInCAO.kt")
|
||||||
public void testLambdaInCAO() throws Exception {
|
public void testLambdaInCAO() throws Exception {
|
||||||
runTest("compiler/testData/ir/irText/expressions/lambdaInCAO.kt");
|
runTest("compiler/testData/ir/irText/expressions/lambdaInCAO.kt");
|
||||||
|
|||||||
+5
-1
@@ -262,7 +262,11 @@ fun StatementGenerator.generateVarargExpressionUsing(
|
|||||||
val irArgumentExpression = generateArgumentExpression(ktArgumentExpression)
|
val irArgumentExpression = generateArgumentExpression(ktArgumentExpression)
|
||||||
?: throw AssertionError("'generateArgumentExpression' should return non-null for vararg element ${ktArgumentExpression.text}")
|
?: throw AssertionError("'generateArgumentExpression' should return non-null for vararg element ${ktArgumentExpression.text}")
|
||||||
val irVarargElement =
|
val irVarargElement =
|
||||||
if (argument.getSpreadElement() != null)
|
if (argument.getSpreadElement() != null ||
|
||||||
|
context.languageVersionSettings
|
||||||
|
.supportsFeature(LanguageFeature.AllowAssigningArrayElementsToVarargsInNamedFormForFunctions) &&
|
||||||
|
argument.isNamed()
|
||||||
|
)
|
||||||
IrSpreadElementImpl(
|
IrSpreadElementImpl(
|
||||||
ktArgumentExpression.startOffsetSkippingComments, ktArgumentExpression.endOffset,
|
ktArgumentExpression.startOffsetSkippingComments, ktArgumentExpression.endOffset,
|
||||||
irArgumentExpression
|
irArgumentExpression
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// !LANGUAGE: +AllowAssigningArrayElementsToVarargsInNamedFormForFunctions
|
||||||
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
|
// IGNORE_BACKEND: JS
|
||||||
|
|
||||||
|
fun test(vararg s: String) = s[1]
|
||||||
|
|
||||||
|
fun box(): String =
|
||||||
|
test(s = arrayOf("", "OK"))
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// !LANGUAGE: -ProhibitAssigningSingleElementsToVarargsInNamedForm
|
// !LANGUAGE: -ProhibitAssigningSingleElementsToVarargsInNamedForm -AllowAssigningArrayElementsToVarargsInNamedFormForFunctions
|
||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
FILE fqName:<root> fileName:/kt37779.kt
|
||||||
|
FUN name:foo visibility:public modality:FINAL <> (s:kotlin.Array<out kotlin.String>) returnType:kotlin.Unit
|
||||||
|
VALUE_PARAMETER name:s index:0 type:kotlin.Array<out kotlin.String> varargElementType:kotlin.String [vararg]
|
||||||
|
BLOCK_BODY
|
||||||
|
FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||||
|
BLOCK_BODY
|
||||||
|
CALL 'public final fun foo (vararg s: kotlin.String): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||||
|
s: VARARG type=kotlin.Array<out kotlin.String> varargElementType=kotlin.String
|
||||||
|
CALL 'public final fun arrayOf <T> (vararg elements: T of kotlin.arrayOf): kotlin.Array<T of kotlin.arrayOf> [inline] declared in kotlin' type=kotlin.Array<kotlin.String> origin=null
|
||||||
|
<T>: kotlin.String
|
||||||
|
elements: VARARG type=kotlin.Array<out kotlin.String> varargElementType=kotlin.String
|
||||||
|
CONST String type=kotlin.String value=""
|
||||||
|
CONST String type=kotlin.String value="OK"
|
||||||
|
FUN name:test2 visibility:public modality:FINAL <> (ss:kotlin.Array<kotlin.String>) returnType:kotlin.Unit
|
||||||
|
VALUE_PARAMETER name:ss index:0 type:kotlin.Array<kotlin.String>
|
||||||
|
BLOCK_BODY
|
||||||
|
CALL 'public final fun foo (vararg s: kotlin.String): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||||
|
s: VARARG type=kotlin.Array<out kotlin.String> varargElementType=kotlin.String
|
||||||
|
GET_VAR 'ss: kotlin.Array<kotlin.String> declared in <root>.test2' type=kotlin.Array<kotlin.String> origin=null
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// !LANGUAGE: +AllowAssigningArrayElementsToVarargsInNamedFormForFunctions
|
||||||
|
fun foo(vararg s: String) {}
|
||||||
|
|
||||||
|
fun test1() {
|
||||||
|
foo(s = arrayOf("", "OK"))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test2(ss: Array<String>) {
|
||||||
|
foo(s = ss)
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
FILE fqName:<root> fileName:/kt37779.kt
|
||||||
|
FUN name:foo visibility:public modality:FINAL <> (s:kotlin.Array<out kotlin.String>) returnType:kotlin.Unit
|
||||||
|
VALUE_PARAMETER name:s index:0 type:kotlin.Array<out kotlin.String> varargElementType:kotlin.String [vararg]
|
||||||
|
BLOCK_BODY
|
||||||
|
FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||||
|
BLOCK_BODY
|
||||||
|
CALL 'public final fun foo (vararg s: kotlin.String): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||||
|
s: VARARG type=kotlin.Array<out kotlin.String> varargElementType=kotlin.String
|
||||||
|
SPREAD_ELEMENT
|
||||||
|
CALL 'public final fun arrayOf <T> (vararg elements: T of kotlin.arrayOf): kotlin.Array<T of kotlin.arrayOf> [inline] declared in kotlin' type=kotlin.Array<kotlin.String> origin=null
|
||||||
|
<T>: kotlin.String
|
||||||
|
elements: VARARG type=kotlin.Array<out kotlin.String> varargElementType=kotlin.String
|
||||||
|
CONST String type=kotlin.String value=""
|
||||||
|
CONST String type=kotlin.String value="OK"
|
||||||
|
FUN name:test2 visibility:public modality:FINAL <> (ss:kotlin.Array<kotlin.String>) returnType:kotlin.Unit
|
||||||
|
VALUE_PARAMETER name:ss index:0 type:kotlin.Array<kotlin.String>
|
||||||
|
BLOCK_BODY
|
||||||
|
CALL 'public final fun foo (vararg s: kotlin.String): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||||
|
s: VARARG type=kotlin.Array<out kotlin.String> varargElementType=kotlin.String
|
||||||
|
SPREAD_ELEMENT
|
||||||
|
GET_VAR 'ss: kotlin.Array<kotlin.String> declared in <root>.test2' type=kotlin.Array<kotlin.String> origin=null
|
||||||
+5
@@ -29535,6 +29535,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/vararg/kt1978.kt");
|
runTest("compiler/testData/codegen/box/vararg/kt1978.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt37779.kt")
|
||||||
|
public void testKt37779() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/vararg/kt37779.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt581.kt")
|
@TestMetadata("kt581.kt")
|
||||||
public void testKt581() throws Exception {
|
public void testKt581() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/vararg/kt581.kt");
|
runTest("compiler/testData/codegen/box/vararg/kt581.kt");
|
||||||
|
|||||||
+10
-5
@@ -17611,6 +17611,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class Optimized extends AbstractLightAnalysisModeTest {
|
public static class Optimized extends AbstractLightAnalysisModeTest {
|
||||||
|
@TestMetadata("callableReferencesToSamePropertiesFromDifferentPackages.kt")
|
||||||
|
public void ignoreCallableReferencesToSamePropertiesFromDifferentPackages() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/multifileClasses/optimized/callableReferencesToSamePropertiesFromDifferentPackages.kt");
|
||||||
|
}
|
||||||
|
|
||||||
private void runTest(String testDataFilePath) throws Exception {
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||||
}
|
}
|
||||||
@@ -17649,11 +17654,6 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/multifileClasses/optimized/callableReferencesToSameFunctionsFromDifferentPackages.kt");
|
runTest("compiler/testData/codegen/box/multifileClasses/optimized/callableReferencesToSameFunctionsFromDifferentPackages.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("callableReferencesToSamePropertiesFromDifferentPackages.kt")
|
|
||||||
public void testCallableReferencesToSamePropertiesFromDifferentPackages() throws Exception {
|
|
||||||
runTest("compiler/testData/codegen/box/multifileClasses/optimized/callableReferencesToSamePropertiesFromDifferentPackages.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("calls.kt")
|
@TestMetadata("calls.kt")
|
||||||
public void testCalls() throws Exception {
|
public void testCalls() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/multifileClasses/optimized/calls.kt");
|
runTest("compiler/testData/codegen/box/multifileClasses/optimized/calls.kt");
|
||||||
@@ -28352,6 +28352,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/vararg/kt1978.kt");
|
runTest("compiler/testData/codegen/box/vararg/kt1978.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt37779.kt")
|
||||||
|
public void testKt37779() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/vararg/kt37779.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt581.kt")
|
@TestMetadata("kt581.kt")
|
||||||
public void testKt581() throws Exception {
|
public void testKt581() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/vararg/kt581.kt");
|
runTest("compiler/testData/codegen/box/vararg/kt581.kt");
|
||||||
|
|||||||
+5
@@ -27974,6 +27974,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/vararg/kt1978.kt");
|
runTest("compiler/testData/codegen/box/vararg/kt1978.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt37779.kt")
|
||||||
|
public void testKt37779() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/vararg/kt37779.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt581.kt")
|
@TestMetadata("kt581.kt")
|
||||||
public void testKt581() throws Exception {
|
public void testKt581() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/vararg/kt581.kt");
|
runTest("compiler/testData/codegen/box/vararg/kt581.kt");
|
||||||
|
|||||||
@@ -1086,6 +1086,11 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
|
|||||||
runTest("compiler/testData/ir/irText/expressions/kt37570.kt");
|
runTest("compiler/testData/ir/irText/expressions/kt37570.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt37779.kt")
|
||||||
|
public void testKt37779() throws Exception {
|
||||||
|
runTest("compiler/testData/ir/irText/expressions/kt37779.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("lambdaInCAO.kt")
|
@TestMetadata("lambdaInCAO.kt")
|
||||||
public void testLambdaInCAO() throws Exception {
|
public void testLambdaInCAO() throws Exception {
|
||||||
runTest("compiler/testData/ir/irText/expressions/lambdaInCAO.kt");
|
runTest("compiler/testData/ir/irText/expressions/lambdaInCAO.kt");
|
||||||
|
|||||||
Generated
+5
@@ -22795,6 +22795,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/vararg/kt1978.kt");
|
runTest("compiler/testData/codegen/box/vararg/kt1978.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt37779.kt")
|
||||||
|
public void testKt37779() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/vararg/kt37779.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt581.kt")
|
@TestMetadata("kt581.kt")
|
||||||
public void testKt581() throws Exception {
|
public void testKt581() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/vararg/kt581.kt");
|
runTest("compiler/testData/codegen/box/vararg/kt581.kt");
|
||||||
|
|||||||
+5
@@ -22855,6 +22855,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/vararg/kt1978.kt");
|
runTest("compiler/testData/codegen/box/vararg/kt1978.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt37779.kt")
|
||||||
|
public void testKt37779() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/vararg/kt37779.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt581.kt")
|
@TestMetadata("kt581.kt")
|
||||||
public void testKt581() throws Exception {
|
public void testKt581() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/vararg/kt581.kt");
|
runTest("compiler/testData/codegen/box/vararg/kt581.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user