[FIR] Add TYPE_PARAMETERS_NOT_ALLOWED check

This commit is contained in:
Andrey Zinovyev
2021-04-12 11:18:14 +03:00
committed by TeamCityServer
parent 5ff82addc9
commit 470993ac07
9 changed files with 60 additions and 11 deletions
@@ -322,6 +322,8 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
val REIFIED_TYPE_PARAMETER_NO_INLINE by error<FirSourceElement, PsiElement>()
val TYPE_PARAMETERS_NOT_ALLOWED by error<FirSourceElement, KtDeclaration>()
val RETURN_TYPE_MISMATCH by error<FirSourceElement, KtExpression>(PositioningStrategy.WHOLE_ELEMENT) {
parameter<ConeKotlinType>("expected")
parameter<ConeKotlinType>("actual")
@@ -237,6 +237,7 @@ object FirErrors {
val NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER by error2<FirSourceElement, KtSimpleNameExpression, Name, FirDeclaration>()
val BOUND_ON_TYPE_ALIAS_PARAMETER_NOT_ALLOWED by error0<FirSourceElement, KtTypeReference>()
val REIFIED_TYPE_PARAMETER_NO_INLINE by error0<FirSourceElement, PsiElement>()
val TYPE_PARAMETERS_NOT_ALLOWED by error0<FirSourceElement, KtDeclaration>()
val RETURN_TYPE_MISMATCH by error2<FirSourceElement, KtExpression, ConeKotlinType, ConeKotlinType>(SourceElementPositioningStrategies.WHOLE_ELEMENT)
// Reflection
@@ -6,11 +6,10 @@
package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
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.analysis.diagnostics.*
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.toFirLightSourceElement
object FirAnonymousFunctionChecker : FirExpressionChecker<FirStatement>() {
override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -26,5 +25,23 @@ object FirAnonymousFunctionChecker : FirExpressionChecker<FirStatement>() {
reporter.reportOn(source, FirErrors.USELESS_VARARG_ON_PARAMETER, context)
}
}
checkTypeParameters(expression, reporter, context)
}
private fun checkTypeParameters(
expression: FirStatement,
reporter: DiagnosticReporter,
context: CheckerContext
) {
expression.source?.let { source ->
source.treeStructure.typeParametersList(source.lighterASTNode)?.let { typeParamsNode ->
reporter.reportOn(
typeParamsNode.toFirLightSourceElement(source.treeStructure),
FirErrors.TYPE_PARAMETERS_NOT_ALLOWED,
context
)
}
}
}
}
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ASSIGNED_VALUE_IS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ASSIGN_OPERATOR_AMBIGUITY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.BACKING_FIELD_IN_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.BOUNDS_NOT_ALLOWED_IF_BOUNDED_BY_TYPE_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.BOUND_ON_TYPE_ALIAS_PARAMETER_NOT_ALLOWED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.BREAK_OR_CONTINUE_OUTSIDE_A_LOOP
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CALLABLE_REFERENCE_LHS_NOT_A_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR
@@ -196,6 +197,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_SETTER_
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_SINGLE_EXPRESSION_STRING_TEMPLATE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_VISIBILITY_MODIFIER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REIFIED_TYPE_IN_CATCH_CLAUSE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REIFIED_TYPE_PARAMETER_NO_INLINE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REPEATED_BOUND
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REPEATED_MODIFIER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.RESERVED_MEMBER_INSIDE_INLINE_CLASS
@@ -223,6 +225,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_CANT_BE_USED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_MISMATCH
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETERS_IN_ENUM
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETERS_IN_OBJECT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETERS_NOT_ALLOWED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_AS_REIFIED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_IN_CATCH_CLAUSE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_IS_NOT_AN_EXPRESSION
@@ -495,6 +498,12 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
NAME
)
map.put(BOUND_ON_TYPE_ALIAS_PARAMETER_NOT_ALLOWED, "Bounds are not allowed on type alias parameters")
map.put(REIFIED_TYPE_PARAMETER_NO_INLINE, "Only type parameters of inline functions can be reified")
map.put(TYPE_PARAMETERS_NOT_ALLOWED, "Type parameters are not allowed here")
map.put(RETURN_TYPE_MISMATCH, "Return type mismatch: expected {0}, actual {1}", RENDER_TYPE, RENDER_TYPE)
// Reflection
@@ -630,6 +630,9 @@ internal fun FlyweightCapableTreeStructure<LighterASTNode>.modalityModifier(decl
internal fun FlyweightCapableTreeStructure<LighterASTNode>.overrideModifier(declaration: LighterASTNode): LighterASTNode? =
modifierList(declaration)?.let { findChildByType(it, KtTokens.OVERRIDE_KEYWORD) }
internal fun FlyweightCapableTreeStructure<LighterASTNode>.typeParametersList(declaration: LighterASTNode): LighterASTNode? =
findChildByType(declaration, KtNodeTypes.TYPE_PARAMETER_LIST)
private fun FlyweightCapableTreeStructure<LighterASTNode>.supertypesList(node: LighterASTNode): LighterASTNode? =
findChildByType(node, KtNodeTypes.SUPER_TYPE_LIST)
@@ -4,16 +4,16 @@
interface A
fun devNull(a: Any?){}
val generic_fun = fun<T>(t: <!UNRESOLVED_REFERENCE!>T<!>): T = null!!
val extension_generic_fun = fun<T><!UNRESOLVED_REFERENCE!>T<!>.(t: <!UNRESOLVED_REFERENCE!>T<!>): T = null!!
val generic_fun = fun<!TYPE_PARAMETERS_NOT_ALLOWED!><T><!>(t: <!UNRESOLVED_REFERENCE!>T<!>): T = null!!
val extension_generic_fun = fun<!TYPE_PARAMETERS_NOT_ALLOWED!><T><!><!UNRESOLVED_REFERENCE!>T<!>.(t: <!UNRESOLVED_REFERENCE!>T<!>): T = null!!
fun fun_with_where() = fun <T> <!UNRESOLVED_REFERENCE!>T<!>.(t: <!UNRESOLVED_REFERENCE!>T<!>): T where T: A = null!!
fun fun_with_where() = fun <!TYPE_PARAMETERS_NOT_ALLOWED!><T><!> <!UNRESOLVED_REFERENCE!>T<!>.(t: <!UNRESOLVED_REFERENCE!>T<!>): T where T: A = null!!
fun outer() {
devNull(fun <T>() {})
devNull(fun <T> T.() {})
devNull(fun <T> (): T = null!!)
devNull(fun <T> (t: T) {})
devNull(fun <T> () where T:A {})
devNull(fun <!TYPE_PARAMETERS_NOT_ALLOWED!><T><!>() {})
devNull(fun <!TYPE_PARAMETERS_NOT_ALLOWED!><T><!> T.() {})
devNull(fun <!TYPE_PARAMETERS_NOT_ALLOWED!><T><!> (): T = null!!)
devNull(fun <!TYPE_PARAMETERS_NOT_ALLOWED!><T><!> (t: T) {})
devNull(fun <!TYPE_PARAMETERS_NOT_ALLOWED!><T><!> () where T:A {})
}
@@ -998,6 +998,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.TYPE_PARAMETERS_NOT_ALLOWED) { firDiagnostic ->
TypeParametersNotAllowedImpl(
firDiagnostic as FirPsiDiagnostic<*>,
token,
)
}
add(FirErrors.RETURN_TYPE_MISMATCH) { firDiagnostic ->
ReturnTypeMismatchImpl(
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
@@ -709,6 +709,10 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
override val diagnosticClass get() = ReifiedTypeParameterNoInline::class
}
abstract class TypeParametersNotAllowed : KtFirDiagnostic<KtDeclaration>() {
override val diagnosticClass get() = TypeParametersNotAllowed::class
}
abstract class ReturnTypeMismatch : KtFirDiagnostic<KtExpression>() {
override val diagnosticClass get() = ReturnTypeMismatch::class
abstract val expected: KtType
@@ -1145,6 +1145,13 @@ internal class ReifiedTypeParameterNoInlineImpl(
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class TypeParametersNotAllowedImpl(
firDiagnostic: FirPsiDiagnostic<*>,
override val token: ValidityToken,
) : KtFirDiagnostic.TypeParametersNotAllowed(), KtAbstractFirDiagnostic<KtDeclaration> {
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class ReturnTypeMismatchImpl(
override val expected: KtType,
override val actual: KtType,