FIR: introduce VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION check

Besides adding VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION,
we remove here NO_TYPE_FOR_TYPE_PARAMETER since it doesn't exist in FE1.0.
The name also doesn't make much sense.
From the usage it looks like it should have been
VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION instead.
This commit is contained in:
Tianyu Geng
2021-03-12 15:54:38 -08:00
committed by Mikhail Glukhikh
parent f4b840467f
commit 94de193993
14 changed files with 58 additions and 34 deletions
@@ -235,7 +235,6 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
parameter<Int>("expectedCount")
parameter<FirClassLikeSymbol<*>>("classifier")
}
val NO_TYPE_FOR_TYPE_PARAMETER by error<FirSourceElement, PsiElement>()
val TYPE_PARAMETERS_IN_OBJECT by error<FirSourceElement, PsiElement>()
val ILLEGAL_PROJECTION_USAGE by error<FirSourceElement, PsiElement>()
val TYPE_PARAMETERS_IN_ENUM by error<FirSourceElement, PsiElement>()
@@ -358,6 +357,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
val FORBIDDEN_VARARG_PARAMETER_TYPE by error<FirSourceElement, KtParameter>(PositioningStrategy.PARAMETER_VARARG_MODIFIER) {
parameter<ConeKotlinType>("varargParameterType")
}
val VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION by error<FirSourceElement, KtParameter>()
}
val PROPERTIES_AND_ACCESSORS by object : DiagnosticGroup("Properties & accessors") {
@@ -183,7 +183,6 @@ object FirErrors {
val UPPER_BOUND_VIOLATED by error2<FirSourceElement, PsiElement, FirTypeParameterSymbol, ConeKotlinType>()
val TYPE_ARGUMENTS_NOT_ALLOWED by error0<FirSourceElement, PsiElement>()
val WRONG_NUMBER_OF_TYPE_ARGUMENTS by error2<FirSourceElement, PsiElement, Int, FirClassLikeSymbol<*>>()
val NO_TYPE_FOR_TYPE_PARAMETER by error0<FirSourceElement, PsiElement>()
val TYPE_PARAMETERS_IN_OBJECT by error0<FirSourceElement, PsiElement>()
val ILLEGAL_PROJECTION_USAGE by error0<FirSourceElement, PsiElement>()
val TYPE_PARAMETERS_IN_ENUM by error0<FirSourceElement, PsiElement>()
@@ -236,6 +235,7 @@ object FirErrors {
val USELESS_VARARG_ON_PARAMETER by warning0<FirSourceElement, KtParameter>()
val MULTIPLE_VARARG_PARAMETERS by error0<FirSourceElement, KtParameter>(SourceElementPositioningStrategies.PARAMETER_VARARG_MODIFIER)
val FORBIDDEN_VARARG_PARAMETER_TYPE by error1<FirSourceElement, KtParameter, ConeKotlinType>(SourceElementPositioningStrategies.PARAMETER_VARARG_MODIFIER)
val VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION by error0<FirSourceElement, KtParameter>()
// Properties & accessors
val ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS by error2<FirSourceElement, KtModifierListOwner, FirMemberDeclaration, FirMemberDeclaration>(SourceElementPositioningStrategies.MODALITY_MODIFIER)
@@ -5,13 +5,17 @@
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.fir.FirRealSourceElementKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.isInline
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirFunction
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
import org.jetbrains.kotlin.fir.types.arrayElementType
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.isUnsignedTypeOrNullableUnsignedType
@@ -20,6 +24,25 @@ import org.jetbrains.kotlin.types.AbstractTypeChecker
object FirFunctionParameterChecker : FirFunctionChecker() {
override fun check(declaration: FirFunction<*>, context: CheckerContext, reporter: DiagnosticReporter) {
checkVarargParameters(declaration, context, reporter)
checkParameterTypes(declaration, context, reporter)
}
private fun checkParameterTypes(declaration: FirFunction<*>, context: CheckerContext, reporter: DiagnosticReporter) {
for (valueParameter in declaration.valueParameters) {
val returnTypeRef = valueParameter.returnTypeRef
if (returnTypeRef !is FirErrorTypeRef) continue
// type problems on real source are already reported by ConeDiagnostic.toFirDiagnostics
if (returnTypeRef.source?.kind == FirRealSourceElementKind) continue
val diagnostic = returnTypeRef.diagnostic
if (diagnostic is ConeSimpleDiagnostic && diagnostic.kind == DiagnosticKind.ValueParameterWithNoTypeAnnotation) {
reporter.reportOn(
valueParameter.source,
FirErrors.VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION,
context
)
}
}
}
private fun checkVarargParameters(function: FirFunction<*>, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -55,10 +55,10 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONFLICTING_PROJE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONSTRUCTOR_IN_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONSTRUCTOR_IN_OBJECT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CYCLIC_CONSTRUCTOR_DELEGATION_CALL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATED_PROPERTY_INSIDE_INLINE_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_CLASS_NOT_PROPERTY_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_CLASS_VARARG_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_CLASS_WITHOUT_PARAMETERS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATED_PROPERTY_INSIDE_INLINE_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATED_PROPERTY_IN_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATION_IN_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR
@@ -118,11 +118,11 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_INTERFACE_N
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_OBJECT_NOT_ALLOWED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MANY_COMPANION_OBJECTS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MISSING_VAL_ON_ANNOTATION_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NESTED_CLASS_NOT_ALLOWED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MULTIPLE_VARARG_PARAMETERS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZED_OR_BE_ABSTRACT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NAMED_ARGUMENTS_NOT_ALLOWED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NESTED_CLASS_NOT_ALLOWED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NONE_APPLICABLE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_FINAL_MEMBER_IN_FINAL_CLASS
@@ -136,7 +136,6 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_A_LOOP_LABEL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_A_SUPERTYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_ELSE_IN_WHEN
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_THIS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_TYPE_FOR_TYPE_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NULLABLE_TYPE_IN_CLASS_LITERAL_LHS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NULLABLE_TYPE_OF_ANNOTATION_MEMBER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OTHER_ERROR
@@ -202,9 +201,10 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNSAFE_OPERATOR_C
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNUSED_VARIABLE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UPPER_BOUND_VIOLATED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_VARARG_ON_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CANNOT_BE_CLONEABLE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_REASSIGNMENT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_WITH_SETTER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CANNOT_BE_CLONEABLE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VARARG_OUTSIDE_PARENTHESES
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VARIABLE_EXPECTED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VARIABLE_INITIALIZER_IS_REDUNDANT
@@ -381,7 +381,6 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
null,
TO_STRING
)
map.put(NO_TYPE_FOR_TYPE_PARAMETER, "There're no types suitable for this type parameter") // &
map.put(TYPE_PARAMETERS_IN_OBJECT, "Type parameters are not allowed for objects")
// map.put(ILLEGAL_PROJECTION_USAGE, ...) // &
map.put(TYPE_PARAMETERS_IN_ENUM, "Enum class cannot have type parameters")
@@ -529,6 +528,7 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
map.put(USELESS_VARARG_ON_PARAMETER, "Vararg on this parameter is useless")
map.put(MULTIPLE_VARARG_PARAMETERS, "Multiple vararg-parameters are prohibited")
map.put(FORBIDDEN_VARARG_PARAMETER_TYPE, "Forbidden vararg parameter type: {0}", RENDER_TYPE)
map.put(VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION, "A type annotation is required on a value parameter")
// Properties & accessors
map.put(
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.kotlin.utils.ifEmpty
private fun ConeDiagnostic.toFirDiagnostic(source: FirSourceElement): FirDiagnostic<FirSourceElement>? = when (this) {
is ConeUnresolvedReferenceError -> FirErrors.UNRESOLVED_REFERENCE.on(source, this.name?.asString() ?: "<No name>")
@@ -147,7 +146,7 @@ private fun ConeSimpleDiagnostic.getFactory(): FirDiagnosticFactory0<FirSourceEl
DiagnosticKind.JumpOutsideLoop -> FirErrors.BREAK_OR_CONTINUE_OUTSIDE_A_LOOP
DiagnosticKind.NotLoopLabel -> FirErrors.NOT_A_LOOP_LABEL
DiagnosticKind.VariableExpected -> FirErrors.VARIABLE_EXPECTED
DiagnosticKind.NoTypeForTypeParameter -> FirErrors.NO_TYPE_FOR_TYPE_PARAMETER
DiagnosticKind.ValueParameterWithNoTypeAnnotation -> FirErrors.VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION
DiagnosticKind.UnknownCallableKind -> FirErrors.UNKNOWN_CALLABLE_KIND
DiagnosticKind.IllegalProjectionUsage -> FirErrors.ILLEGAL_PROJECTION_USAGE
DiagnosticKind.MissingStdlibClass -> FirErrors.MISSING_STDLIB_CLASS
@@ -53,7 +53,7 @@ fun FirFunction<*>.constructFunctionalTypeRef(isSuspend: Boolean = false): FirRe
it.returnTypeRef.coneTypeSafe<ConeKotlinType>() ?: ConeKotlinErrorType(
ConeSimpleDiagnostic(
"No type for parameter",
DiagnosticKind.NoTypeForTypeParameter
DiagnosticKind.ValueParameterWithNoTypeAnnotation
)
)
}
@@ -578,7 +578,9 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
if (valueParameter.returnTypeRef is FirImplicitTypeRef) {
transformer.replaceDeclarationResolvePhaseIfNeeded(valueParameter, transformerPhase)
valueParameter.replaceReturnTypeRef(
valueParameter.returnTypeRef.errorTypeFromPrototype(ConeSimpleDiagnostic("Unresolved value parameter type"))
valueParameter.returnTypeRef.errorTypeFromPrototype(
ConeSimpleDiagnostic("No type for parameter", DiagnosticKind.ValueParameterWithNoTypeAnnotation)
)
)
return context.withValueParameter(valueParameter) {
valueParameter.compose()
@@ -833,7 +835,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
valueParameter.transformReturnTypeRef(
StoreType,
valueParameter.returnTypeRef.resolvedTypeFromPrototype(
ConeKotlinErrorType(ConeSimpleDiagnostic("No type for parameter", DiagnosticKind.NoTypeForTypeParameter))
ConeKotlinErrorType(ConeSimpleDiagnostic("No type for parameter", DiagnosticKind.ValueParameterWithNoTypeAnnotation))
)
)
}
@@ -27,10 +27,10 @@ enum class DiagnosticKind {
RecursionInImplicitTypes,
Java,
SuperNotAllowed,
NoTypeForTypeParameter,
ValueParameterWithNoTypeAnnotation,
UnknownCallableKind,
SymbolNotFound,
IllegalProjectionUsage,
MissingStdlibClass,
Other
}
}
@@ -1,5 +1,5 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_ANONYMOUS_PARAMETER -UNUSED_VARIABLE
fun test(a) {
fun test(<!VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>a<!>, <!VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>b<!>, <!VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>c<!>) {
}
@@ -1,5 +1,5 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_ANONYMOUS_PARAMETER -UNUSED_VARIABLE
fun test(<!VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>a<!>) {
fun test(<!VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>a<!>, <!VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>b<!>, <!VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION!>c<!>) {
}
@@ -3,7 +3,7 @@ package
public val bar: (???) -> kotlin.Unit
public val la: (???) -> kotlin.Unit
public val las: (kotlin.Int) -> kotlin.Unit
public fun test(/*0*/ a: [ERROR : Type annotation was missing for parameter a]): kotlin.Unit
public fun test(/*0*/ a: [ERROR : Type annotation was missing for parameter a], /*1*/ b: [ERROR : Type annotation was missing for parameter b], /*2*/ c: [ERROR : Type annotation was missing for parameter c]): kotlin.Unit
public final class A {
public constructor A(/*0*/ a: [ERROR : Type annotation was missing for parameter a])
@@ -738,12 +738,6 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.NO_TYPE_FOR_TYPE_PARAMETER) { firDiagnostic ->
NoTypeForTypeParameterImpl(
firDiagnostic as FirPsiDiagnostic<*>,
token,
)
}
add(FirErrors.TYPE_PARAMETERS_IN_OBJECT) { firDiagnostic ->
TypeParametersInObjectImpl(
firDiagnostic as FirPsiDiagnostic<*>,
@@ -1032,6 +1026,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION) { firDiagnostic ->
ValueParameterWithNoTypeAnnotationImpl(
firDiagnostic as FirPsiDiagnostic<*>,
token,
)
}
add(FirErrors.ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS) { firDiagnostic ->
AbstractPropertyInNonAbstractClassImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a as FirDeclaration),
@@ -525,10 +525,6 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
abstract val classifier: KtClassLikeSymbol
}
abstract class NoTypeForTypeParameter : KtFirDiagnostic<PsiElement>() {
override val diagnosticClass get() = NoTypeForTypeParameter::class
}
abstract class TypeParametersInObject : KtFirDiagnostic<PsiElement>() {
override val diagnosticClass get() = TypeParametersInObject::class
}
@@ -729,6 +725,10 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
abstract val varargParameterType: KtType
}
abstract class ValueParameterWithNoTypeAnnotation : KtFirDiagnostic<KtParameter>() {
override val diagnosticClass get() = ValueParameterWithNoTypeAnnotation::class
}
abstract class AbstractPropertyInNonAbstractClass : KtFirDiagnostic<KtModifierListOwner>() {
override val diagnosticClass get() = AbstractPropertyInNonAbstractClass::class
abstract val property: KtSymbol
@@ -844,13 +844,6 @@ internal class WrongNumberOfTypeArgumentsImpl(
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class NoTypeForTypeParameterImpl(
firDiagnostic: FirPsiDiagnostic<*>,
override val token: ValidityToken,
) : KtFirDiagnostic.NoTypeForTypeParameter(), KtAbstractFirDiagnostic<PsiElement> {
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class TypeParametersInObjectImpl(
firDiagnostic: FirPsiDiagnostic<*>,
override val token: ValidityToken,
@@ -1177,6 +1170,13 @@ internal class ForbiddenVarargParameterTypeImpl(
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class ValueParameterWithNoTypeAnnotationImpl(
firDiagnostic: FirPsiDiagnostic<*>,
override val token: ValidityToken,
) : KtFirDiagnostic.ValueParameterWithNoTypeAnnotation(), KtAbstractFirDiagnostic<KtParameter> {
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class AbstractPropertyInNonAbstractClassImpl(
override val property: KtSymbol,
override val containingClass: KtSymbol,