Fix incorrect handling of mixed named/positional arguments

^KT-40404 Fixed
This commit is contained in:
Denis Zharkov
2020-07-23 16:12:34 +03:00
parent d083297366
commit dc6efa5a61
9 changed files with 63 additions and 7 deletions
@@ -15514,6 +15514,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
runTest("compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/oldInference.kt");
}
@TestMetadata("secondNamed.kt")
public void testSecondNamed() throws Exception {
runTest("compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/secondNamed.kt");
}
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
runTest("compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/simple.kt");
@@ -96,7 +96,6 @@ private class FirCallArgumentsProcessor(private val function: FirFunction<*>) {
if (state == State.VARARG_POSITION) {
completeVarargPositionArguments()
}
state = State.NAMED_ONLY_ARGUMENTS
processNamedArgument(argument, argumentName)
}
@@ -137,6 +136,8 @@ private class FirCallArgumentsProcessor(private val function: FirFunction<*>) {
addDiagnostic(NamedArgumentNotAllowed(argument, function))
}
val stateAllowsMixedNamedAndPositionArguments = state != State.NAMED_ONLY_ARGUMENTS
state = State.NAMED_ONLY_ARGUMENTS
val parameter = findParameterByName(argument, name) ?: return
result[parameter]?.let {
@@ -146,7 +147,7 @@ private class FirCallArgumentsProcessor(private val function: FirFunction<*>) {
result[parameter] = ResolvedCallArgument.SimpleArgument(argument)
if (parameters.getOrNull(currentPositionedParameterIndex) == parameter) {
if (stateAllowsMixedNamedAndPositionArguments && parameters.getOrNull(currentPositionedParameterIndex) == parameter) {
state = State.POSITION_ARGUMENTS
currentPositionedParameterIndex++
}
@@ -69,7 +69,7 @@ class ArgumentsToParametersMapper(
private class CallArgumentProcessor(
val descriptor: CallableDescriptor,
val allowMixedNamedAndPositionArguments: Boolean
val languageSettingsAllowMixedNamedAndPositionArguments: Boolean
) {
val result: MutableMap<ValueParameterDescriptor, ResolvedCallArgument> = LinkedHashMap()
private var state = State.POSITION_ARGUMENTS
@@ -148,6 +148,9 @@ class ArgumentsToParametersMapper(
addDiagnostic(NamedArgumentNotAllowed(argument, descriptor))
}
val stateAllowsMixedNamedAndPositionArguments = state != State.NAMED_ONLY_ARGUMENTS
state = State.NAMED_ONLY_ARGUMENTS
val parameter = findParameterByName(argument, name) ?: return
addDiagnostic(NamedArgumentReference(argument, parameter))
@@ -159,7 +162,8 @@ class ArgumentsToParametersMapper(
result[parameter.original] = ResolvedCallArgument.SimpleArgument(argument)
if (allowMixedNamedAndPositionArguments && parameters.getOrNull(currentPositionedParameterIndex)?.original == parameter.original) {
if (stateAllowsMixedNamedAndPositionArguments && languageSettingsAllowMixedNamedAndPositionArguments &&
parameters.getOrNull(currentPositionedParameterIndex)?.original == parameter.original) {
state = State.POSITION_ARGUMENTS
currentPositionedParameterIndex++
}
@@ -212,7 +216,6 @@ class ArgumentsToParametersMapper(
if (state == State.VARARG_POSITION) {
completeVarargPositionArguments()
}
state = State.NAMED_ONLY_ARGUMENTS
processNamedArgument(argument, argumentName)
}
@@ -0,0 +1,18 @@
// !LANGUAGE: +NewInference +MixedNamedArgumentsInTheirOwnPosition
// !DIAGNOSTICS: -UNUSED_PARAMETER
// SKIP_TXT
fun foo(a: String, b: String) {}
fun reformat(
str: String,
normalizeCase: String = "default",
upperCaseFirstLetter: Boolean = true,
divideByCamelHumps: Boolean = false,
wordSeparator: Char = ' '
) {}
fun main() {
<!INAPPLICABLE_CANDIDATE!>foo<!>(b = "first", a = "a", "second") // prints "a, second"
<!INAPPLICABLE_CANDIDATE!>reformat<!>(normalizeCase = "first",str = "","second",false,true, 's' )
}
@@ -0,0 +1,19 @@
// !LANGUAGE: +NewInference +MixedNamedArgumentsInTheirOwnPosition
// !DIAGNOSTICS: -UNUSED_PARAMETER
// SKIP_TXT
fun foo(a: String, b: String) {}
fun reformat(
str: String,
normalizeCase: String = "default",
upperCaseFirstLetter: Boolean = true,
divideByCamelHumps: Boolean = false,
wordSeparator: Char = ' '
) {}
fun main() {
foo(b = "first", a = "a", <!MIXING_NAMED_AND_POSITIONED_ARGUMENTS!>"second"<!>) // prints "a, second"
reformat(normalizeCase = "first",str = "",<!MIXING_NAMED_AND_POSITIONED_ARGUMENTS!>"second"<!>,<!MIXING_NAMED_AND_POSITIONED_ARGUMENTS!>false<!>,<!MIXING_NAMED_AND_POSITIONED_ARGUMENTS!>true<!>, <!MIXING_NAMED_AND_POSITIONED_ARGUMENTS!>'s'<!> )
}
@@ -26,5 +26,5 @@ public @interface A {
@A fun test8() {}
@A(x = Any::class, <!MIXING_NAMED_AND_POSITIONED_ARGUMENTS!>*arrayOf("5", "6")<!>, <!MIXING_NAMED_AND_POSITIONED_ARGUMENTS!>"7"<!>, y = 3) fun test9() {}
@A(x = Any::class, value = ["5", "6"], <!NI;POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION, NI;TYPE_MISMATCH, OI;MIXING_NAMED_AND_POSITIONED_ARGUMENTS!>"7"<!>, y = 3) fun test10() {}
@A(x = Any::class, value = ["5", "6"], <!MIXING_NAMED_AND_POSITIONED_ARGUMENTS!>"7"<!>, y = 3) fun test10() {}
@A(x = Any::class, value = ["5", "6", "7"], y = 3) fun test11() {}
@@ -1,7 +1,7 @@
package
@A(value = {"1", "2", "3"}) public fun test1(): kotlin.Unit
@A(value = {"5", "6"}, x = "7", y = 3) public fun test10(): kotlin.Unit
@A(value = {"5", "6"}, x = kotlin.Any::class, y = 3) public fun test10(): kotlin.Unit
@A(value = {"5", "6", "7"}, x = kotlin.Any::class, y = 3) public fun test11(): kotlin.Unit
@A(value = {"4"}) public fun test2(): kotlin.Unit
@A(value = {{"5", "6"}, "7"}) public fun test3(): kotlin.Unit
@@ -15521,6 +15521,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali
runTest("compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/oldInference.kt");
}
@TestMetadata("secondNamed.kt")
public void testSecondNamed() throws Exception {
runTest("compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/secondNamed.kt");
}
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
runTest("compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/simple.kt");
@@ -15516,6 +15516,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
runTest("compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/oldInference.kt");
}
@TestMetadata("secondNamed.kt")
public void testSecondNamed() throws Exception {
runTest("compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/secondNamed.kt");
}
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
runTest("compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/simple.kt");