From 67b1bb448a851183666be848d36d21a50dd8045f Mon Sep 17 00:00:00 2001 From: "Evgeniy.Zhelenskiy" Date: Tue, 21 Nov 2023 13:12:46 +0000 Subject: [PATCH] [FIR] Report repeating parameters in dynamic functions in Kotlin/JS ^KT-59988 --- .../calls/FirArgumentsToParametersMapper.kt | 14 ++++++++++---- .../fir/resolve/calls/ResolutionDiagnostic.kt | 3 +-- .../dynamicTypes/withInvisibleSynthesized.fir.kt | 2 +- .../dynamicTypes/namedArguments.fir.kt | 2 +- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirArgumentsToParametersMapper.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirArgumentsToParametersMapper.kt index 47a08304d42..a1eb30bd8bd 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirArgumentsToParametersMapper.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirArgumentsToParametersMapper.kt @@ -37,7 +37,7 @@ data class ArgumentMapping( // foo(b = bar(), a = qux()) // parameterToCallArgumentMap.values() should be [ 'bar()', 'foo()' ] val parameterToCallArgumentMap: LinkedHashMap, - val diagnostics: List + val diagnostics: List, ) { fun toArgumentToParameterMapping(): LinkedHashMap { val argumentToParameterMapping = linkedMapOf() @@ -65,7 +65,7 @@ fun BodyResolveComponents.mapArguments( arguments: List, function: FirFunction, originScope: FirScope?, - callSiteIsOperatorCall: Boolean + callSiteIsOperatorCall: Boolean, ): ArgumentMapping { if (arguments.isEmpty() && function.valueParameters.isEmpty()) { return EmptyArgumentMapping @@ -110,12 +110,15 @@ private class FirCallArgumentsProcessor( private val function: FirFunction, private val bodyResolveComponents: BodyResolveComponents, private val originScope: FirScope?, - private val isIndexedSetOperator: Boolean + private val isIndexedSetOperator: Boolean, ) { private var state = State.POSITION_ARGUMENTS private var currentPositionedParameterIndex = 0 private var varargArguments: MutableList? = null private var nameToParameter: Map? = null + private var namedDynamicArgumentsNamesImpl: MutableSet? = null + private val namedDynamicArgumentsNames: MutableSet + get() = namedDynamicArgumentsNamesImpl ?: mutableSetOf().also { namedDynamicArgumentsNamesImpl = it } var diagnostics: MutableList? = null private set val result: LinkedHashMap = LinkedHashMap(function.valueParameters.size) @@ -165,6 +168,9 @@ private class FirCallArgumentsProcessor( // process named argument function.origin == FirDeclarationOrigin.DynamicScope -> { processPositionArgument(argument.expression, isLastArgument) + if (!namedDynamicArgumentsNames.add(argument.name)) { + addDiagnostic(ArgumentPassedTwice(argument)) + } } else -> { if (state == State.VARARG_POSITION) { @@ -228,7 +234,7 @@ private class FirCallArgumentsProcessor( val parameter = findParameterByName(argument) ?: return result[parameter]?.let { - addDiagnostic(ArgumentPassedTwice(argument, parameter)) + addDiagnostic(ArgumentPassedTwice(argument)) return } diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt index 35947f2ba4a..a47ef71d2e5 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionDiagnostic.kt @@ -50,8 +50,7 @@ class NamedArgumentNotAllowed( ) : ResolutionDiagnostic(INAPPLICABLE_ARGUMENTS_MAPPING_ERROR) class ArgumentPassedTwice( - override val argument: FirExpression, - val valueParameter: FirValueParameter + override val argument: FirNamedArgumentExpression, ) : InapplicableArgumentDiagnostic() class VarargArgumentOutsideParentheses( diff --git a/compiler/testData/diagnostics/tests/dynamicTypes/withInvisibleSynthesized.fir.kt b/compiler/testData/diagnostics/tests/dynamicTypes/withInvisibleSynthesized.fir.kt index d79cef78101..d0003dc21e5 100644 --- a/compiler/testData/diagnostics/tests/dynamicTypes/withInvisibleSynthesized.fir.kt +++ b/compiler/testData/diagnostics/tests/dynamicTypes/withInvisibleSynthesized.fir.kt @@ -24,7 +24,7 @@ class K: J.C() { sam(null) sam( name = null, - name = null + name = null ) } diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes/namedArguments.fir.kt b/compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes/namedArguments.fir.kt index 59eafd7b24f..d591f0db3d9 100644 --- a/compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes/namedArguments.fir.kt +++ b/compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes/namedArguments.fir.kt @@ -3,5 +3,5 @@ fun test(d: dynamic) { d.foo(1, name = "name") - d.foo(1, duplicate = "", duplicate = "") + d.foo(1, duplicate = "", duplicate = "") }