[FIR] Report repeating parameters in dynamic functions in Kotlin/JS

^KT-59988
This commit is contained in:
Evgeniy.Zhelenskiy
2023-11-21 13:12:46 +00:00
committed by Space Team
parent 166964bfcc
commit 67b1bb448a
4 changed files with 13 additions and 8 deletions
@@ -37,7 +37,7 @@ data class ArgumentMapping(
// foo(b = bar(), a = qux())
// parameterToCallArgumentMap.values() should be [ 'bar()', 'foo()' ]
val parameterToCallArgumentMap: LinkedHashMap<FirValueParameter, ResolvedCallArgument>,
val diagnostics: List<ResolutionDiagnostic>
val diagnostics: List<ResolutionDiagnostic>,
) {
fun toArgumentToParameterMapping(): LinkedHashMap<FirExpression, FirValueParameter> {
val argumentToParameterMapping = linkedMapOf<FirExpression, FirValueParameter>()
@@ -65,7 +65,7 @@ fun BodyResolveComponents.mapArguments(
arguments: List<FirExpression>,
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<FirExpression>? = null
private var nameToParameter: Map<Name, FirValueParameter>? = null
private var namedDynamicArgumentsNamesImpl: MutableSet<Name>? = null
private val namedDynamicArgumentsNames: MutableSet<Name>
get() = namedDynamicArgumentsNamesImpl ?: mutableSetOf<Name>().also { namedDynamicArgumentsNamesImpl = it }
var diagnostics: MutableList<ResolutionDiagnostic>? = null
private set
val result: LinkedHashMap<FirValueParameter, ResolvedCallArgument> = 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
}
@@ -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(
@@ -24,7 +24,7 @@ class K: J.C() {
sam(null)
sam(
name = null,
name = null
<!ARGUMENT_PASSED_TWICE!>name<!> = null
)
}
@@ -3,5 +3,5 @@ fun test(d: dynamic) {
d.foo(1, name = "name")
d.foo(1, duplicate = "", duplicate = "")
d.foo(1, duplicate = "", <!ARGUMENT_PASSED_TWICE!>duplicate<!> = "")
}