FIR: report WRONG_ANNOTATION_TARGET on types
This commit is contained in:
Vendored
+1
-1
@@ -5,7 +5,7 @@ interface I {
|
||||
}
|
||||
|
||||
class A {
|
||||
fun too(): @<!NOT_AN_ANNOTATION_CLASS!>Annotation<!> Unit {}
|
||||
fun too(): <!WRONG_ANNOTATION_TARGET!>@<!NOT_AN_ANNOTATION_CLASS!>Annotation<!><!> Unit {}
|
||||
|
||||
fun foo(): <!REDUNDANT_RETURN_UNIT_TYPE!>Unit<!>
|
||||
{
|
||||
|
||||
@@ -30,7 +30,7 @@ abstract class First {
|
||||
}
|
||||
|
||||
@WithString("xyz")
|
||||
class Second(val y: Char) : @WithInt(0) First() {
|
||||
class Second(val y: Char) : <!WRONG_ANNOTATION_TARGET!>@WithInt(0)<!> First() {
|
||||
override fun foo(arg: Double) {
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.declarations.FirAnnotatedDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
|
||||
@@ -40,12 +41,14 @@ private val defaultAnnotationTargets = KotlinTarget.DEFAULT_TARGET_SET
|
||||
|
||||
fun FirAnnotationCall.getAllowedAnnotationTargets(session: FirSession): Set<KotlinTarget> {
|
||||
if (annotationTypeRef is FirErrorTypeRef) return KotlinTarget.values().toSet()
|
||||
val annotationClass = (this.annotationTypeRef.coneType as? ConeClassLikeType)?.lookupTag?.toSymbol(session)?.fir as? FirRegularClass
|
||||
val annotationClass = (this.annotationTypeRef.coneType as? ConeClassLikeType)
|
||||
?.fullyExpandedType(session)?.lookupTag?.toSymbol(session)?.fir as? FirRegularClass
|
||||
return annotationClass?.getAllowedAnnotationTargets() ?: defaultAnnotationTargets
|
||||
}
|
||||
|
||||
fun FirRegularClass.getAllowedAnnotationTargets(): Set<KotlinTarget> {
|
||||
val targetAnnotation = getTargetAnnotation() ?: return defaultAnnotationTargets
|
||||
if (targetAnnotation.argumentList.arguments.isEmpty()) return emptySet()
|
||||
val arguments = when (val targetArgument = targetAnnotation.findSingleArgumentByName(TARGET_PARAMETER_NAME)) {
|
||||
is FirVarargArgumentsExpression -> targetArgument.arguments
|
||||
is FirArrayOfCall -> targetArgument.arguments
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.type
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.getAllowedAnnotationTargets
|
||||
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.withSuppressedDiagnostics
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
|
||||
object FirTypeAnnotationChecker : FirTypeRefChecker() {
|
||||
override fun check(typeRef: FirTypeRef, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
for (annotation in typeRef.annotations) {
|
||||
withSuppressedDiagnostics(annotation, context) {
|
||||
val annotationTargets = annotation.getAllowedAnnotationTargets(context.session)
|
||||
if (KotlinTarget.TYPE !in annotationTargets) {
|
||||
val useSiteTarget = annotation.useSiteTarget
|
||||
if (useSiteTarget == null || KotlinTarget.USE_SITE_MAPPING[useSiteTarget] !in annotationTargets) {
|
||||
reporter.reportOn(annotation.source, FirErrors.WRONG_ANNOTATION_TARGET, "type usage", context)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -171,6 +171,7 @@ abstract class AbstractDiagnosticCollectorVisitor(
|
||||
if (resolvedTypeRef.type is ConeClassErrorType) {
|
||||
super.visitResolvedTypeRef(resolvedTypeRef, data)
|
||||
}
|
||||
if (resolvedTypeRef.source?.kind is FirFakeSourceElementKind) return
|
||||
resolvedTypeRef.delegatedTypeRef?.accept(this, data)
|
||||
}
|
||||
|
||||
|
||||
@@ -5,18 +5,14 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.checkers
|
||||
|
||||
import org.jetbrains.kotlin.fir.analysis.cfa.AbstractFirPropertyInitializationChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.cfa.FirCallsEffectAnalyzer
|
||||
import org.jetbrains.kotlin.fir.analysis.cfa.FirPropertyInitializationAnalyzer
|
||||
import org.jetbrains.kotlin.fir.analysis.cfa.FirReturnsImpliesAnalyzer
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.cfa.FirControlFlowChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.*
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.type.FirSuspendModifierChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.type.FirTypeAnnotationChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.type.FirTypeRefChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.type.TypeCheckers
|
||||
|
||||
object CommonTypeCheckers : TypeCheckers() {
|
||||
override val typeRefCheckers: Set<FirTypeRefChecker> = setOf(
|
||||
FirSuspendModifierChecker
|
||||
FirTypeAnnotationChecker,
|
||||
FirSuspendModifierChecker,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -323,7 +323,8 @@ private fun FirTypeRef.hideLocalTypeIfNeeded(
|
||||
}
|
||||
val superType = firClass.superTypeRefs.single()
|
||||
if (superType is FirResolvedTypeRef) {
|
||||
return superType
|
||||
val newKind = source?.kind
|
||||
return if (newKind is FirFakeSourceElementKind) superType.copyWithNewSourceKind(newKind) else superType
|
||||
}
|
||||
}
|
||||
return this
|
||||
|
||||
Reference in New Issue
Block a user