FIR: support EXPERIMENTAL_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION...
This commit is contained in:
+12
-6
@@ -9,13 +9,16 @@ import org.jetbrains.kotlin.fir.FirRealSourceElementKind
|
|||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirOptInUsageBaseChecker
|
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirOptInUsageBaseChecker
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPERIMENTAL_CAN_ONLY_BE_USED_AS_ANNOTATION
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPERIMENTAL_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_USE_EXPERIMENTAL
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.getAnnotationByFqName
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||||
import org.jetbrains.kotlin.fir.symbols.ensureResolved
|
import org.jetbrains.kotlin.fir.symbols.ensureResolved
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||||
@@ -24,16 +27,19 @@ import org.jetbrains.kotlin.resolve.checkers.OptInNames
|
|||||||
object FirOptInUsageTypeRefChecker : FirTypeRefChecker() {
|
object FirOptInUsageTypeRefChecker : FirTypeRefChecker() {
|
||||||
@OptIn(SymbolInternals::class)
|
@OptIn(SymbolInternals::class)
|
||||||
override fun check(typeRef: FirTypeRef, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(typeRef: FirTypeRef, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
if (typeRef.source?.kind !is FirRealSourceElementKind) return
|
val source = typeRef.source
|
||||||
|
if (source?.kind !is FirRealSourceElementKind) return
|
||||||
val coneType = typeRef.coneTypeSafe<ConeClassLikeType>() ?: return
|
val coneType = typeRef.coneTypeSafe<ConeClassLikeType>() ?: return
|
||||||
val symbol = coneType.lookupTag.toSymbol(context.session) ?: return
|
val symbol = coneType.lookupTag.toSymbol(context.session) ?: return
|
||||||
symbol.ensureResolved(FirResolvePhase.STATUS)
|
symbol.ensureResolved(FirResolvePhase.STATUS)
|
||||||
val fqName = symbol.classId.asSingleFqName()
|
val fqName = symbol.classId.asSingleFqName()
|
||||||
val lastAnnotationCall = context.qualifiedAccessOrAnnotationCalls.lastOrNull() as? FirAnnotationCall
|
val lastAnnotationCall = context.qualifiedAccessOrAnnotationCalls.lastOrNull() as? FirAnnotationCall
|
||||||
if ((lastAnnotationCall == null || lastAnnotationCall.annotationTypeRef !== typeRef) &&
|
if (lastAnnotationCall == null || lastAnnotationCall.annotationTypeRef !== typeRef) {
|
||||||
(fqName == OptInNames.REQUIRES_OPT_IN_FQ_NAME || fqName == OptInNames.OPT_IN_FQ_NAME)
|
if (fqName == OptInNames.REQUIRES_OPT_IN_FQ_NAME || fqName == OptInNames.OPT_IN_FQ_NAME) {
|
||||||
) {
|
reporter.reportOn(source, EXPERIMENTAL_CAN_ONLY_BE_USED_AS_ANNOTATION, context)
|
||||||
reporter.reportOn(typeRef.source, FirErrors.EXPERIMENTAL_CAN_ONLY_BE_USED_AS_ANNOTATION, context)
|
} else if (symbol is FirRegularClassSymbol && symbol.fir.getAnnotationByFqName(OptInNames.REQUIRES_OPT_IN_FQ_NAME) != null) {
|
||||||
|
reporter.reportOn(source, EXPERIMENTAL_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_USE_EXPERIMENTAL, context)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
with(FirOptInUsageBaseChecker) {
|
with(FirOptInUsageBaseChecker) {
|
||||||
|
|||||||
+4
-4
@@ -54,11 +54,11 @@ annotation class Marker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun f6(m: Marker) {}
|
fun f6(m: <!EXPERIMENTAL_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_USE_EXPERIMENTAL!>Marker<!>) {}
|
||||||
fun f7(): List<Marker>? = null
|
fun f7(): List<<!EXPERIMENTAL_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_USE_EXPERIMENTAL!>Marker<!>>? = null
|
||||||
fun f8(): test.Marker? = null
|
fun f8(): <!EXPERIMENTAL_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_USE_EXPERIMENTAL!>test.Marker?<!> = null
|
||||||
|
|
||||||
typealias Marker0 = Marker
|
typealias Marker0 = <!EXPERIMENTAL_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_USE_EXPERIMENTAL!>Marker<!>
|
||||||
|
|
||||||
fun f9(m: Marker0) {}
|
fun f9(m: Marker0) {}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user