FIR checker: pass expected array type in ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION
This is needed by the IDE quickfix to generate the correct `arrayOf` (or `intArrayOf`, etc`) wrapper call.
This commit is contained in:
+2
@@ -1475,12 +1475,14 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
}
|
||||
add(FirErrors.ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION.errorFactory) { firDiagnostic ->
|
||||
AssigningSingleElementToVarargInNamedFormFunctionErrorImpl(
|
||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION.warningFactory) { firDiagnostic ->
|
||||
AssigningSingleElementToVarargInNamedFormFunctionWarningImpl(
|
||||
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
|
||||
+2
@@ -1062,10 +1062,12 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
|
||||
abstract class AssigningSingleElementToVarargInNamedFormFunctionError : KtFirDiagnostic<KtExpression>() {
|
||||
override val diagnosticClass get() = AssigningSingleElementToVarargInNamedFormFunctionError::class
|
||||
abstract val expectedArrayType: KtType
|
||||
}
|
||||
|
||||
abstract class AssigningSingleElementToVarargInNamedFormFunctionWarning : KtFirDiagnostic<KtExpression>() {
|
||||
override val diagnosticClass get() = AssigningSingleElementToVarargInNamedFormFunctionWarning::class
|
||||
abstract val expectedArrayType: KtType
|
||||
}
|
||||
|
||||
abstract class AssigningSingleElementToVarargInNamedFormAnnotationError : KtFirDiagnostic<KtExpression>() {
|
||||
|
||||
+2
@@ -1270,11 +1270,13 @@ internal class SpreadOfNullableImpl(
|
||||
) : KtFirDiagnostic.SpreadOfNullable(), KtAbstractFirDiagnostic<PsiElement>
|
||||
|
||||
internal class AssigningSingleElementToVarargInNamedFormFunctionErrorImpl(
|
||||
override val expectedArrayType: KtType,
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.AssigningSingleElementToVarargInNamedFormFunctionError(), KtAbstractFirDiagnostic<KtExpression>
|
||||
|
||||
internal class AssigningSingleElementToVarargInNamedFormFunctionWarningImpl(
|
||||
override val expectedArrayType: KtType,
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.AssigningSingleElementToVarargInNamedFormFunctionWarning(), KtAbstractFirDiagnostic<KtExpression>
|
||||
|
||||
+3
-1
@@ -493,7 +493,9 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
|
||||
val SPREAD_OF_NULLABLE by error<PsiElement>(PositioningStrategy.SPREAD_OPERATOR)
|
||||
|
||||
val ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION by deprecationError<KtExpression>(LanguageFeature.ProhibitAssigningSingleElementsToVarargsInNamedForm)
|
||||
val ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION by deprecationError<KtExpression>(LanguageFeature.ProhibitAssigningSingleElementsToVarargsInNamedForm) {
|
||||
parameter<ConeKotlinType>("expectedArrayType")
|
||||
}
|
||||
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>()
|
||||
|
||||
+1
-1
@@ -334,7 +334,7 @@ object FirErrors {
|
||||
val MANY_LAMBDA_EXPRESSION_ARGUMENTS by error0<KtValueArgument>()
|
||||
val NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER by error1<KtElement, String>()
|
||||
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_FUNCTION by deprecationError1<KtExpression, ConeKotlinType>(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>()
|
||||
|
||||
+21
-8
@@ -18,7 +18,9 @@ import org.jetbrains.kotlin.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.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.fir.types.isArrayType
|
||||
|
||||
object FirNamedVarargChecker : FirCallChecker() {
|
||||
@@ -28,9 +30,6 @@ object FirNamedVarargChecker : FirCallChecker() {
|
||||
expression !is FirDelegatedConstructorCall &&
|
||||
expression !is FirArrayOfCall) return
|
||||
val isAnnotation = expression is FirAnnotation
|
||||
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
|
||||
@@ -40,7 +39,7 @@ object FirNamedVarargChecker : FirCallChecker() {
|
||||
else LanguageFeature.AllowAssigningArrayElementsToVarargsInNamedFormForFunctions
|
||||
)
|
||||
|
||||
fun checkArgument(argument: FirExpression, isVararg: Boolean) {
|
||||
fun checkArgument(argument: FirExpression, isVararg: Boolean, expectedArrayType: ConeKotlinType?) {
|
||||
if (argument !is FirNamedArgumentExpression) return
|
||||
if (argument.isSpread) {
|
||||
if (isVararg && (expression as? FirResolvable)?.calleeReference !is FirErrorNamedReference) {
|
||||
@@ -53,20 +52,34 @@ object FirNamedVarargChecker : FirCallChecker() {
|
||||
if (argument.expression is FirArrayOfCall) return
|
||||
if (allowAssignArray && typeRef.isArrayType) return
|
||||
|
||||
reporter.reportOn(argument.expression.source, singleElementToVarargErrorFactory, context)
|
||||
if (isAnnotation) {
|
||||
reporter.reportOn(
|
||||
argument.expression.source,
|
||||
FirErrors.ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION,
|
||||
context
|
||||
)
|
||||
} else {
|
||||
require(expectedArrayType != null) { "expectedArrayType must be passed for function call" }
|
||||
reporter.reportOn(
|
||||
argument.expression.source,
|
||||
FirErrors.ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION,
|
||||
expectedArrayType,
|
||||
context,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (expression is FirArrayOfCall) {
|
||||
// FirArrayOfCall has the `vararg` argument expression pre-flattened and doesn't have an argument mapping.
|
||||
expression.arguments.forEach { checkArgument(it, it is FirNamedArgumentExpression) }
|
||||
expression.arguments.forEach { checkArgument(it, it is FirNamedArgumentExpression, null /* not used for annotation call */) }
|
||||
} else {
|
||||
val argumentMap = expression.argumentMapping ?: return
|
||||
for ((argument, parameter) in argumentMap) {
|
||||
if (!parameter.isVararg) continue
|
||||
if (argument is FirVarargArgumentsExpression) {
|
||||
argument.arguments.forEach { checkArgument(it, true) }
|
||||
argument.arguments.forEach { checkArgument(it, true, parameter.returnTypeRef.coneType) }
|
||||
} else {
|
||||
checkArgument(argument, false)
|
||||
checkArgument(argument, false, parameter.returnTypeRef.coneType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -839,7 +839,8 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
||||
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"
|
||||
"Assigning single elements to varargs in named form is forbidden",
|
||||
NOT_RENDERED
|
||||
)
|
||||
map.put(
|
||||
ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION,
|
||||
|
||||
Reference in New Issue
Block a user