From dfc36ec6146392ca0e6da9411cd51dd352c8e833 Mon Sep 17 00:00:00 2001 From: Tianyu Geng Date: Wed, 8 Sep 2021 15:38:27 -0700 Subject: [PATCH] FIR checker: ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_(ANNOTATION|FUNCTION) --- .../testData/resolve/arguments/vararg.kt | 2 +- .../diagnostics/FirDiagnosticsList.kt | 2 ++ .../fir/analysis/diagnostics/FirErrors.kt | 2 ++ .../expression/FirNamedVarargChecker.kt | 25 +++++++++++------- .../diagnostics/FirDefaultErrorMessages.kt | 4 +++ .../tests/checkArguments/kt17691.fir.kt | 2 +- .../kt17691WithEnabledFeature.fir.kt | 25 ------------------ .../kt17691WithEnabledFeature.kt | 1 + .../collectionLiteralsWithVarargs.fir.kt | 2 +- ...assignArrayToVararagInNamedForm_1_3.fir.kt | 4 +-- ...assignArrayToVararagInNamedForm_1_4.fir.kt | 4 +-- ...gleArrayElementAsVarargInAnnotation.fir.kt | 2 +- ...rayElementAsVarargInAnnotationError.fir.kt | 26 ------------------- ...leArrayElementAsVarargInAnnotationError.kt | 1 + ...entsInNamedFormAnnDeprecation_after.fir.kt | 4 +-- ...ntsInNamedFormAnnDeprecation_before.fir.kt | 4 +-- ...entsInNamedFormFunDeprecation_after.fir.kt | 12 ++++----- ...ntsInNamedFormFunDeprecation_before.fir.kt | 12 ++++----- ...tAssigningSingleElementsInNamedForm.fir.kt | 6 ++--- .../diagnostics/KtFirDataClassConverters.kt | 12 +++++++++ .../api/fir/diagnostics/KtFirDiagnostics.kt | 8 ++++++ .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 14 ++++++++++ 22 files changed, 87 insertions(+), 87 deletions(-) delete mode 100644 compiler/testData/diagnostics/tests/checkArguments/kt17691WithEnabledFeature.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/varargs/assignNonConstSingleArrayElementAsVarargInAnnotationError.fir.kt diff --git a/compiler/fir/analysis-tests/testData/resolve/arguments/vararg.kt b/compiler/fir/analysis-tests/testData/resolve/arguments/vararg.kt index 066ecab17e1..08450469081 100644 --- a/compiler/fir/analysis-tests/testData/resolve/arguments/vararg.kt +++ b/compiler/fir/analysis-tests/testData/resolve/arguments/vararg.kt @@ -10,7 +10,7 @@ fun test() { foo("") foo(1, 2) - bar(1, z = true, y = *arrayOf("my", "yours")) + bar(1, z = true, y = *arrayOf("my", "yours")) bar(0, z = false, y = "", y = "other") bar(0, "", true) diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index 91f938ac0a9..45b5a402649 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -463,6 +463,8 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { val ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION by deprecationError(LanguageFeature.ProhibitAssigningSingleElementsToVarargsInNamedForm) val ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION by deprecationError(LanguageFeature.ProhibitAssigningSingleElementsToVarargsInNamedForm) + val REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_ANNOTATION by warning() + val REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION by warning() } val AMBIGUITY by object : DiagnosticGroup("Ambiguity") { diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index 344fbecb12e..05a3ac60c64 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -320,6 +320,8 @@ object FirErrors { val SPREAD_OF_NULLABLE by error0(SourceElementPositioningStrategies.SPREAD_OPERATOR) val ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION by deprecationError0(ProhibitAssigningSingleElementsToVarargsInNamedForm) val ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION by deprecationError0(ProhibitAssigningSingleElementsToVarargsInNamedForm) + val REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_ANNOTATION by warning0() + val REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION by warning0() // Ambiguity val OVERLOAD_RESOLUTION_AMBIGUITY by error1>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirNamedVarargChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirNamedVarargChecker.kt index a6998927ef6..370034bc10d 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirNamedVarargChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirNamedVarargChecker.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.languageVersionSettings +import org.jetbrains.kotlin.fir.references.FirErrorNamedReference import org.jetbrains.kotlin.fir.types.FirErrorTypeRef import org.jetbrains.kotlin.fir.types.isArrayType @@ -27,41 +28,47 @@ object FirNamedVarargChecker : FirCallChecker() { expression !is FirDelegatedConstructorCall && expression !is FirArrayOfCall) return val isAnnotation = expression is FirAnnotation - val errorFactory = + val singleElementToVarargErrorFactory = if (isAnnotation) FirErrors.ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION else FirErrors.ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION + val redundantSpreadWarningFactory = + if (isAnnotation) FirErrors.REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_ANNOTATION + else FirErrors.REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION val allowAssignArray = context.session.languageVersionSettings.supportsFeature( if (isAnnotation) LanguageFeature.AssigningArraysToVarargsInNamedFormInAnnotations else LanguageFeature.AllowAssigningArrayElementsToVarargsInNamedFormForFunctions ) - fun checkArgument(argument: FirExpression) { + fun checkArgument(argument: FirExpression, isVararg: Boolean) { if (argument !is FirNamedArgumentExpression) return - if (argument.isSpread) return + if (argument.isSpread) { + if (isVararg && (expression as? FirResolvable)?.calleeReference !is FirErrorNamedReference) { + reporter.reportOn(argument.expression.source, redundantSpreadWarningFactory, context) + } + return + } val typeRef = argument.expression.typeRef if (typeRef is FirErrorTypeRef) return if (argument.expression is FirArrayOfCall) return if (allowAssignArray && typeRef.isArrayType) return - reporter.reportOn(argument.expression.source, errorFactory, context) + reporter.reportOn(argument.expression.source, singleElementToVarargErrorFactory, context) } if (expression is FirArrayOfCall) { // FirArrayOfCall has the `vararg` argument expression pre-flattened and doesn't have an argument mapping. - expression.arguments.forEach(::checkArgument) + expression.arguments.forEach { checkArgument(it, it is FirNamedArgumentExpression) } } else { val argumentMap = expression.argumentMapping ?: return for ((argument, parameter) in argumentMap) { if (!parameter.isVararg) continue if (argument is FirVarargArgumentsExpression) { - argument.arguments.forEach(::checkArgument) + argument.arguments.forEach { checkArgument(it, true) } } else { - checkArgument(argument) + checkArgument(argument, false) } } } } - - } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index f5dc77259e0..c5baf304507 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -374,6 +374,8 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_PROJECT import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_RETURN_UNIT_TYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_SETTER_PARAMETER_TYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_SINGLE_EXPRESSION_STRING_TEMPLATE +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_ANNOTATION +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_VISIBILITY_MODIFIER import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REIFIED_TYPE_FORBIDDEN_SUBSTITUTION import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REIFIED_TYPE_IN_CATCH_CLAUSE @@ -806,6 +808,8 @@ class FirDefaultErrorMessages { map.put(SPREAD_OF_NULLABLE, "The spread operator (*foo) may not be applied to an argument of nullable type") map.put(ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION, "Assigning single elements to varargs in named form is forbidden") map.put(ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION, "Assigning single elements to varargs in named form is forbidden") + map.put(REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_ANNOTATION, "Redundant spread (*) operator"); + map.put(REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION, "Redundant spread (*) operator"); map.put(TYPE_MISMATCH, "Type mismatch: inferred type is {1} but {0} was expected", TO_STRING, TO_STRING) map.put(THROWABLE_TYPE_MISMATCH, "Throwable type mismatch: actual type is {0}", TO_STRING) diff --git a/compiler/testData/diagnostics/tests/checkArguments/kt17691.fir.kt b/compiler/testData/diagnostics/tests/checkArguments/kt17691.fir.kt index 8a2d5d61e6b..afe4092f21d 100644 --- a/compiler/testData/diagnostics/tests/checkArguments/kt17691.fir.kt +++ b/compiler/testData/diagnostics/tests/checkArguments/kt17691.fir.kt @@ -6,7 +6,7 @@ fun foo(vararg x: Unit, y: Any) {} fun main() { foo({ }(), y = { }()) - foo(x = *arrayOf({ }()), y = { }()) + foo(x = *arrayOf({ }()), y = { }()) foo(x = arrayOf({ }()), y = { }()) foo(*arrayOf({ }()), y = { }()) } diff --git a/compiler/testData/diagnostics/tests/checkArguments/kt17691WithEnabledFeature.fir.kt b/compiler/testData/diagnostics/tests/checkArguments/kt17691WithEnabledFeature.fir.kt deleted file mode 100644 index b64e64e6b28..00000000000 --- a/compiler/testData/diagnostics/tests/checkArguments/kt17691WithEnabledFeature.fir.kt +++ /dev/null @@ -1,25 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_PARAMETER -// !LANGUAGE: +UseCorrectExecutionOrderForVarargArguments -// WITH_RUNTIME - -fun foo(vararg x: Unit, y: Any) {} - -fun main() { - foo({ }(), y = { }()) - foo(x = *arrayOf({ }()), y = { }()) - foo(x = arrayOf({ }()), y = { }()) - foo(*arrayOf({ }()), y = { }()) -} - -fun foo2(vararg x: Unit, y: Any, z: Any) {} - -fun main2() { - foo2(y = { }(), x = arrayOf({ }()), z = { }()) -} - -fun foo3(vararg x: Unit, y: Any, z: Any = { }()) {} - -fun main3() { - // no warning, execution order is already right - foo3(y = { }(), x = arrayOf({ }())) -} diff --git a/compiler/testData/diagnostics/tests/checkArguments/kt17691WithEnabledFeature.kt b/compiler/testData/diagnostics/tests/checkArguments/kt17691WithEnabledFeature.kt index 6357b521810..c0d304e8e4f 100644 --- a/compiler/testData/diagnostics/tests/checkArguments/kt17691WithEnabledFeature.kt +++ b/compiler/testData/diagnostics/tests/checkArguments/kt17691WithEnabledFeature.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_PARAMETER // !LANGUAGE: +UseCorrectExecutionOrderForVarargArguments // WITH_RUNTIME diff --git a/compiler/testData/diagnostics/tests/collectionLiterals/collectionLiteralsWithVarargs.fir.kt b/compiler/testData/diagnostics/tests/collectionLiterals/collectionLiteralsWithVarargs.fir.kt index 05eeca17669..4b9071d8d44 100644 --- a/compiler/testData/diagnostics/tests/collectionLiterals/collectionLiteralsWithVarargs.fir.kt +++ b/compiler/testData/diagnostics/tests/collectionLiterals/collectionLiteralsWithVarargs.fir.kt @@ -22,7 +22,7 @@ fun test1_2() {} @Ann2(*[]) fun test2() {} -@Ann3(a = *[0f, 1 / 0f]) +@Ann3(a = *[0f, 1 / 0f]) fun test3() {} @Ann5(Ann4(*["/"])) diff --git a/compiler/testData/diagnostics/tests/varargs/assignArrayToVararagInNamedForm_1_3.fir.kt b/compiler/testData/diagnostics/tests/varargs/assignArrayToVararagInNamedForm_1_3.fir.kt index fa77f09cb18..b8657c339d0 100644 --- a/compiler/testData/diagnostics/tests/varargs/assignArrayToVararagInNamedForm_1_3.fir.kt +++ b/compiler/testData/diagnostics/tests/varargs/assignArrayToVararagInNamedForm_1_3.fir.kt @@ -12,7 +12,7 @@ fun test_fun(s: String, arr: Array) { withVararg(arr) // Error withVararg(*arr) // OK withVararg(s = arr) // Error - withVararg(s = *arr) // OK + withVararg(s = *arr) // OK withVararg(s) // OK withVararg(s = s) // Error @@ -25,7 +25,7 @@ fun test_ann(s: String, arr: Array) { foo() @Ann(s = [""], x = 1) foo() - @Ann(s = *[""], x = 1) + @Ann(s = *[""], x = 1) foo() @Ann("", x = 1) diff --git a/compiler/testData/diagnostics/tests/varargs/assignArrayToVararagInNamedForm_1_4.fir.kt b/compiler/testData/diagnostics/tests/varargs/assignArrayToVararagInNamedForm_1_4.fir.kt index 1306fc99699..248e7dc5432 100644 --- a/compiler/testData/diagnostics/tests/varargs/assignArrayToVararagInNamedForm_1_4.fir.kt +++ b/compiler/testData/diagnostics/tests/varargs/assignArrayToVararagInNamedForm_1_4.fir.kt @@ -12,7 +12,7 @@ fun test_fun(s: String, arr: Array) { withVararg(arr) // Error withVararg(*arr) // OK withVararg(s = arr) // OK - withVararg(s = *arr) // Warning + withVararg(s = *arr) // Warning withVararg(s) // OK withVararg(s = s) // Error @@ -25,7 +25,7 @@ fun test_ann(s: String, arr: Array) { foo() @Ann(s = [""], x = 1) foo() - @Ann(s = *[""], x = 1) + @Ann(s = *[""], x = 1) foo() @Ann("", x = 1) diff --git a/compiler/testData/diagnostics/tests/varargs/assignNonConstSingleArrayElementAsVarargInAnnotation.fir.kt b/compiler/testData/diagnostics/tests/varargs/assignNonConstSingleArrayElementAsVarargInAnnotation.fir.kt index 6c540ad4bb0..3e93ea4629c 100644 --- a/compiler/testData/diagnostics/tests/varargs/assignNonConstSingleArrayElementAsVarargInAnnotation.fir.kt +++ b/compiler/testData/diagnostics/tests/varargs/assignNonConstSingleArrayElementAsVarargInAnnotation.fir.kt @@ -19,7 +19,7 @@ fun foo3() {} @Anno(value = [nonConstLong()]) fun foo4() {} -@Anno(value = *nonConstArray) +@Anno(value = *nonConstArray) fun bar1() {} @Anno(*nonConstArray) diff --git a/compiler/testData/diagnostics/tests/varargs/assignNonConstSingleArrayElementAsVarargInAnnotationError.fir.kt b/compiler/testData/diagnostics/tests/varargs/assignNonConstSingleArrayElementAsVarargInAnnotationError.fir.kt deleted file mode 100644 index 42ce3fff26c..00000000000 --- a/compiler/testData/diagnostics/tests/varargs/assignNonConstSingleArrayElementAsVarargInAnnotationError.fir.kt +++ /dev/null @@ -1,26 +0,0 @@ -// !LANGUAGE: +ProhibitNonConstValuesAsVarargsInAnnotations, +ProhibitAssigningSingleElementsToVarargsInNamedForm - -val nonConstArray = longArrayOf(0) -fun nonConstFun(): LongArray = TODO() - -fun nonConstLong(): Long = TODO() - -annotation class Anno(vararg val value: Long) - -@Anno(value = nonConstArray) -fun foo1() {} - -@Anno(value = nonConstFun()) -fun foo2() {} - -@Anno(value = longArrayOf(nonConstLong())) -fun foo3() {} - -@Anno(value = [nonConstLong()]) -fun foo4() {} - -@Anno(value = *nonConstArray) -fun bar1() {} - -@Anno(*nonConstArray) -fun bar2() {} diff --git a/compiler/testData/diagnostics/tests/varargs/assignNonConstSingleArrayElementAsVarargInAnnotationError.kt b/compiler/testData/diagnostics/tests/varargs/assignNonConstSingleArrayElementAsVarargInAnnotationError.kt index 8ebd09ff23b..427def38c9d 100644 --- a/compiler/testData/diagnostics/tests/varargs/assignNonConstSingleArrayElementAsVarargInAnnotationError.kt +++ b/compiler/testData/diagnostics/tests/varargs/assignNonConstSingleArrayElementAsVarargInAnnotationError.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !LANGUAGE: +ProhibitNonConstValuesAsVarargsInAnnotations, +ProhibitAssigningSingleElementsToVarargsInNamedForm val nonConstArray = longArrayOf(0) diff --git a/compiler/testData/diagnostics/tests/varargs/assigningSingleElementsInNamedFormAnnDeprecation_after.fir.kt b/compiler/testData/diagnostics/tests/varargs/assigningSingleElementsInNamedFormAnnDeprecation_after.fir.kt index 516602d3992..9bfa8255bc9 100644 --- a/compiler/testData/diagnostics/tests/varargs/assigningSingleElementsInNamedFormAnnDeprecation_after.fir.kt +++ b/compiler/testData/diagnostics/tests/varargs/assigningSingleElementsInNamedFormAnnDeprecation_after.fir.kt @@ -14,10 +14,10 @@ annotation class Ann(vararg val s: String) @Ann(s = "value") fun test1() {} -@Ann(s = *arrayOf("value")) +@Ann(s = *arrayOf("value")) fun test2() {} -@Ann(s = *["value"]) +@Ann(s = *["value"]) fun test3() {} @JavaAnn(value = "value") diff --git a/compiler/testData/diagnostics/tests/varargs/assigningSingleElementsInNamedFormAnnDeprecation_before.fir.kt b/compiler/testData/diagnostics/tests/varargs/assigningSingleElementsInNamedFormAnnDeprecation_before.fir.kt index d1f27f1627e..65120850e83 100644 --- a/compiler/testData/diagnostics/tests/varargs/assigningSingleElementsInNamedFormAnnDeprecation_before.fir.kt +++ b/compiler/testData/diagnostics/tests/varargs/assigningSingleElementsInNamedFormAnnDeprecation_before.fir.kt @@ -14,10 +14,10 @@ annotation class Ann(vararg val s: String) @Ann(s = "value") fun test1() {} -@Ann(s = *arrayOf("value")) +@Ann(s = *arrayOf("value")) fun test2() {} -@Ann(s = *["value"]) +@Ann(s = *["value"]) fun test3() {} @JavaAnn(value = "value") diff --git a/compiler/testData/diagnostics/tests/varargs/assigningSingleElementsInNamedFormFunDeprecation_after.fir.kt b/compiler/testData/diagnostics/tests/varargs/assigningSingleElementsInNamedFormFunDeprecation_after.fir.kt index 8d2acd9c7b0..73f882c5f06 100644 --- a/compiler/testData/diagnostics/tests/varargs/assigningSingleElementsInNamedFormFunDeprecation_after.fir.kt +++ b/compiler/testData/diagnostics/tests/varargs/assigningSingleElementsInNamedFormFunDeprecation_after.fir.kt @@ -8,9 +8,9 @@ open class Cls(vararg p: Long) fun test(i: IntArray) { foo(s = 1) foo(s = i) - foo(s = *i) + foo(s = *i) foo(s = intArrayOf(1)) - foo(s = *intArrayOf(1)) + foo(s = *intArrayOf(1)) foo(1) Cls(p = 1) @@ -19,7 +19,7 @@ fun test(i: IntArray) { val c = object : Cls(p = 1) {} - foo(s = *intArrayOf(elements = 1)) + foo(s = *intArrayOf(elements = 1)) } @@ -28,7 +28,7 @@ fun anyFoo(vararg a: Any) {} fun testAny() { anyFoo(a = "") anyFoo(a = arrayOf("")) - anyFoo(a = *arrayOf("")) + anyFoo(a = *arrayOf("")) } fun genFoo(vararg t: T) {} @@ -37,11 +37,11 @@ fun testGen() { genFoo(t = 1) genFoo(t = null) genFoo>(t = arrayOf()) - genFoo>(t = *arrayOf(arrayOf())) + genFoo>(t = *arrayOf(arrayOf())) genFoo(t = "") genFoo(t = arrayOf("")) - genFoo(t = *arrayOf("")) + genFoo(t = *arrayOf("")) } fun manyFoo(vararg v: Int) {} diff --git a/compiler/testData/diagnostics/tests/varargs/assigningSingleElementsInNamedFormFunDeprecation_before.fir.kt b/compiler/testData/diagnostics/tests/varargs/assigningSingleElementsInNamedFormFunDeprecation_before.fir.kt index 73db5c6c769..25c32f77737 100644 --- a/compiler/testData/diagnostics/tests/varargs/assigningSingleElementsInNamedFormFunDeprecation_before.fir.kt +++ b/compiler/testData/diagnostics/tests/varargs/assigningSingleElementsInNamedFormFunDeprecation_before.fir.kt @@ -8,9 +8,9 @@ open class Cls(vararg p: Long) fun test(i: IntArray) { foo(s = 1) foo(s = i) - foo(s = *i) + foo(s = *i) foo(s = intArrayOf(1)) - foo(s = *intArrayOf(1)) + foo(s = *intArrayOf(1)) foo(1) Cls(p = 1) @@ -19,7 +19,7 @@ fun test(i: IntArray) { val c = object : Cls(p = 1) {} - foo(s = *intArrayOf(elements = 1)) + foo(s = *intArrayOf(elements = 1)) } @@ -28,7 +28,7 @@ fun anyFoo(vararg a: Any) {} fun testAny() { anyFoo(a = "") anyFoo(a = arrayOf("")) - anyFoo(a = *arrayOf("")) + anyFoo(a = *arrayOf("")) } fun genFoo(vararg t: T) {} @@ -37,11 +37,11 @@ fun testGen() { genFoo(t = 1) genFoo(t = null) genFoo>(t = arrayOf()) - genFoo>(t = *arrayOf(arrayOf())) + genFoo>(t = *arrayOf(arrayOf())) genFoo(t = "") genFoo(t = arrayOf("")) - genFoo(t = *arrayOf("")) + genFoo(t = *arrayOf("")) } fun manyFoo(vararg v: Int) {} diff --git a/compiler/testData/diagnostics/tests/varargs/prohibitAssigningSingleElementsInNamedForm.fir.kt b/compiler/testData/diagnostics/tests/varargs/prohibitAssigningSingleElementsInNamedForm.fir.kt index dcd2547a208..254086471af 100644 --- a/compiler/testData/diagnostics/tests/varargs/prohibitAssigningSingleElementsInNamedForm.fir.kt +++ b/compiler/testData/diagnostics/tests/varargs/prohibitAssigningSingleElementsInNamedForm.fir.kt @@ -5,7 +5,7 @@ annotation class Anno1(vararg val s: String) annotation class Anno2(vararg val i: Int) @Anno1(s = "foo") -@Anno2(i = *intArrayOf(1)) +@Anno2(i = *intArrayOf(1)) fun f1() {} @Anno1(s = ["foo"]) @@ -13,12 +13,12 @@ fun f1() {} fun f2() {} @Anno1(s = arrayOf(elements = "foo")) -@Anno2(i = intArrayOf(elements = *intArrayOf(1))) +@Anno2(i = intArrayOf(elements = *intArrayOf(1))) fun f3() {} fun foo(vararg ints: Int) {} fun test() { foo(ints = 1) - foo(ints = *intArrayOf(1)) + foo(ints = *intArrayOf(1)) } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt index 1a5b3cedfdc..f337d57e778 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -1400,6 +1400,18 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_ANNOTATION) { firDiagnostic -> + RedundantSpreadOperatorInNamedFormInAnnotationImpl( + firDiagnostic as FirPsiDiagnostic, + token, + ) + } + add(FirErrors.REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION) { firDiagnostic -> + RedundantSpreadOperatorInNamedFormInFunctionImpl( + firDiagnostic as FirPsiDiagnostic, + token, + ) + } add(FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY) { firDiagnostic -> OverloadResolutionAmbiguityImpl( firDiagnostic.a.map { firBasedSymbol -> diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt index 342e2dd7384..799265474f9 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt @@ -1005,6 +1005,14 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = AssigningSingleElementToVarargInNamedFormAnnotationWarning::class } + abstract class RedundantSpreadOperatorInNamedFormInAnnotation : KtFirDiagnostic() { + override val diagnosticClass get() = RedundantSpreadOperatorInNamedFormInAnnotation::class + } + + abstract class RedundantSpreadOperatorInNamedFormInFunction : KtFirDiagnostic() { + override val diagnosticClass get() = RedundantSpreadOperatorInNamedFormInFunction::class + } + abstract class OverloadResolutionAmbiguity : KtFirDiagnostic() { override val diagnosticClass get() = OverloadResolutionAmbiguity::class abstract val candidates: List diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index 1bc058a3a79..5b4888a0226 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -1606,6 +1606,20 @@ internal class AssigningSingleElementToVarargInNamedFormAnnotationWarningImpl( override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) } +internal class RedundantSpreadOperatorInNamedFormInAnnotationImpl( + firDiagnostic: FirPsiDiagnostic, + override val token: ValidityToken, +) : KtFirDiagnostic.RedundantSpreadOperatorInNamedFormInAnnotation(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) +} + +internal class RedundantSpreadOperatorInNamedFormInFunctionImpl( + firDiagnostic: FirPsiDiagnostic, + override val token: ValidityToken, +) : KtFirDiagnostic.RedundantSpreadOperatorInNamedFormInFunction(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) +} + internal class OverloadResolutionAmbiguityImpl( override val candidates: List, firDiagnostic: FirPsiDiagnostic,