[FIR] Fix arguments mapping for indexed set operator
Now processPositionArgument changes STATE as well as processNamedArgument ^KT-59386
This commit is contained in:
committed by
Space Team
parent
8f5294a508
commit
43c66ee0e5
+11
-28
@@ -12,7 +12,6 @@ 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.utils.isOperator
|
import org.jetbrains.kotlin.fir.declarations.utils.isOperator
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildNamedArgumentExpression
|
|
||||||
import org.jetbrains.kotlin.fir.isSubstitutionOrIntersectionOverride
|
import org.jetbrains.kotlin.fir.isSubstitutionOrIntersectionOverride
|
||||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.defaultParameterResolver
|
import org.jetbrains.kotlin.fir.resolve.defaultParameterResolver
|
||||||
@@ -95,22 +94,6 @@ fun BodyResolveComponents.mapArguments(
|
|||||||
&& function.name == OperatorNameConventions.SET
|
&& function.name == OperatorNameConventions.SET
|
||||||
&& function.origin !is FirDeclarationOrigin.DynamicScope
|
&& function.origin !is FirDeclarationOrigin.DynamicScope
|
||||||
|
|
||||||
if (isIndexedSetOperator &&
|
|
||||||
function.valueParameters.any { it.defaultValue != null || it.isVararg }
|
|
||||||
) {
|
|
||||||
val v = nonLambdaArguments.last()
|
|
||||||
if (v !is FirNamedArgumentExpression) {
|
|
||||||
val namedV = buildNamedArgumentExpression {
|
|
||||||
source = v.source
|
|
||||||
expression = v
|
|
||||||
isSpread = false
|
|
||||||
name = function.valueParameters.last().name
|
|
||||||
}
|
|
||||||
nonLambdaArguments.removeAt(nonLambdaArguments.size - 1)
|
|
||||||
nonLambdaArguments.add(namedV)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val processor = FirCallArgumentsProcessor(session, function, this, originScope, isIndexedSetOperator)
|
val processor = FirCallArgumentsProcessor(session, function, this, originScope, isIndexedSetOperator)
|
||||||
processor.processNonLambdaArguments(nonLambdaArguments)
|
processor.processNonLambdaArguments(nonLambdaArguments)
|
||||||
if (externalArgument != null) {
|
if (externalArgument != null) {
|
||||||
@@ -172,15 +155,16 @@ private class FirCallArgumentsProcessor(
|
|||||||
when {
|
when {
|
||||||
// process position argument
|
// process position argument
|
||||||
argument !is FirNamedArgumentExpression -> {
|
argument !is FirNamedArgumentExpression -> {
|
||||||
if (processPositionArgument(argument, isLastArgument)) {
|
if (state == State.VARARG_POSITION && isIndexedSetOperator && isLastArgument) {
|
||||||
state = State.VARARG_POSITION
|
// The last argument of an indexed set operator should be reserved for the last argument (the assigned value).
|
||||||
|
// That's why if vararg presented, they should be completed
|
||||||
|
completeVarargPositionArguments()
|
||||||
}
|
}
|
||||||
|
processPositionArgument(argument, isLastArgument)
|
||||||
}
|
}
|
||||||
// process named argument
|
// process named argument
|
||||||
function.origin == FirDeclarationOrigin.DynamicScope -> {
|
function.origin == FirDeclarationOrigin.DynamicScope -> {
|
||||||
if (processPositionArgument(argument.expression, isLastArgument)) {
|
processPositionArgument(argument.expression, isLastArgument)
|
||||||
state = State.VARARG_POSITION
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
if (state == State.VARARG_POSITION) {
|
if (state == State.VARARG_POSITION) {
|
||||||
@@ -191,11 +175,10 @@ private class FirCallArgumentsProcessor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// return true, if it was mapped to vararg parameter
|
private fun processPositionArgument(argument: FirExpression, isLastArgument: Boolean) {
|
||||||
private fun processPositionArgument(argument: FirExpression, isLastArgument: Boolean): Boolean {
|
|
||||||
if (state == State.NAMED_ONLY_ARGUMENTS) {
|
if (state == State.NAMED_ONLY_ARGUMENTS) {
|
||||||
addDiagnostic(MixingNamedAndPositionArguments(argument))
|
addDiagnostic(MixingNamedAndPositionArguments(argument))
|
||||||
return false
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// The last parameter of an indexed set operator should be reserved for the last argument (the assigned value).
|
// The last parameter of an indexed set operator should be reserved for the last argument (the assigned value).
|
||||||
@@ -219,19 +202,19 @@ private class FirCallArgumentsProcessor(
|
|||||||
val parameter = parameters.getOrNull(assignedParameterIndex)
|
val parameter = parameters.getOrNull(assignedParameterIndex)
|
||||||
if (parameter == null) {
|
if (parameter == null) {
|
||||||
addDiagnostic(TooManyArguments(argument, function))
|
addDiagnostic(TooManyArguments(argument, function))
|
||||||
return false
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (!parameter.isVararg) {
|
return if (!parameter.isVararg) {
|
||||||
currentPositionedParameterIndex++
|
currentPositionedParameterIndex++
|
||||||
|
|
||||||
result[parameter] = ResolvedCallArgument.SimpleArgument(argument)
|
result[parameter] = ResolvedCallArgument.SimpleArgument(argument)
|
||||||
false
|
state = State.POSITION_ARGUMENTS
|
||||||
}
|
}
|
||||||
// all position arguments will be mapped to current vararg parameter
|
// all position arguments will be mapped to current vararg parameter
|
||||||
else {
|
else {
|
||||||
addVarargArgument(argument)
|
addVarargArgument(argument)
|
||||||
true
|
state = State.VARARG_POSITION
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,16 +20,23 @@ object Z {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object W {
|
||||||
|
operator fun set(vararg va: Int, value: Int) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
A[0] = ""
|
A[0] = <!ARGUMENT_TYPE_MISMATCH!>""<!>
|
||||||
A[0] = 2.72
|
A[0] = 2.72
|
||||||
|
|
||||||
B[0] = ""
|
B[0] = <!ARGUMENT_TYPE_MISMATCH!>""<!>
|
||||||
B[0] = 2.72
|
B[0] = <!ARGUMENT_TYPE_MISMATCH!>2.72<!>
|
||||||
B[0] = true
|
B[0] = true
|
||||||
|
|
||||||
D[0] = ""
|
D[0] = <!ARGUMENT_TYPE_MISMATCH!>""<!>
|
||||||
D[0] = 2.72
|
D[0] = 2.72
|
||||||
|
|
||||||
Z[<!TOO_MANY_ARGUMENTS!>0<!>] = <!TOO_MANY_ARGUMENTS!>""<!>
|
Z[<!TOO_MANY_ARGUMENTS!>0<!>] = <!TOO_MANY_ARGUMENTS!>""<!>
|
||||||
|
|
||||||
|
W[0] = 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,11 @@ object Z {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object W {
|
||||||
|
operator fun set(vararg va: Int, value: Int) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
A[0] = <!TYPE_MISMATCH!>""<!>
|
A[0] = <!TYPE_MISMATCH!>""<!>
|
||||||
A[0] = 2.72
|
A[0] = 2.72
|
||||||
@@ -32,4 +37,6 @@ fun test() {
|
|||||||
D[0] = 2.72
|
D[0] = 2.72
|
||||||
|
|
||||||
Z[<!TOO_MANY_ARGUMENTS!>0<!>] = <!TOO_MANY_ARGUMENTS!>""<!>
|
Z[<!TOO_MANY_ARGUMENTS!>0<!>] = <!TOO_MANY_ARGUMENTS!>""<!>
|
||||||
|
|
||||||
|
W[0] = 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,14 @@ public object D {
|
|||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public object W {
|
||||||
|
private constructor W()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public final operator fun set(/*0*/ vararg va: kotlin.Int /*kotlin.IntArray*/, /*1*/ value: kotlin.Int): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
public object Z {
|
public object Z {
|
||||||
private constructor Z()
|
private constructor Z()
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
@@ -33,3 +41,4 @@ public object Z {
|
|||||||
public final operator fun set(): kotlin.Unit
|
public final operator fun set(): kotlin.Unit
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user