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 ->
|
add(FirErrors.ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION.errorFactory) { firDiagnostic ->
|
||||||
AssigningSingleElementToVarargInNamedFormFunctionErrorImpl(
|
AssigningSingleElementToVarargInNamedFormFunctionErrorImpl(
|
||||||
|
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||||
firDiagnostic as KtPsiDiagnostic,
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
add(FirErrors.ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION.warningFactory) { firDiagnostic ->
|
add(FirErrors.ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION.warningFactory) { firDiagnostic ->
|
||||||
AssigningSingleElementToVarargInNamedFormFunctionWarningImpl(
|
AssigningSingleElementToVarargInNamedFormFunctionWarningImpl(
|
||||||
|
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||||
firDiagnostic as KtPsiDiagnostic,
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
|
|||||||
+2
@@ -1062,10 +1062,12 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
|
|
||||||
abstract class AssigningSingleElementToVarargInNamedFormFunctionError : KtFirDiagnostic<KtExpression>() {
|
abstract class AssigningSingleElementToVarargInNamedFormFunctionError : KtFirDiagnostic<KtExpression>() {
|
||||||
override val diagnosticClass get() = AssigningSingleElementToVarargInNamedFormFunctionError::class
|
override val diagnosticClass get() = AssigningSingleElementToVarargInNamedFormFunctionError::class
|
||||||
|
abstract val expectedArrayType: KtType
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class AssigningSingleElementToVarargInNamedFormFunctionWarning : KtFirDiagnostic<KtExpression>() {
|
abstract class AssigningSingleElementToVarargInNamedFormFunctionWarning : KtFirDiagnostic<KtExpression>() {
|
||||||
override val diagnosticClass get() = AssigningSingleElementToVarargInNamedFormFunctionWarning::class
|
override val diagnosticClass get() = AssigningSingleElementToVarargInNamedFormFunctionWarning::class
|
||||||
|
abstract val expectedArrayType: KtType
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class AssigningSingleElementToVarargInNamedFormAnnotationError : KtFirDiagnostic<KtExpression>() {
|
abstract class AssigningSingleElementToVarargInNamedFormAnnotationError : KtFirDiagnostic<KtExpression>() {
|
||||||
|
|||||||
+2
@@ -1270,11 +1270,13 @@ internal class SpreadOfNullableImpl(
|
|||||||
) : KtFirDiagnostic.SpreadOfNullable(), KtAbstractFirDiagnostic<PsiElement>
|
) : KtFirDiagnostic.SpreadOfNullable(), KtAbstractFirDiagnostic<PsiElement>
|
||||||
|
|
||||||
internal class AssigningSingleElementToVarargInNamedFormFunctionErrorImpl(
|
internal class AssigningSingleElementToVarargInNamedFormFunctionErrorImpl(
|
||||||
|
override val expectedArrayType: KtType,
|
||||||
override val firDiagnostic: KtPsiDiagnostic,
|
override val firDiagnostic: KtPsiDiagnostic,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
) : KtFirDiagnostic.AssigningSingleElementToVarargInNamedFormFunctionError(), KtAbstractFirDiagnostic<KtExpression>
|
) : KtFirDiagnostic.AssigningSingleElementToVarargInNamedFormFunctionError(), KtAbstractFirDiagnostic<KtExpression>
|
||||||
|
|
||||||
internal class AssigningSingleElementToVarargInNamedFormFunctionWarningImpl(
|
internal class AssigningSingleElementToVarargInNamedFormFunctionWarningImpl(
|
||||||
|
override val expectedArrayType: KtType,
|
||||||
override val firDiagnostic: KtPsiDiagnostic,
|
override val firDiagnostic: KtPsiDiagnostic,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
) : KtFirDiagnostic.AssigningSingleElementToVarargInNamedFormFunctionWarning(), KtAbstractFirDiagnostic<KtExpression>
|
) : 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 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 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_ANNOTATION by warning<KtExpression>()
|
||||||
val REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION 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 MANY_LAMBDA_EXPRESSION_ARGUMENTS by error0<KtValueArgument>()
|
||||||
val NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER by error1<KtElement, String>()
|
val NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER by error1<KtElement, String>()
|
||||||
val SPREAD_OF_NULLABLE by error0<PsiElement>(SourceElementPositioningStrategies.SPREAD_OPERATOR)
|
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 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_ANNOTATION by warning0<KtExpression>()
|
||||||
val REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION 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.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
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.FirErrorTypeRef
|
||||||
|
import org.jetbrains.kotlin.fir.types.coneType
|
||||||
import org.jetbrains.kotlin.fir.types.isArrayType
|
import org.jetbrains.kotlin.fir.types.isArrayType
|
||||||
|
|
||||||
object FirNamedVarargChecker : FirCallChecker() {
|
object FirNamedVarargChecker : FirCallChecker() {
|
||||||
@@ -28,9 +30,6 @@ object FirNamedVarargChecker : FirCallChecker() {
|
|||||||
expression !is FirDelegatedConstructorCall &&
|
expression !is FirDelegatedConstructorCall &&
|
||||||
expression !is FirArrayOfCall) return
|
expression !is FirArrayOfCall) return
|
||||||
val isAnnotation = expression is FirAnnotation
|
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 =
|
val redundantSpreadWarningFactory =
|
||||||
if (isAnnotation) FirErrors.REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_ANNOTATION
|
if (isAnnotation) FirErrors.REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_ANNOTATION
|
||||||
else FirErrors.REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION
|
else FirErrors.REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION
|
||||||
@@ -40,7 +39,7 @@ object FirNamedVarargChecker : FirCallChecker() {
|
|||||||
else LanguageFeature.AllowAssigningArrayElementsToVarargsInNamedFormForFunctions
|
else LanguageFeature.AllowAssigningArrayElementsToVarargsInNamedFormForFunctions
|
||||||
)
|
)
|
||||||
|
|
||||||
fun checkArgument(argument: FirExpression, isVararg: Boolean) {
|
fun checkArgument(argument: FirExpression, isVararg: Boolean, expectedArrayType: ConeKotlinType?) {
|
||||||
if (argument !is FirNamedArgumentExpression) return
|
if (argument !is FirNamedArgumentExpression) return
|
||||||
if (argument.isSpread) {
|
if (argument.isSpread) {
|
||||||
if (isVararg && (expression as? FirResolvable)?.calleeReference !is FirErrorNamedReference) {
|
if (isVararg && (expression as? FirResolvable)?.calleeReference !is FirErrorNamedReference) {
|
||||||
@@ -53,20 +52,34 @@ object FirNamedVarargChecker : FirCallChecker() {
|
|||||||
if (argument.expression is FirArrayOfCall) return
|
if (argument.expression is FirArrayOfCall) return
|
||||||
if (allowAssignArray && typeRef.isArrayType) 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) {
|
if (expression is FirArrayOfCall) {
|
||||||
// FirArrayOfCall has the `vararg` argument expression pre-flattened and doesn't have an argument mapping.
|
// 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 {
|
} else {
|
||||||
val argumentMap = expression.argumentMapping ?: return
|
val argumentMap = expression.argumentMapping ?: return
|
||||||
for ((argument, parameter) in argumentMap) {
|
for ((argument, parameter) in argumentMap) {
|
||||||
if (!parameter.isVararg) continue
|
if (!parameter.isVararg) continue
|
||||||
if (argument is FirVarargArgumentsExpression) {
|
if (argument is FirVarargArgumentsExpression) {
|
||||||
argument.arguments.forEach { checkArgument(it, true) }
|
argument.arguments.forEach { checkArgument(it, true, parameter.returnTypeRef.coneType) }
|
||||||
} else {
|
} 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(SPREAD_OF_NULLABLE, "The spread operator (*foo) may not be applied to an argument of nullable type")
|
||||||
map.put(
|
map.put(
|
||||||
ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION,
|
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(
|
map.put(
|
||||||
ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION,
|
ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION,
|
||||||
|
|||||||
Reference in New Issue
Block a user