FIR: map arguments for overloading indexed access operator
This commit is contained in:
committed by
Mikhail Glukhikh
parent
a73856be66
commit
49679f3145
+22
-1
@@ -6,11 +6,14 @@
|
|||||||
package org.jetbrains.kotlin.fir.resolve.calls
|
package org.jetbrains.kotlin.fir.resolve.calls
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.isOperator
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirLambdaArgumentExpression
|
import org.jetbrains.kotlin.fir.expressions.FirLambdaArgumentExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression
|
import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirSpreadArgumentExpression
|
import org.jetbrains.kotlin.fir.expressions.FirSpreadArgumentExpression
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.builder.buildNamedArgumentExpression
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
@@ -50,12 +53,30 @@ fun mapArguments(
|
|||||||
return EmptyArgumentMapping
|
return EmptyArgumentMapping
|
||||||
}
|
}
|
||||||
val externalArgument: FirExpression? = arguments.lastOrNull { it is FirLambdaArgumentExpression }
|
val externalArgument: FirExpression? = arguments.lastOrNull { it is FirLambdaArgumentExpression }
|
||||||
val argumentsInParenthesis: List<FirExpression> = if (externalArgument == null) {
|
var argumentsInParenthesis: List<FirExpression> = if (externalArgument == null) {
|
||||||
arguments
|
arguments
|
||||||
} else {
|
} else {
|
||||||
arguments.subList(0, arguments.size - 1)
|
arguments.subList(0, arguments.size - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this is an overloading indexed access operator, it could have default values in the middle.
|
||||||
|
// For proper argument mapping, wrap the last one, which is supposed to be the updated value, as a named argument.
|
||||||
|
if ((function as? FirSimpleFunction)?.isOperator == true &&
|
||||||
|
function.name == Name.identifier("set") &&
|
||||||
|
function.valueParameters.any { it.defaultValue != null }
|
||||||
|
) {
|
||||||
|
val v = argumentsInParenthesis.last()
|
||||||
|
if (v !is FirNamedArgumentExpression) {
|
||||||
|
val namedV = buildNamedArgumentExpression {
|
||||||
|
source = v.source
|
||||||
|
expression = v
|
||||||
|
isSpread = false
|
||||||
|
name = function.valueParameters.last().name
|
||||||
|
}
|
||||||
|
argumentsInParenthesis = argumentsInParenthesis.dropLast(1) + listOf(namedV)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val processor = FirCallArgumentsProcessor(function)
|
val processor = FirCallArgumentsProcessor(function)
|
||||||
processor.processArgumentsInParenthesis(argumentsInParenthesis)
|
processor.processArgumentsInParenthesis(argumentsInParenthesis)
|
||||||
if (externalArgument != null) {
|
if (externalArgument != null) {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// !LANGUAGE: +ProperArrayConventionSetterWithDefaultCalls
|
// !LANGUAGE: +ProperArrayConventionSetterWithDefaultCalls
|
||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
var inc: String = ""
|
var inc: String = ""
|
||||||
|
|
||||||
class X {
|
class X {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// !LANGUAGE: +ProperArrayConventionSetterWithDefaultCalls
|
// !LANGUAGE: +ProperArrayConventionSetterWithDefaultCalls
|
||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
var result = "fail"
|
var result = "fail"
|
||||||
|
|
||||||
class A {
|
class A {
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
// !LANGUAGE: +ProperArrayConventionSetterWithDefaultCalls
|
// !LANGUAGE: +ProperArrayConventionSetterWithDefaultCalls
|
||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
var inc: String = ""
|
var inc: String = ""
|
||||||
|
|
||||||
class X {
|
class X {
|
||||||
|
|||||||
@@ -21,12 +21,12 @@ object Z {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
<!INAPPLICABLE_CANDIDATE!>A[0] = ""<!>
|
A[0] = ""
|
||||||
<!INAPPLICABLE_CANDIDATE!>A[0] = 2.72<!>
|
A[0] = 2.72
|
||||||
|
|
||||||
<!INAPPLICABLE_CANDIDATE!>B[0] = ""<!>
|
B[0] = ""
|
||||||
<!INAPPLICABLE_CANDIDATE!>B[0] = 2.72<!>
|
B[0] = 2.72
|
||||||
<!INAPPLICABLE_CANDIDATE!>B[0] = true<!>
|
B[0] = true
|
||||||
|
|
||||||
<!INAPPLICABLE_CANDIDATE!>D[0] = ""<!>
|
<!INAPPLICABLE_CANDIDATE!>D[0] = ""<!>
|
||||||
<!INAPPLICABLE_CANDIDATE!>D[0] = 2.72<!>
|
<!INAPPLICABLE_CANDIDATE!>D[0] = 2.72<!>
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ operator fun Int.set(s: Int, x: String = "", z: Int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
<!INAPPLICABLE_CANDIDATE!>1[2] = 1<!>
|
1[2] = 1
|
||||||
1.set(2, z = 1)
|
1.set(2, z = 1)
|
||||||
1[2] += 1
|
1[2] += 1
|
||||||
|
|
||||||
1.<!INAPPLICABLE_CANDIDATE!>set<!>(2, 1)
|
1.set(2, 1)
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-9
@@ -47,9 +47,10 @@ FILE fqName:<root> fileName:/kt28456b.kt
|
|||||||
FUN name:testSimpleAssignment visibility:public modality:FINAL <> (a:<root>.A) returnType:kotlin.Unit
|
FUN name:testSimpleAssignment visibility:public modality:FINAL <> (a:<root>.A) returnType:kotlin.Unit
|
||||||
VALUE_PARAMETER name:a index:0 type:<root>.A
|
VALUE_PARAMETER name:a index:0 type:<root>.A
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE_ARGUMENTS_MAPPING_ERROR): /set>#' type=kotlin.Unit
|
CALL 'public final fun set (i: kotlin.Int, j: kotlin.Int, v: kotlin.Int): kotlin.Unit [operator] declared in <root>' type=kotlin.Unit origin=null
|
||||||
CONST Int type=kotlin.Int value=1
|
$receiver: GET_VAR 'a: <root>.A declared in <root>.testSimpleAssignment' type=<root>.A origin=null
|
||||||
CONST Int type=kotlin.Int value=0
|
i: CONST Int type=kotlin.Int value=1
|
||||||
|
v: CONST Int type=kotlin.Int value=0
|
||||||
FUN name:testPostfixIncrement visibility:public modality:FINAL <> (a:<root>.A) returnType:kotlin.Int
|
FUN name:testPostfixIncrement visibility:public modality:FINAL <> (a:<root>.A) returnType:kotlin.Int
|
||||||
VALUE_PARAMETER name:a index:0 type:<root>.A
|
VALUE_PARAMETER name:a index:0 type:<root>.A
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
@@ -59,9 +60,10 @@ FILE fqName:<root> fileName:/kt28456b.kt
|
|||||||
CALL 'public final fun get (i: kotlin.Int, a: kotlin.Int, b: kotlin.Int, c: kotlin.Int, d: kotlin.Int): kotlin.Int [operator] declared in <root>' type=kotlin.Int origin=null
|
CALL 'public final fun get (i: kotlin.Int, a: kotlin.Int, b: kotlin.Int, c: kotlin.Int, d: kotlin.Int): kotlin.Int [operator] declared in <root>' type=kotlin.Int origin=null
|
||||||
$receiver: GET_VAR 'a: <root>.A declared in <root>.testPostfixIncrement' type=<root>.A origin=null
|
$receiver: GET_VAR 'a: <root>.A declared in <root>.testPostfixIncrement' type=<root>.A origin=null
|
||||||
i: CONST Int type=kotlin.Int value=1
|
i: CONST Int type=kotlin.Int value=1
|
||||||
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE_ARGUMENTS_MAPPING_ERROR): /set>#' type=kotlin.Unit
|
CALL 'public final fun set (i: kotlin.Int, j: kotlin.Int, v: kotlin.Int): kotlin.Unit [operator] declared in <root>' type=kotlin.Unit origin=null
|
||||||
CONST Int type=kotlin.Int value=1
|
$receiver: GET_VAR 'a: <root>.A declared in <root>.testPostfixIncrement' type=<root>.A origin=null
|
||||||
CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
i: CONST Int type=kotlin.Int value=1
|
||||||
|
v: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||||
$this: GET_VAR 'val tmp_0: kotlin.Int [val] declared in <root>.testPostfixIncrement' type=kotlin.Int origin=null
|
$this: GET_VAR 'val tmp_0: kotlin.Int [val] declared in <root>.testPostfixIncrement' type=kotlin.Int origin=null
|
||||||
GET_VAR 'val tmp_0: kotlin.Int [val] declared in <root>.testPostfixIncrement' type=kotlin.Int origin=null
|
GET_VAR 'val tmp_0: kotlin.Int [val] declared in <root>.testPostfixIncrement' type=kotlin.Int origin=null
|
||||||
FUN name:testCompoundAssignment visibility:public modality:FINAL <> (a:<root>.A) returnType:kotlin.Unit
|
FUN name:testCompoundAssignment visibility:public modality:FINAL <> (a:<root>.A) returnType:kotlin.Unit
|
||||||
@@ -72,9 +74,10 @@ FILE fqName:<root> fileName:/kt28456b.kt
|
|||||||
GET_VAR 'a: <root>.A declared in <root>.testCompoundAssignment' type=<root>.A origin=null
|
GET_VAR 'a: <root>.A declared in <root>.testCompoundAssignment' type=<root>.A origin=null
|
||||||
VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.Int [val]
|
VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.Int [val]
|
||||||
CONST Int type=kotlin.Int value=1
|
CONST Int type=kotlin.Int value=1
|
||||||
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE_ARGUMENTS_MAPPING_ERROR): /set>#' type=kotlin.Unit
|
CALL 'public final fun set (i: kotlin.Int, j: kotlin.Int, v: kotlin.Int): kotlin.Unit [operator] declared in <root>' type=kotlin.Unit origin=null
|
||||||
GET_VAR 'val tmp_2: kotlin.Int [val] declared in <root>.testCompoundAssignment' type=kotlin.Int origin=null
|
$receiver: GET_VAR 'val tmp_1: <root>.A [val] declared in <root>.testCompoundAssignment' type=<root>.A origin=null
|
||||||
CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
i: GET_VAR 'val tmp_2: kotlin.Int [val] declared in <root>.testCompoundAssignment' type=kotlin.Int origin=null
|
||||||
|
v: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||||
$this: CALL 'public final fun get (i: kotlin.Int, a: kotlin.Int, b: kotlin.Int, c: kotlin.Int, d: kotlin.Int): kotlin.Int [operator] declared in <root>' type=kotlin.Int origin=null
|
$this: CALL 'public final fun get (i: kotlin.Int, a: kotlin.Int, b: kotlin.Int, c: kotlin.Int, d: kotlin.Int): kotlin.Int [operator] declared in <root>' type=kotlin.Int origin=null
|
||||||
$receiver: GET_VAR 'val tmp_1: <root>.A [val] declared in <root>.testCompoundAssignment' type=<root>.A origin=null
|
$receiver: GET_VAR 'val tmp_1: <root>.A [val] declared in <root>.testCompoundAssignment' type=<root>.A origin=null
|
||||||
i: GET_VAR 'val tmp_2: kotlin.Int [val] declared in <root>.testCompoundAssignment' type=kotlin.Int origin=null
|
i: GET_VAR 'val tmp_2: kotlin.Int [val] declared in <root>.testCompoundAssignment' type=kotlin.Int origin=null
|
||||||
|
|||||||
Reference in New Issue
Block a user