From dc6efa5a611101bde371be9677828a712523b965 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Thu, 23 Jul 2020 16:12:34 +0300 Subject: [PATCH] Fix incorrect handling of mixed named/positional arguments ^KT-40404 Fixed --- ...irOldFrontendDiagnosticsTestGenerated.java | 5 +++++ .../calls/FirArgumentsToParametersMapper.kt | 5 +++-- .../components/ArgumentsToParametersMapper.kt | 9 ++++++--- .../mixedNamedPosition/secondNamed.fir.kt | 18 ++++++++++++++++++ .../mixedNamedPosition/secondNamed.kt | 19 +++++++++++++++++++ .../valueArrayAndOtherDefault.kt | 2 +- .../valueArrayAndOtherDefault.ni.txt | 2 +- .../checkers/DiagnosticsTestGenerated.java | 5 +++++ .../DiagnosticsUsingJavacTestGenerated.java | 5 +++++ 9 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/secondNamed.fir.kt create mode 100644 compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/secondNamed.kt diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java index af52e823f4e..282b4bbbb43 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java @@ -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"); 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 1a281f073d9..d702c13c6ea 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 @@ -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++ } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ArgumentsToParametersMapper.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ArgumentsToParametersMapper.kt index 3786ee94f23..f2936a1227e 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ArgumentsToParametersMapper.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ArgumentsToParametersMapper.kt @@ -69,7 +69,7 @@ class ArgumentsToParametersMapper( private class CallArgumentProcessor( val descriptor: CallableDescriptor, - val allowMixedNamedAndPositionArguments: Boolean + val languageSettingsAllowMixedNamedAndPositionArguments: Boolean ) { val result: MutableMap = 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) } diff --git a/compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/secondNamed.fir.kt b/compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/secondNamed.fir.kt new file mode 100644 index 00000000000..c46ef743c54 --- /dev/null +++ b/compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/secondNamed.fir.kt @@ -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() { + foo(b = "first", a = "a", "second") // prints "a, second" + reformat(normalizeCase = "first",str = "","second",false,true, 's' ) +} diff --git a/compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/secondNamed.kt b/compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/secondNamed.kt new file mode 100644 index 00000000000..d18712bbe5c --- /dev/null +++ b/compiler/testData/diagnostics/tests/namedArguments/mixedNamedPosition/secondNamed.kt @@ -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", "second") // prints "a, second" + reformat(normalizeCase = "first",str = "","second",false,true, 's' ) +} + diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/valueArrayAndOtherDefault.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/valueArrayAndOtherDefault.kt index 6f43e4fdf94..ee2422d2d7e 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/valueArrayAndOtherDefault.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/valueArrayAndOtherDefault.kt @@ -26,5 +26,5 @@ public @interface A { @A fun test8() {} @A(x = Any::class, *arrayOf("5", "6"), "7", y = 3) fun test9() {} -@A(x = Any::class, value = ["5", "6"], "7", y = 3) fun test10() {} +@A(x = Any::class, value = ["5", "6"], "7", y = 3) fun test10() {} @A(x = Any::class, value = ["5", "6", "7"], y = 3) fun test11() {} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/valueArrayAndOtherDefault.ni.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/valueArrayAndOtherDefault.ni.txt index fa3940b3cad..edfeee37f9b 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/valueArrayAndOtherDefault.ni.txt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/valueArrayAndOtherDefault.ni.txt @@ -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 diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 365814a5674..42230663e72 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -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"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 1ed2594938d..103599c6329 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -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");