[FIR] Keep vararg argument order in resolved calls (KT-17691).
This commit is contained in:
committed by
teamcityserver
parent
f6ce2d893c
commit
eb631bc429
Generated
+15
@@ -13016,6 +13016,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/increment/classVarargGetSet.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("classVarargGetSetEvaluationOrder.kt")
|
||||
public void testClassVarargGetSetEvaluationOrder() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/increment/classVarargGetSetEvaluationOrder.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("classWithGetSet.kt")
|
||||
public void testClassWithGetSet() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/increment/classWithGetSet.kt");
|
||||
@@ -17861,6 +17866,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
public void testVarargs() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/mixedNamedPosition/varargs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("varargsEvaluationOrder.kt")
|
||||
public void testVarargsEvaluationOrder() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/mixedNamedPosition/varargsEvaluationOrder.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/multiDecl")
|
||||
@@ -31536,6 +31546,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/vararg/emptyVarargOfBoxedPrimitiveType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("evaluationOrder.kt")
|
||||
public void testEvaluationOrder() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/vararg/evaluationOrder.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt1978.kt")
|
||||
public void testKt1978() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/vararg/kt1978.kt");
|
||||
|
||||
+2
@@ -29,6 +29,8 @@ data class ArgumentMapping(
|
||||
// fun foo(a: Int, b: Int) {}
|
||||
// foo(b = bar(), a = qux())
|
||||
// parameterToCallArgumentMap.values() should be [ 'bar()', 'foo()' ]
|
||||
// TODO: Consider changing this (and other similar declarations like Candidate.argumentMapping) to LinkedHashMap to signify that
|
||||
// order is important. Right now we're assuming that mutableMapOf() will always return a LinkedHashMap.
|
||||
val parameterToCallArgumentMap: Map<FirValueParameter, ResolvedCallArgument>,
|
||||
val oldToNewArgumentMap: Map<FirExpression, FirExpression>,
|
||||
val diagnostics: List<ResolutionDiagnostic>
|
||||
|
||||
+18
-4
@@ -40,10 +40,12 @@ internal fun remapArgumentsWithVararg(
|
||||
argumentList: FirArgumentList,
|
||||
argumentMapping: Map<FirExpression, FirValueParameter>
|
||||
): Map<FirExpression, FirValueParameter> {
|
||||
// Create a FirVarargArgumentExpression for the vararg arguments
|
||||
// Create a FirVarargArgumentExpression for the vararg arguments.
|
||||
// The order of arguments in the mapping must be preserved for FIR2IR, hence we have to find where the vararg arguments end.
|
||||
// FIR2IR uses the mapping order to determine if arguments need to be reordered.
|
||||
val varargParameterTypeRef = varargParameter.returnTypeRef
|
||||
val varargElementType = varargArrayType.arrayElementType()
|
||||
var firstIndex = argumentList.arguments.size
|
||||
var indexAfterVarargs = argumentList.arguments.size
|
||||
val newArgumentMapping = mutableMapOf<FirExpression, FirValueParameter>()
|
||||
val varargArgument = buildVarargArgumentsExpression {
|
||||
this.varargElementType = varargParameterTypeRef.withReplacedConeType(varargElementType)
|
||||
@@ -51,14 +53,26 @@ internal fun remapArgumentsWithVararg(
|
||||
for ((i, arg) in argumentList.arguments.withIndex()) {
|
||||
val valueParameter = argumentMapping[arg] ?: continue
|
||||
if (valueParameter.isVararg) {
|
||||
firstIndex = min(firstIndex, i)
|
||||
// `arg` is a vararg argument.
|
||||
arguments += arg
|
||||
} else {
|
||||
} else if (arguments.isEmpty()) {
|
||||
// `arg` is BEFORE the vararg arguments.
|
||||
newArgumentMapping[arg] = valueParameter
|
||||
} else {
|
||||
// `arg` is AFTER the vararg arguments.
|
||||
indexAfterVarargs = i
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
newArgumentMapping[varargArgument] = varargParameter
|
||||
|
||||
// Add mapping for arguments after the vararg arguments, if any.
|
||||
for (i in indexAfterVarargs until argumentList.arguments.size) {
|
||||
val arg = argumentList.arguments[i]
|
||||
val valueParameter = argumentMapping[arg] ?: continue
|
||||
newArgumentMapping[arg] = valueParameter
|
||||
}
|
||||
return newArgumentMapping
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user