FIR: map arguments for overloading indexed access operator

This commit is contained in:
Jinseong Jeon
2020-09-09 09:49:56 -07:00
committed by Mikhail Glukhikh
parent a73856be66
commit 49679f3145
7 changed files with 41 additions and 20 deletions
@@ -6,11 +6,14 @@
package org.jetbrains.kotlin.fir.resolve.calls
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.isOperator
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirLambdaArgumentExpression
import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression
import org.jetbrains.kotlin.fir.expressions.FirSpreadArgumentExpression
import org.jetbrains.kotlin.fir.expressions.builder.buildNamedArgumentExpression
import org.jetbrains.kotlin.name.Name
import java.util.*
import kotlin.collections.ArrayList
@@ -50,12 +53,30 @@ fun mapArguments(
return EmptyArgumentMapping
}
val externalArgument: FirExpression? = arguments.lastOrNull { it is FirLambdaArgumentExpression }
val argumentsInParenthesis: List<FirExpression> = if (externalArgument == null) {
var argumentsInParenthesis: List<FirExpression> = if (externalArgument == null) {
arguments
} else {
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)
processor.processArgumentsInParenthesis(argumentsInParenthesis)
if (externalArgument != null) {
@@ -1,5 +1,4 @@
// !LANGUAGE: +ProperArrayConventionSetterWithDefaultCalls
// IGNORE_BACKEND_FIR: JVM_IR
var inc: String = ""
class X {
@@ -1,5 +1,4 @@
// !LANGUAGE: +ProperArrayConventionSetterWithDefaultCalls
// IGNORE_BACKEND_FIR: JVM_IR
var result = "fail"
class A {
@@ -1,5 +1,4 @@
// !LANGUAGE: +ProperArrayConventionSetterWithDefaultCalls
// IGNORE_BACKEND_FIR: JVM_IR
var inc: String = ""
class X {
@@ -21,12 +21,12 @@ object Z {
}
fun test() {
<!INAPPLICABLE_CANDIDATE!>A[0] = ""<!>
<!INAPPLICABLE_CANDIDATE!>A[0] = 2.72<!>
A[0] = ""
A[0] = 2.72
<!INAPPLICABLE_CANDIDATE!>B[0] = ""<!>
<!INAPPLICABLE_CANDIDATE!>B[0] = 2.72<!>
<!INAPPLICABLE_CANDIDATE!>B[0] = true<!>
B[0] = ""
B[0] = 2.72
B[0] = true
<!INAPPLICABLE_CANDIDATE!>D[0] = ""<!>
<!INAPPLICABLE_CANDIDATE!>D[0] = 2.72<!>
@@ -11,9 +11,9 @@ operator fun Int.set(s: Int, x: String = "", z: Int) {
}
fun main() {
<!INAPPLICABLE_CANDIDATE!>1[2] = 1<!>
1[2] = 1
1.set(2, z = 1)
1[2] += 1
1.<!INAPPLICABLE_CANDIDATE!>set<!>(2, 1)
1.set(2, 1)
}
+12 -9
View File
@@ -47,9 +47,10 @@ FILE fqName:<root> fileName:/kt28456b.kt
FUN name:testSimpleAssignment visibility:public modality:FINAL <> (a:<root>.A) returnType:kotlin.Unit
VALUE_PARAMETER name:a index:0 type:<root>.A
BLOCK_BODY
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE_ARGUMENTS_MAPPING_ERROR): /set>#' type=kotlin.Unit
CONST Int type=kotlin.Int value=1
CONST Int type=kotlin.Int value=0
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
$receiver: GET_VAR 'a: <root>.A declared in <root>.testSimpleAssignment' type=<root>.A origin=null
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
VALUE_PARAMETER name:a index:0 type:<root>.A
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
$receiver: GET_VAR 'a: <root>.A declared in <root>.testPostfixIncrement' type=<root>.A origin=null
i: CONST Int type=kotlin.Int value=1
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE_ARGUMENTS_MAPPING_ERROR): /set>#' type=kotlin.Unit
CONST Int type=kotlin.Int value=1
CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
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
$receiver: GET_VAR 'a: <root>.A declared in <root>.testPostfixIncrement' type=<root>.A 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
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
@@ -72,9 +74,10 @@ FILE fqName:<root> fileName:/kt28456b.kt
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]
CONST Int type=kotlin.Int value=1
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE_ARGUMENTS_MAPPING_ERROR): /set>#' type=kotlin.Unit
GET_VAR 'val tmp_2: kotlin.Int [val] declared in <root>.testCompoundAssignment' type=kotlin.Int origin=null
CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
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
$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
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
$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