Annotation inspections (UnstableApiUsage, MustAlreadyBeRemovedApi, etc): don't run if annotation can't be referenced from file.

GitOrigin-RevId: a040f6cc7dba6c7315684a13b37a3d3db64b70f7
This commit is contained in:
Sergey Patrikeev
2020-04-24 09:55:48 +00:00
committed by intellij-monorepo-bot
parent a431d5458e
commit b708dbb210
7 changed files with 30 additions and 11 deletions
@@ -57,6 +57,13 @@ data class AnnotatedContainingDeclaration(
@ApiStatus.Internal
internal object AnnotatedApiUsageUtil {
/**
* Returns `true` iff the annotation with qualified name [annotationFqn] can be referenced from file [psiFile].
* It may be used to check whether it is necessary to run for the given file an inspection that checks usages of some annotations.
*/
fun canAnnotationBeUsedInFile(annotationFqn: String, psiFile: PsiFile): Boolean =
JavaPsiFacade.getInstance(psiFile.project).findClass(annotationFqn, psiFile.resolveScope) != null
/**
* Searches for an annotation on a [target] or its enclosing declaration (containing class or package).
*
@@ -24,8 +24,12 @@ class MissingDeprecatedAnnotationOnScheduledForRemovalApiInspection : LocalInspe
override fun runForWholeFile() = true
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor =
UastVisitorAdapter(MissingDeprecatedAnnotationOnSFRVisitor(holder), true)
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
if (!AnnotatedApiUsageUtil.canAnnotationBeUsedInFile(SCHEDULED_FOR_REMOVAL_ANNOTATION_NAME, holder.file)) {
return PsiElementVisitor.EMPTY_VISITOR
}
return UastVisitorAdapter(MissingDeprecatedAnnotationOnSFRVisitor(holder), true)
}
private class MissingDeprecatedAnnotationOnSFRVisitor(private val problemsHolder: ProblemsHolder) : AbstractUastNonRecursiveVisitor() {
override fun visitClass(node: UClass): Boolean {
@@ -31,7 +31,9 @@ class MustAlreadyBeRemovedApiInspection : LocalInspectionTool() {
var currentVersion: String = ""
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
if (currentVersion.isEmpty()) return PsiElementVisitor.EMPTY_VISITOR
if (currentVersion.isEmpty() || !AnnotatedApiUsageUtil.canAnnotationBeUsedInFile(SCHEDULED_FOR_REMOVAL_ANNOTATION_NAME, holder.file)) {
return PsiElementVisitor.EMPTY_VISITOR
}
return UastVisitorAdapter(MustAlreadyBeRemovedApiVisitor(holder, currentVersion), true)
}
@@ -23,7 +23,7 @@ class NonExtendableApiUsageInspection : LocalInspectionTool() {
}
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor =
if (JavaPsiFacade.getInstance(holder.project).findClass(ANNOTATION_NAME, holder.file.resolveScope) != null) {
if (AnnotatedApiUsageUtil.canAnnotationBeUsedInFile(ANNOTATION_NAME, holder.file)) {
ApiUsageUastVisitor.createPsiElementVisitor(NonExtendableApiUsageProcessor(holder))
} else {
PsiElementVisitor.EMPTY_VISITOR
@@ -6,7 +6,10 @@ import com.intellij.codeInsight.daemon.impl.analysis.HighlightMessageUtil
import com.intellij.codeInspection.apiUsage.ApiUsageProcessor
import com.intellij.codeInspection.apiUsage.ApiUsageUastVisitor
import com.intellij.openapi.roots.ProjectFileIndex
import com.intellij.psi.*
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiModifierListOwner
import com.intellij.psi.util.PsiUtilCore
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.uast.UElement
@@ -23,7 +26,7 @@ class OverrideOnlyInspection : LocalInspectionTool() {
}
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor =
if (JavaPsiFacade.getInstance(holder.project).findClass(ANNOTATION_NAME, holder.file.resolveScope) != null) {
if (AnnotatedApiUsageUtil.canAnnotationBeUsedInFile(ANNOTATION_NAME, holder.file)) {
ApiUsageUastVisitor.createPsiElementVisitor(OverrideOnlyProcessor(holder))
} else {
PsiElementVisitor.EMPTY_VISITOR
@@ -53,9 +53,7 @@ class UnstableApiUsageInspection : LocalInspectionTool() {
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
val annotations = unstableApiAnnotations.toList()
val psiFacade = JavaPsiFacade.getInstance(holder.project)
val resolveScope = holder.file.resolveScope
return if (annotations.any { psiFacade.findClass(it, resolveScope) != null }) {
return if (annotations.any { AnnotatedApiUsageUtil.canAnnotationBeUsedInFile(it, holder.file) }) {
ApiUsageUastVisitor.createPsiElementVisitor(
UnstableApiUsageProcessor(
holder,
@@ -7,6 +7,7 @@ import com.intellij.codeInspection.UnstableApiUsageInspection.Companion.DEFAULT_
import com.intellij.codeInspection.util.SpecialAnnotationsUtil
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.PsiField
import com.intellij.psi.util.PropertyUtil
import com.intellij.uast.UastVisitorAdapter
@@ -29,8 +30,12 @@ class UnstableTypeUsedInSignatureInspection : LocalInspectionTool() {
@JvmField
val unstableApiAnnotations: MutableList<String> = ExternalizableStringSet(*DEFAULT_UNSTABLE_API_ANNOTATIONS.toTypedArray())
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean) =
UastVisitorAdapter(UnstableTypeUsedInSignatureVisitor(holder, unstableApiAnnotations.toList()), true)
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
if (unstableApiAnnotations.none { AnnotatedApiUsageUtil.canAnnotationBeUsedInFile(it, holder.file) }) {
return PsiElementVisitor.EMPTY_VISITOR
}
return UastVisitorAdapter(UnstableTypeUsedInSignatureVisitor(holder, unstableApiAnnotations.toList()), true)
}
override fun createOptionsPanel(): JPanel {
val annotationsListControl = SpecialAnnotationsUtil.createSpecialAnnotationsListControl(