FIR checker: ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_(ANNOTATION|FUNCTION)

This commit is contained in:
Tianyu Geng
2021-09-08 15:38:27 -07:00
committed by teamcityserver
parent e95de0a778
commit dfc36ec614
22 changed files with 87 additions and 87 deletions
@@ -10,7 +10,7 @@ fun test() {
foo(<!ARGUMENT_TYPE_MISMATCH!>""<!>)
foo(1, <!ARGUMENT_TYPE_MISMATCH!>2<!>)
bar(1, z = true, y = *arrayOf("my", "yours"))
bar(1, z = true, y = *<!REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION!>arrayOf("my", "yours")<!>)
bar(0, z = false, y = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>""<!>, <!ARGUMENT_PASSED_TWICE!>y<!> = "other")
bar(0, "", true<!NO_VALUE_FOR_PARAMETER!>)<!>
@@ -463,6 +463,8 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION by deprecationError<KtExpression>(LanguageFeature.ProhibitAssigningSingleElementsToVarargsInNamedForm)
val ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION by deprecationError<KtExpression>(LanguageFeature.ProhibitAssigningSingleElementsToVarargsInNamedForm)
val REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_ANNOTATION by warning<KtExpression>()
val REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION by warning<KtExpression>()
}
val AMBIGUITY by object : DiagnosticGroup("Ambiguity") {
@@ -320,6 +320,8 @@ object FirErrors {
val SPREAD_OF_NULLABLE by error0<PsiElement>(SourceElementPositioningStrategies.SPREAD_OPERATOR)
val ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION by deprecationError0<KtExpression>(ProhibitAssigningSingleElementsToVarargsInNamedForm)
val ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION by deprecationError0<KtExpression>(ProhibitAssigningSingleElementsToVarargsInNamedForm)
val REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_ANNOTATION by warning0<KtExpression>()
val REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION by warning0<KtExpression>()
// Ambiguity
val OVERLOAD_RESOLUTION_AMBIGUITY by error1<PsiElement, Collection<FirBasedSymbol<*>>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
@@ -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)
}
}
}
}
}
@@ -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)
@@ -6,7 +6,7 @@ fun foo(vararg x: Unit, y: Any) {}
fun main() {
foo({ }(), y = { }())
foo(x = *arrayOf({ }()), y = { }())
foo(x = *<!REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION!>arrayOf({ }())<!>, y = { }())
foo(x = arrayOf({ }()), y = { }())
foo(*arrayOf({ }()), y = { }())
}
@@ -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({ }()))
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_PARAMETER
// !LANGUAGE: +UseCorrectExecutionOrderForVarargArguments
// WITH_RUNTIME
@@ -22,7 +22,7 @@ fun test1_2() {}
@Ann2(*[])
fun test2() {}
@Ann3(a = *[0f, <!DIVISION_BY_ZERO!>1 / 0f<!>])
@Ann3(a = *<!REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_ANNOTATION!>[0f, <!DIVISION_BY_ZERO!>1 / 0f<!>]<!>)
fun test3() {}
@Ann5(Ann4(*["/"]))
@@ -12,7 +12,7 @@ fun test_fun(s: String, arr: Array<String>) {
withVararg(<!ARGUMENT_TYPE_MISMATCH!>arr<!>) // Error
withVararg(*arr) // OK
withVararg(s = <!ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>arr<!>) // Error
withVararg(s = *arr) // OK
withVararg(s = *<!REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION!>arr<!>) // OK
withVararg(s) // OK
withVararg(s = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>s<!>) // Error
@@ -25,7 +25,7 @@ fun test_ann(s: String, arr: Array<String>) {
foo()
@Ann(s = [""], x = 1)
foo()
@Ann(s = *[""], x = 1)
@Ann(s = *<!REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_ANNOTATION!>[""]<!>, x = 1)
foo()
@Ann("", x = 1)
@@ -12,7 +12,7 @@ fun test_fun(s: String, arr: Array<String>) {
withVararg(<!ARGUMENT_TYPE_MISMATCH!>arr<!>) // Error
withVararg(*arr) // OK
withVararg(s = arr) // OK
withVararg(s = *arr) // Warning
withVararg(s = *<!REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION!>arr<!>) // Warning
withVararg(s) // OK
withVararg(s = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>s<!>) // Error
@@ -25,7 +25,7 @@ fun test_ann(s: String, arr: Array<String>) {
foo()
@Ann(s = [""], x = 1)
foo()
@Ann(s = *[""], x = 1)
@Ann(s = *<!REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_ANNOTATION!>[""]<!>, x = 1)
foo()
@Ann("", x = 1)
@@ -19,7 +19,7 @@ fun foo3() {}
@Anno(value = <!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>[<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>nonConstLong()<!>]<!>)
fun foo4() {}
@Anno(value = *<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>nonConstArray<!>)
@Anno(value = *<!ANNOTATION_ARGUMENT_MUST_BE_CONST, REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_ANNOTATION!>nonConstArray<!>)
fun bar1() {}
@Anno(*<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>nonConstArray<!>)
@@ -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 = <!ANNOTATION_ARGUMENT_MUST_BE_CONST!>nonConstArray<!>)
fun foo1() {}
@Anno(value = <!ANNOTATION_ARGUMENT_MUST_BE_CONST!>nonConstFun()<!>)
fun foo2() {}
@Anno(value = <!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>longArrayOf(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>nonConstLong()<!>)<!>)
fun foo3() {}
@Anno(value = <!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>[<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>nonConstLong()<!>]<!>)
fun foo4() {}
@Anno(value = *<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>nonConstArray<!>)
fun bar1() {}
@Anno(*<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>nonConstArray<!>)
fun bar2() {}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !LANGUAGE: +ProhibitNonConstValuesAsVarargsInAnnotations, +ProhibitAssigningSingleElementsToVarargsInNamedForm
val nonConstArray = longArrayOf(0)
@@ -14,10 +14,10 @@ annotation class Ann(vararg val s: String)
@Ann(s = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION_ERROR!>"value"<!>)
fun test1() {}
@Ann(s = *arrayOf("value"))
@Ann(s = *<!REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_ANNOTATION!>arrayOf("value")<!>)
fun test2() {}
@Ann(s = *["value"])
@Ann(s = *<!REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_ANNOTATION!>["value"]<!>)
fun test3() {}
@JavaAnn(value = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION_ERROR!>"value"<!>)
@@ -14,10 +14,10 @@ annotation class Ann(vararg val s: String)
@Ann(s = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION_WARNING!>"value"<!>)
fun test1() {}
@Ann(s = *arrayOf("value"))
@Ann(s = *<!REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_ANNOTATION!>arrayOf("value")<!>)
fun test2() {}
@Ann(s = *["value"])
@Ann(s = *<!REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_ANNOTATION!>["value"]<!>)
fun test3() {}
@JavaAnn(value = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION_WARNING!>"value"<!>)
@@ -8,9 +8,9 @@ open class Cls(vararg p: Long)
fun test(i: IntArray) {
foo(s = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>1<!>)
foo(s = <!ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>i<!>)
foo(s = *i)
foo(s = *<!REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION!>i<!>)
foo(s = <!ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>intArrayOf(1)<!>)
foo(s = *intArrayOf(1))
foo(s = *<!REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION!>intArrayOf(1)<!>)
foo(1)
Cls(p = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>1<!>)
@@ -19,7 +19,7 @@ fun test(i: IntArray) {
val c = object : Cls(p = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>1<!>) {}
foo(s = *intArrayOf(elements = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>1<!>))
foo(s = *<!REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION!>intArrayOf(elements = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>1<!>)<!>)
}
@@ -28,7 +28,7 @@ fun anyFoo(vararg a: Any) {}
fun testAny() {
anyFoo(a = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>""<!>)
anyFoo(a = <!ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>arrayOf("")<!>)
anyFoo(a = *arrayOf(""))
anyFoo(a = *<!REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION!>arrayOf("")<!>)
}
fun <T> genFoo(vararg t: T) {}
@@ -37,11 +37,11 @@ fun testGen() {
genFoo<Int>(t = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>1<!>)
genFoo<Int?>(t = <!ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR, NULL_FOR_NONNULL_TYPE!>null<!>)
genFoo<Array<Int>>(t = <!ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>arrayOf()<!>)
genFoo<Array<Int>>(t = *arrayOf(arrayOf()))
genFoo<Array<Int>>(t = *<!REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION!>arrayOf(arrayOf())<!>)
genFoo(t = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>""<!>)
genFoo(t = <!ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>arrayOf("")<!>)
genFoo(t = *arrayOf(""))
genFoo(t = *<!REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION!>arrayOf("")<!>)
}
fun manyFoo(vararg v: Int) {}
@@ -8,9 +8,9 @@ open class Cls(vararg p: Long)
fun test(i: IntArray) {
foo(s = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_WARNING!>1<!>)
foo(s = <!ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_WARNING!>i<!>)
foo(s = *i)
foo(s = *<!REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION!>i<!>)
foo(s = <!ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_WARNING!>intArrayOf(1)<!>)
foo(s = *intArrayOf(1))
foo(s = *<!REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION!>intArrayOf(1)<!>)
foo(1)
Cls(p = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_WARNING!>1<!>)
@@ -19,7 +19,7 @@ fun test(i: IntArray) {
val c = object : Cls(p = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_WARNING!>1<!>) {}
foo(s = *intArrayOf(elements = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_WARNING!>1<!>))
foo(s = *<!REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION!>intArrayOf(elements = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_WARNING!>1<!>)<!>)
}
@@ -28,7 +28,7 @@ fun anyFoo(vararg a: Any) {}
fun testAny() {
anyFoo(a = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_WARNING!>""<!>)
anyFoo(a = <!ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_WARNING!>arrayOf("")<!>)
anyFoo(a = *arrayOf(""))
anyFoo(a = *<!REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION!>arrayOf("")<!>)
}
fun <T> genFoo(vararg t: T) {}
@@ -37,11 +37,11 @@ fun testGen() {
genFoo<Int>(t = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_WARNING!>1<!>)
genFoo<Int?>(t = <!ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_WARNING, NULL_FOR_NONNULL_TYPE!>null<!>)
genFoo<Array<Int>>(t = <!ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_WARNING!>arrayOf()<!>)
genFoo<Array<Int>>(t = *arrayOf(arrayOf()))
genFoo<Array<Int>>(t = *<!REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION!>arrayOf(arrayOf())<!>)
genFoo(t = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_WARNING!>""<!>)
genFoo(t = <!ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_WARNING!>arrayOf("")<!>)
genFoo(t = *arrayOf(""))
genFoo(t = *<!REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION!>arrayOf("")<!>)
}
fun manyFoo(vararg v: Int) {}
@@ -5,7 +5,7 @@ annotation class Anno1(vararg val s: String)
annotation class Anno2(vararg val i: Int)
@Anno1(s = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION_ERROR!>"foo"<!>)
@Anno2(i = *intArrayOf(1))
@Anno2(i = *<!REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_ANNOTATION!>intArrayOf(1)<!>)
fun f1() {}
@Anno1(s = ["foo"])
@@ -13,12 +13,12 @@ fun f1() {}
fun f2() {}
@Anno1(s = arrayOf(elements = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>"foo"<!>))
@Anno2(i = intArrayOf(elements = *intArrayOf(1)))
@Anno2(i = intArrayOf(elements = *<!REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION!>intArrayOf(1)<!>))
fun f3() {}
fun foo(vararg ints: Int) {}
fun test() {
foo(ints = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>1<!>)
foo(ints = *intArrayOf(1))
foo(ints = *<!REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION!>intArrayOf(1)<!>)
}
@@ -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 ->
@@ -1005,6 +1005,14 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
override val diagnosticClass get() = AssigningSingleElementToVarargInNamedFormAnnotationWarning::class
}
abstract class RedundantSpreadOperatorInNamedFormInAnnotation : KtFirDiagnostic<KtExpression>() {
override val diagnosticClass get() = RedundantSpreadOperatorInNamedFormInAnnotation::class
}
abstract class RedundantSpreadOperatorInNamedFormInFunction : KtFirDiagnostic<KtExpression>() {
override val diagnosticClass get() = RedundantSpreadOperatorInNamedFormInFunction::class
}
abstract class OverloadResolutionAmbiguity : KtFirDiagnostic<PsiElement>() {
override val diagnosticClass get() = OverloadResolutionAmbiguity::class
abstract val candidates: List<KtSymbol>
@@ -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<KtExpression> {
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
}
internal class RedundantSpreadOperatorInNamedFormInFunctionImpl(
firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken,
) : KtFirDiagnostic.RedundantSpreadOperatorInNamedFormInFunction(), KtAbstractFirDiagnostic<KtExpression> {
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
}
internal class OverloadResolutionAmbiguityImpl(
override val candidates: List<KtSymbol>,
firDiagnostic: FirPsiDiagnostic,