[FIR] Fix false positive error for trailing lambda on dynamic call

#KT-57961
This commit is contained in:
Kirill Rakhman
2023-04-14 15:41:43 +02:00
committed by Space Team
parent 418132c240
commit a3bf61c3f7
5 changed files with 30 additions and 43 deletions
@@ -262,19 +262,27 @@ private class FirCallArgumentsProcessor(
return
}
if (lastParameter.isVararg) {
addDiagnostic(VarargArgumentOutsideParentheses(externalArgument, lastParameter))
return
if (function.origin != FirDeclarationOrigin.DynamicScope) {
if (lastParameter.isVararg) {
addDiagnostic(VarargArgumentOutsideParentheses(externalArgument, lastParameter))
return
}
val previousOccurrence = result[lastParameter]
if (previousOccurrence != null) {
addDiagnostic(TooManyArguments(externalArgument, function))
return
}
result[lastParameter] = ResolvedCallArgument.SimpleArgument(externalArgument)
} else {
val existing = result[lastParameter]
if (existing == null) {
result[lastParameter] = ResolvedCallArgument.SimpleArgument(externalArgument)
} else {
result[lastParameter] = ResolvedCallArgument.VarargArgument(existing.arguments + externalArgument)
}
}
val previousOccurrence = result[lastParameter]
if (previousOccurrence != null) {
addDiagnostic(TooManyArguments(externalArgument, function))
return
}
result[lastParameter] = ResolvedCallArgument.SimpleArgument(externalArgument)
}
fun processExcessLambdaArguments(excessLambdaArguments: List<FirExpression>) {
@@ -312,7 +320,7 @@ private class FirCallArgumentsProcessor(
private fun completeVarargPositionArguments() {
assert(state == State.VARARG_POSITION) { "Incorrect state: $state" }
val parameter = parameters[currentPositionedParameterIndex]
result.put(parameter, ResolvedCallArgument.VarargArgument(varargArguments!!))
result[parameter] = ResolvedCallArgument.VarargArgument(varargArguments!!)
}
private fun addVarargArgument(argument: FirExpression) {
@@ -31,7 +31,7 @@ fun test(d: dynamic) {
<!DEBUG_INFO_DYNAMIC!>d()<!>
<!DEBUG_INFO_DYNAMIC!>d(1)<!>
<!DEBUG_INFO_DYNAMIC!>d(name = 1)<!>
<!DEBUG_INFO_DYNAMIC!>d <!VARARG_OUTSIDE_PARENTHESES!>{}<!><!>
<!DEBUG_INFO_DYNAMIC!>d {}<!>
class C {
val plus: dynamic = null
@@ -2,19 +2,19 @@
// !CHECK_TYPE
fun test(d: dynamic) {
d.foo <!VARARG_OUTSIDE_PARENTHESES!>{}<!>
d.foo {}
d.foo <!VARARG_OUTSIDE_PARENTHESES!>{ <!UNRESOLVED_REFERENCE!>it<!> }<!>
d.foo { <!UNRESOLVED_REFERENCE!>it<!> }
d.foo <!VARARG_OUTSIDE_PARENTHESES!>{ x -> }<!>
d.foo { x -> }
d.foo <!VARARG_OUTSIDE_PARENTHESES!>{ x: Int -> "" }<!>
d.foo { x: Int -> "" }
d.foo <!VARARG_OUTSIDE_PARENTHESES!>{ x, y -> "" }<!>
d.foo { x, y -> "" }
d.foo <!VARARG_OUTSIDE_PARENTHESES!>{ x: String, y: Int -> "" }<!>
d.foo { x: String, y: Int -> "" }
d.foo <!VARARG_OUTSIDE_PARENTHESES!>{ x, y: Int -> "" }<!>
d.foo { x, y: Int -> "" }
d.foo({})
@@ -1,22 +0,0 @@
fun test(d: dynamic) {
val a = arrayOf(1, 2, 3)
d.foo(<!SPREAD_OPERATOR_IN_DYNAMIC_CALL!>*<!>d)
d.foo(<!SPREAD_OPERATOR_IN_DYNAMIC_CALL!>*<!>a)
d.foo(1, "2", <!SPREAD_OPERATOR_IN_DYNAMIC_CALL!>*<!>a)
d.foo(1, *a) <!VARARG_OUTSIDE_PARENTHESES!>{ }<!>
d.foo(*a) <!VARARG_OUTSIDE_PARENTHESES!>{ "" }<!>
d.foo(<!SPREAD_OPERATOR_IN_DYNAMIC_CALL!>*<!>a, <!SPREAD_OPERATOR_IN_DYNAMIC_CALL!>*<!>a)
d.foo(*a, *a) <!VARARG_OUTSIDE_PARENTHESES!>{ "" }<!>
d.foo(<!SPREAD_OPERATOR_IN_DYNAMIC_CALL!>*<!>a, 1, { "" }, <!SPREAD_OPERATOR_IN_DYNAMIC_CALL!>*<!>a)
d.foo(<!SPREAD_OPERATOR_IN_DYNAMIC_CALL!>*<!>a, 1)
d.foo(<!SPREAD_OPERATOR_IN_DYNAMIC_CALL!>*<!>a, <!SPREAD_OPERATOR_IN_DYNAMIC_CALL!>*<!>a, { "" })
bar(d)
bar(d, d)
bar(<!WRONG_OPERATION_WITH_DYNAMIC!>*d<!>)
bar(<!WRONG_OPERATION_WITH_DYNAMIC!>*d<!>, <!WRONG_OPERATION_WITH_DYNAMIC!>*d<!>)
bar(<!WRONG_OPERATION_WITH_DYNAMIC!>*d<!>, 23, <!WRONG_OPERATION_WITH_DYNAMIC!>*d<!>)
}
fun bar(vararg x: Int): Unit = TODO("$x")
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
fun test(d: dynamic) {
val a = arrayOf(1, 2, 3)