[FIR] Introduce FirResolvedArgumentList with argument-parameter mapping
#KT-36345 Fixed
This commit is contained in:
@@ -542,6 +542,20 @@ class Fir2IrVisitor(
|
|||||||
val argumentsCount = call.arguments.size
|
val argumentsCount = call.arguments.size
|
||||||
if (argumentsCount <= valueArgumentsCount) {
|
if (argumentsCount <= valueArgumentsCount) {
|
||||||
apply {
|
apply {
|
||||||
|
val argumentMapping = call.argumentMapping
|
||||||
|
if (argumentMapping != null && argumentMapping.isNotEmpty()) {
|
||||||
|
require(call is FirFunctionCall)
|
||||||
|
val function =
|
||||||
|
((call.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirFunctionSymbol<*>)?.fir
|
||||||
|
val valueParameters = function?.valueParameters
|
||||||
|
if (valueParameters != null) {
|
||||||
|
for ((argument, parameter) in argumentMapping) {
|
||||||
|
val argumentExpression = argument.toIrExpression()
|
||||||
|
putValueArgument(valueParameters.indexOf(parameter), argumentExpression)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
for ((index, argument) in call.arguments.withIndex()) {
|
for ((index, argument) in call.arguments.withIndex()) {
|
||||||
val argumentExpression = argument.toIrExpression()
|
val argumentExpression = argument.toIrExpression()
|
||||||
putValueArgument(index, argumentExpression)
|
putValueArgument(index, argumentExpression)
|
||||||
|
|||||||
+11
-12
@@ -181,15 +181,16 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
else -> {
|
else -> {
|
||||||
resultType = typeRef.substituteTypeRef(subCandidate)
|
resultType = typeRef.substituteTypeRef(subCandidate)
|
||||||
val argumentMapping = subCandidate.argumentMapping
|
val argumentMapping = subCandidate.argumentMapping
|
||||||
val vararg = argumentMapping?.values?.firstOrNull { it.isVararg }
|
val varargParameter = argumentMapping?.values?.firstOrNull { it.isVararg }
|
||||||
result.argumentList.transformArguments(this, subCandidate.createArgumentsMapping())
|
result.argumentList.transformArguments(this, subCandidate.createArgumentsMapping())
|
||||||
with(result.argumentList) call@{
|
with(result.argumentList) call@{
|
||||||
if (vararg != null) {
|
if (varargParameter != null) {
|
||||||
// Create a FirVarargArgumentExpression for the vararg arguments
|
// Create a FirVarargArgumentExpression for the vararg arguments
|
||||||
val varargParameterTypeRef = vararg.returnTypeRef
|
val varargParameterTypeRef = varargParameter.returnTypeRef
|
||||||
val resolvedArrayType = varargParameterTypeRef.substitute(subCandidate)
|
val resolvedArrayType = varargParameterTypeRef.substitute(subCandidate)
|
||||||
val resolvedElementType = resolvedArrayType.arrayElementType(session)
|
val resolvedElementType = resolvedArrayType.arrayElementType(session)
|
||||||
var firstIndex = this@call.arguments.size
|
var firstIndex = this@call.arguments.size
|
||||||
|
val newArgumentMapping = mutableMapOf<FirExpression, FirValueParameter>()
|
||||||
val varargArgument = buildVarargArgumentsExpression {
|
val varargArgument = buildVarargArgumentsExpression {
|
||||||
varargElementType = varargParameterTypeRef.withReplacedConeType(resolvedElementType)
|
varargElementType = varargParameterTypeRef.withReplacedConeType(resolvedElementType)
|
||||||
this.typeRef = varargParameterTypeRef.withReplacedConeType(resolvedArrayType)
|
this.typeRef = varargParameterTypeRef.withReplacedConeType(resolvedArrayType)
|
||||||
@@ -198,20 +199,18 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
if (valueParameter.isVararg) {
|
if (valueParameter.isVararg) {
|
||||||
firstIndex = min(firstIndex, i)
|
firstIndex = min(firstIndex, i)
|
||||||
arguments += arg
|
arguments += arg
|
||||||
|
} else {
|
||||||
|
newArgumentMapping[arg] = valueParameter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.replaceArgumentList(
|
newArgumentMapping[varargArgument] = varargParameter
|
||||||
buildArgumentList {
|
subCandidate.argumentMapping = newArgumentMapping
|
||||||
arguments += result.arguments
|
|
||||||
for (arg in varargArgument.arguments) {
|
|
||||||
arguments.remove(arg)
|
|
||||||
}
|
|
||||||
arguments.add(firstIndex, varargArgument)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
subCandidate.argumentMapping?.let {
|
||||||
|
result.replaceArgumentList(FirResolvedArgumentList(it))
|
||||||
|
}
|
||||||
result.transformExplicitReceiver(integerApproximator, null)
|
result.transformExplicitReceiver(integerApproximator, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.expressions
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildArgumentList
|
import org.jetbrains.kotlin.fir.expressions.builder.buildArgumentList
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||||
@@ -49,3 +50,16 @@ class FirArraySetArgumentList(
|
|||||||
override val arguments: List<FirExpression>
|
override val arguments: List<FirExpression>
|
||||||
get() = indexes + rValue
|
get() = indexes + rValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class FirResolvedArgumentList(
|
||||||
|
val mapping: Map<FirExpression, FirValueParameter>
|
||||||
|
) : FirAbstractArgumentList() {
|
||||||
|
override val arguments: List<FirExpression>
|
||||||
|
get() = mapping.keys.toList()
|
||||||
|
|
||||||
|
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
||||||
|
for (argument in mapping.keys) {
|
||||||
|
argument.accept(visitor, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.fir.expressions
|
package org.jetbrains.kotlin.fir.expressions
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnostic
|
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildConstExpression
|
import org.jetbrains.kotlin.fir.expressions.builder.buildConstExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildErrorExpression
|
import org.jetbrains.kotlin.fir.expressions.builder.buildErrorExpression
|
||||||
@@ -38,6 +39,9 @@ inline val FirCall.arguments: List<FirExpression> get() = argumentList.arguments
|
|||||||
|
|
||||||
inline val FirCall.argument: FirExpression get() = argumentList.arguments.first()
|
inline val FirCall.argument: FirExpression get() = argumentList.arguments.first()
|
||||||
|
|
||||||
|
inline val FirCall.argumentMapping: Map<FirExpression, FirValueParameter>?
|
||||||
|
get() = (argumentList as? FirResolvedArgumentList)?.mapping
|
||||||
|
|
||||||
fun FirExpression.toResolvedCallableReference(): FirResolvedNamedReference? {
|
fun FirExpression.toResolvedCallableReference(): FirResolvedNamedReference? {
|
||||||
return (this as? FirQualifiedAccess)?.calleeReference as? FirResolvedNamedReference
|
return (this as? FirQualifiedAccess)?.calleeReference as? FirResolvedNamedReference
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
// KT-9277 Unexpected NullPointerException in an invocaton with named arguments
|
// KT-9277 Unexpected NullPointerException in an invocaton with named arguments
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
var res = "";
|
var res = "";
|
||||||
var call = test(a = {res += "K"; "K"}(), b = {res+="O"; "O"}(), c = {res += "L"; "L"})
|
var call = test(a = {res += "K"; "K"}(), b = {res+="O"; "O"}(), c = {res += "L"; "L"})
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
var res = "";
|
var res = "";
|
||||||
var call = Z("Z").test(a = {res += "K"; "K"}(), b = {res+="O"; "O"}(), c = {res += "L"; "L"})
|
var call = Z("Z").test(a = {res += "K"; "K"}(), b = {res+="O"; "O"}(), c = {res += "L"; "L"})
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
class A(val a: Int = 0, val b: String = "a")
|
class A(val a: Int = 0, val b: String = "a")
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
fun Int.foo(a: Int = 1,
|
fun Int.foo(a: Int = 1,
|
||||||
b: Int = 2,
|
b: Int = 2,
|
||||||
c: Int = 3,
|
c: Int = 3,
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
fun Int.foo(a: Int = 1, b: String): Int {
|
fun Int.foo(a: Int = 1, b: String): Int {
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
class A {
|
class A {
|
||||||
fun Int.foo(a: Int = 1,
|
fun Int.foo(a: Int = 1,
|
||||||
b: Int = 2,
|
b: Int = 2,
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
class A() {
|
class A() {
|
||||||
fun foo(a: Int = 1,
|
fun foo(a: Int = 1,
|
||||||
b: Int = 2,
|
b: Int = 2,
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
fun foo(a: String = "Companion", b: Int = 1, c: Long = 2): String {
|
fun foo(a: String = "Companion", b: Int = 1, c: Long = 2): String {
|
||||||
return "$a $b $c"
|
return "$a $b $c"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
fun foo(a: Int = 1,
|
fun foo(a: Int = 1,
|
||||||
b: Int = 2,
|
b: Int = 2,
|
||||||
c: Int = 3,
|
c: Int = 3,
|
||||||
|
|||||||
Vendored
-1
@@ -1,5 +1,4 @@
|
|||||||
// !LANGUAGE: +ProperComputationOrderOfTailrecDefaultParameters
|
// !LANGUAGE: +ProperComputationOrderOfTailrecDefaultParameters
|
||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// DONT_RUN_GENERATED_CODE: JS
|
// DONT_RUN_GENERATED_CODE: JS
|
||||||
|
|
||||||
var counter = 0
|
var counter = 0
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
fun <T> T.toPrefixedString(prefix: String = "", suffix: String="") = prefix + this.toString() + suffix
|
fun <T> T.toPrefixedString(prefix: String = "", suffix: String="") = prefix + this.toString() + suffix
|
||||||
|
|
||||||
fun box() : String {
|
fun box() : String {
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// FILE: destructuringAssignmentWithNullabilityAssertionOnExtensionReceiver_lv12.kt
|
// FILE: destructuringAssignmentWithNullabilityAssertionOnExtensionReceiver_lv12.kt
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// FILE: test.kt
|
// FILE: test.kt
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// FILE: test.kt
|
// FILE: test.kt
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// FILE: test.kt
|
// FILE: test.kt
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// FILE: test.kt
|
// FILE: test.kt
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// FILE: equalsNull.kt
|
// FILE: equalsNull.kt
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
val global = "OK"
|
val global = "OK"
|
||||||
class A {
|
class A {
|
||||||
val prop: String
|
val prop: String
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
|
|
||||||
// FILE: A.java
|
// FILE: A.java
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
fun foo(a: Int, vararg b: Int, f: (IntArray) -> String): String {
|
fun foo(a: Int, vararg b: Int, f: (IntArray) -> String): String {
|
||||||
return "test" + a + " " + f(b)
|
return "test" + a + " " + f(b)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -32,7 +32,7 @@ FILE fqName:<root> fileName:/useNextParamInLambda.kt
|
|||||||
RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in <root>'
|
RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in <root>'
|
||||||
CALL 'public final fun plus (other: kotlin.Any?): kotlin.String [operator] declared in kotlin.String' type=kotlin.String origin=PLUS
|
CALL 'public final fun plus (other: kotlin.Any?): kotlin.String [operator] declared in kotlin.String' type=kotlin.String origin=PLUS
|
||||||
$this: CALL 'public final fun f (f1: kotlin.Function0<kotlin.String>, f2: kotlin.Function0<kotlin.String>): kotlin.String declared in <root>' type=kotlin.String origin=null
|
$this: CALL 'public final fun f (f1: kotlin.Function0<kotlin.String>, f2: kotlin.Function0<kotlin.String>): kotlin.String declared in <root>' type=kotlin.String origin=null
|
||||||
f1: FUN_EXPR type=kotlin.Function0<kotlin.String> origin=LAMBDA
|
f2: FUN_EXPR type=kotlin.Function0<kotlin.String> origin=LAMBDA
|
||||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.String
|
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.String
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): kotlin.String declared in <root>.box'
|
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): kotlin.String declared in <root>.box'
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ FILE fqName:<root> fileName:/callWithReorderedArguments.kt
|
|||||||
a: CALL 'public final fun noReorder1 (): kotlin.Int declared in <root>' type=kotlin.Int origin=null
|
a: CALL 'public final fun noReorder1 (): kotlin.Int declared in <root>' type=kotlin.Int origin=null
|
||||||
b: CALL 'public final fun noReorder2 (): kotlin.Int declared in <root>' type=kotlin.Int origin=null
|
b: CALL 'public final fun noReorder2 (): kotlin.Int declared in <root>' type=kotlin.Int origin=null
|
||||||
CALL 'public final fun foo (a: kotlin.Int, b: kotlin.Int): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
CALL 'public final fun foo (a: kotlin.Int, b: kotlin.Int): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||||
a: CALL 'public final fun reordered1 (): kotlin.Int declared in <root>' type=kotlin.Int origin=null
|
a: CALL 'public final fun reordered2 (): kotlin.Int declared in <root>' type=kotlin.Int origin=null
|
||||||
b: CALL 'public final fun reordered2 (): kotlin.Int declared in <root>' type=kotlin.Int origin=null
|
b: CALL 'public final fun reordered1 (): kotlin.Int declared in <root>' type=kotlin.Int origin=null
|
||||||
CALL 'public final fun foo (a: kotlin.Int, b: kotlin.Int): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
CALL 'public final fun foo (a: kotlin.Int, b: kotlin.Int): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||||
a: CONST Int type=kotlin.Int value=1
|
a: CALL 'public final fun reordered2 (): kotlin.Int declared in <root>' type=kotlin.Int origin=null
|
||||||
b: CALL 'public final fun reordered2 (): kotlin.Int declared in <root>' type=kotlin.Int origin=null
|
b: CONST Int type=kotlin.Int value=1
|
||||||
|
|||||||
Reference in New Issue
Block a user