[FIR] Add NOT_A_CLASS diagnostics
This commit is contained in:
committed by
TeamCityServer
parent
aff885bcd1
commit
4caf3c5e83
+6
@@ -914,6 +914,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirErrors.NOT_A_CLASS) { firDiagnostic ->
|
||||||
|
NotAClassImpl(
|
||||||
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirErrors.OPT_IN_USAGE) { firDiagnostic ->
|
add(FirErrors.OPT_IN_USAGE) { firDiagnostic ->
|
||||||
OptInUsageImpl(
|
OptInUsageImpl(
|
||||||
firDiagnostic.a,
|
firDiagnostic.a,
|
||||||
|
|||||||
+4
@@ -659,6 +659,10 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
override val diagnosticClass get() = RepeatedAnnotationWarning::class
|
override val diagnosticClass get() = RepeatedAnnotationWarning::class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class NotAClass : KtFirDiagnostic<PsiElement>() {
|
||||||
|
override val diagnosticClass get() = NotAClass::class
|
||||||
|
}
|
||||||
|
|
||||||
abstract class OptInUsage : KtFirDiagnostic<PsiElement>() {
|
abstract class OptInUsage : KtFirDiagnostic<PsiElement>() {
|
||||||
override val diagnosticClass get() = OptInUsage::class
|
override val diagnosticClass get() = OptInUsage::class
|
||||||
abstract val optInMarkerFqName: FqName
|
abstract val optInMarkerFqName: FqName
|
||||||
|
|||||||
+5
@@ -790,6 +790,11 @@ internal class RepeatedAnnotationWarningImpl(
|
|||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
) : KtFirDiagnostic.RepeatedAnnotationWarning(), KtAbstractFirDiagnostic<KtAnnotationEntry>
|
) : KtFirDiagnostic.RepeatedAnnotationWarning(), KtAbstractFirDiagnostic<KtAnnotationEntry>
|
||||||
|
|
||||||
|
internal class NotAClassImpl(
|
||||||
|
override val firDiagnostic: KtPsiDiagnostic,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.NotAClass(), KtAbstractFirDiagnostic<PsiElement>
|
||||||
|
|
||||||
internal class OptInUsageImpl(
|
internal class OptInUsageImpl(
|
||||||
override val optInMarkerFqName: FqName,
|
override val optInMarkerFqName: FqName,
|
||||||
override val message: String,
|
override val message: String,
|
||||||
|
|||||||
+1
@@ -281,6 +281,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
val INAPPLICABLE_FILE_TARGET by error<KtAnnotationEntry>(PositioningStrategy.ANNOTATION_USE_SITE)
|
val INAPPLICABLE_FILE_TARGET by error<KtAnnotationEntry>(PositioningStrategy.ANNOTATION_USE_SITE)
|
||||||
val REPEATED_ANNOTATION by error<KtAnnotationEntry>()
|
val REPEATED_ANNOTATION by error<KtAnnotationEntry>()
|
||||||
val REPEATED_ANNOTATION_WARNING by warning<KtAnnotationEntry>()
|
val REPEATED_ANNOTATION_WARNING by warning<KtAnnotationEntry>()
|
||||||
|
val NOT_A_CLASS by error<PsiElement>()
|
||||||
}
|
}
|
||||||
|
|
||||||
val OPT_IN by object : DiagnosticGroup("OptIn") {
|
val OPT_IN by object : DiagnosticGroup("OptIn") {
|
||||||
|
|||||||
@@ -247,6 +247,7 @@ object FirErrors {
|
|||||||
val INAPPLICABLE_FILE_TARGET by error0<KtAnnotationEntry>(SourceElementPositioningStrategies.ANNOTATION_USE_SITE)
|
val INAPPLICABLE_FILE_TARGET by error0<KtAnnotationEntry>(SourceElementPositioningStrategies.ANNOTATION_USE_SITE)
|
||||||
val REPEATED_ANNOTATION by error0<KtAnnotationEntry>()
|
val REPEATED_ANNOTATION by error0<KtAnnotationEntry>()
|
||||||
val REPEATED_ANNOTATION_WARNING by warning0<KtAnnotationEntry>()
|
val REPEATED_ANNOTATION_WARNING by warning0<KtAnnotationEntry>()
|
||||||
|
val NOT_A_CLASS by error0<PsiElement>()
|
||||||
|
|
||||||
// OptIn
|
// OptIn
|
||||||
val OPT_IN_USAGE by warning2<PsiElement, FqName, String>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
val OPT_IN_USAGE by warning2<PsiElement, FqName, String>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.syntax.FirUnderscoredTypeArgum
|
|||||||
object CommonExpressionCheckers : ExpressionCheckers() {
|
object CommonExpressionCheckers : ExpressionCheckers() {
|
||||||
override val annotationCallCheckers: Set<FirAnnotationCallChecker>
|
override val annotationCallCheckers: Set<FirAnnotationCallChecker>
|
||||||
get() = setOf(
|
get() = setOf(
|
||||||
FirAnnotationArgumentChecker,
|
FirAnnotationExpressionChecker,
|
||||||
FirOptInAnnotationCallChecker,
|
FirOptInAnnotationCallChecker,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+37
-11
@@ -7,23 +7,27 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.KtSourceElement
|
import org.jetbrains.kotlin.KtSourceElement
|
||||||
import org.jetbrains.kotlin.config.ApiVersion
|
import org.jetbrains.kotlin.config.ApiVersion
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
|
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory0
|
||||||
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.ConstantArgumentKind
|
import org.jetbrains.kotlin.fir.analysis.checkers.ConstantArgumentKind
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.checkConstantArguments
|
import org.jetbrains.kotlin.fir.analysis.checkers.checkConstantArguments
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory0
|
|
||||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.findArgumentByName
|
import org.jetbrains.kotlin.fir.declarations.findArgumentByName
|
||||||
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.resolve.fqName
|
import org.jetbrains.kotlin.fir.resolve.fqName
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||||
|
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
|
||||||
|
import org.jetbrains.kotlin.fir.types.coneType
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.RequireKotlinConstants
|
import org.jetbrains.kotlin.resolve.RequireKotlinConstants
|
||||||
|
|
||||||
object FirAnnotationArgumentChecker : FirAnnotationCallChecker() {
|
object FirAnnotationExpressionChecker : FirAnnotationCallChecker() {
|
||||||
private val versionArgumentName = Name.identifier("version")
|
private val versionArgumentName = Name.identifier("version")
|
||||||
private val deprecatedSinceKotlinFqName = FqName("kotlin.DeprecatedSinceKotlin")
|
private val deprecatedSinceKotlinFqName = FqName("kotlin.DeprecatedSinceKotlin")
|
||||||
private val sinceKotlinFqName = FqName("kotlin.SinceKotlin")
|
private val sinceKotlinFqName = FqName("kotlin.SinceKotlin")
|
||||||
@@ -44,13 +48,8 @@ object FirAnnotationArgumentChecker : FirAnnotationCallChecker() {
|
|||||||
|
|
||||||
checkAnnotationsWithVersion(fqName, expression, context, reporter)
|
checkAnnotationsWithVersion(fqName, expression, context, reporter)
|
||||||
checkDeprecatedSinceKotlin(expression.source, fqName, argumentMapping, context, reporter)
|
checkDeprecatedSinceKotlin(expression.source, fqName, argumentMapping, context, reporter)
|
||||||
|
checkAnnotationUsedAsAnnotationArgument(expression, context, reporter)
|
||||||
val args = expression.argumentList.arguments
|
checkNotAClass(expression, context, reporter)
|
||||||
for (arg in args) {
|
|
||||||
for (ann in arg.unwrapArgument().annotations) {
|
|
||||||
reporter.reportOn(ann.source, FirErrors.ANNOTATION_USED_AS_ANNOTATION_ARGUMENT, context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkAnnotationArgumentWithSubElements(
|
private fun checkAnnotationArgumentWithSubElements(
|
||||||
@@ -194,4 +193,31 @@ object FirAnnotationArgumentChecker : FirAnnotationCallChecker() {
|
|||||||
reporter.reportOn(source, FirErrors.DEPRECATED_SINCE_KOTLIN_WITH_UNORDERED_VERSIONS, context)
|
reporter.reportOn(source, FirErrors.DEPRECATED_SINCE_KOTLIN_WITH_UNORDERED_VERSIONS, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun checkAnnotationUsedAsAnnotationArgument(
|
||||||
|
expression: FirAnnotationCall,
|
||||||
|
context: CheckerContext,
|
||||||
|
reporter: DiagnosticReporter
|
||||||
|
) {
|
||||||
|
val args = expression.argumentList.arguments
|
||||||
|
for (arg in args) {
|
||||||
|
for (ann in arg.unwrapArgument().annotations) {
|
||||||
|
reporter.reportOn(ann.source, FirErrors.ANNOTATION_USED_AS_ANNOTATION_ARGUMENT, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkNotAClass(
|
||||||
|
expression: FirAnnotationCall,
|
||||||
|
context: CheckerContext,
|
||||||
|
reporter: DiagnosticReporter
|
||||||
|
) {
|
||||||
|
val annotationTypeRef = expression.annotationTypeRef
|
||||||
|
if (expression.calleeReference is FirErrorNamedReference &&
|
||||||
|
annotationTypeRef !is FirErrorTypeRef &&
|
||||||
|
annotationTypeRef.coneType !is ConeClassLikeType
|
||||||
|
) {
|
||||||
|
reporter.reportOn(annotationTypeRef.source, FirErrors.NOT_A_CLASS, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+2
@@ -306,6 +306,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_VARARG_SPREAD
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOTHING_TO_INLINE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOTHING_TO_INLINE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOTHING_TO_OVERRIDE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOTHING_TO_OVERRIDE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_AN_ANNOTATION_CLASS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_AN_ANNOTATION_CLASS
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_A_CLASS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_A_FUNCTION_LABEL
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_A_FUNCTION_LABEL
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_A_LOOP_LABEL
|
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.NOT_A_SUPERTYPE
|
||||||
@@ -779,6 +780,7 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
|||||||
OPT_IN_MARKER_ON_OVERRIDE_WARNING,
|
OPT_IN_MARKER_ON_OVERRIDE_WARNING,
|
||||||
"Opt-in requirement marker annotation on override makes no sense without the same marker on base declaration"
|
"Opt-in requirement marker annotation on override makes no sense without the same marker on base declaration"
|
||||||
)
|
)
|
||||||
|
map.put(NOT_A_CLASS, "Not a class")
|
||||||
|
|
||||||
// Exposed visibility group // #
|
// Exposed visibility group // #
|
||||||
map.put(
|
map.put(
|
||||||
|
|||||||
-9
@@ -1,9 +0,0 @@
|
|||||||
class Foo<T> {
|
|
||||||
@T
|
|
||||||
fun foo() = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
class Bar<T : Annotation> {
|
|
||||||
@T
|
|
||||||
fun foo() = 0
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
class Foo<T> {
|
class Foo<T> {
|
||||||
@<!NOT_A_CLASS!>T<!>
|
@<!NOT_A_CLASS!>T<!>
|
||||||
fun foo() = 0
|
fun foo() = 0
|
||||||
|
|||||||
Reference in New Issue
Block a user