From e06cb1ec390f1cafdf202e6d9361ce09c842e678 Mon Sep 17 00:00:00 2001 From: Vyacheslav Gerasimov Date: Mon, 21 Aug 2017 21:26:26 +0300 Subject: [PATCH] Android Lint: Use Uast to check for SuppressLint annotation #KT-14800 Fixed Target versions 1.1.5 --- idea/testData/android/lint/javaPerformance.kt | 2 +- idea/testData/android/lint/toast.kt | 2 +- .../tools/klint/client/api/LintDriver.java | 41 ++++++++++++++++--- 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/idea/testData/android/lint/javaPerformance.kt b/idea/testData/android/lint/javaPerformance.kt index 02491db0106..b3cddced1f8 100644 --- a/idea/testData/android/lint/javaPerformance.kt +++ b/idea/testData/android/lint/javaPerformance.kt @@ -73,7 +73,7 @@ class JavaPerformanceTest(context: Context, attrs: AttributeSet, defStyle: Int) // This one should not be reported: @SuppressLint("UseSparseArrays") - val myOtherMap = HashMap() + val myOtherMap = HashMap() } protected fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int, diff --git a/idea/testData/android/lint/toast.kt b/idea/testData/android/lint/toast.kt index 9cb25102a04..a7f485638fa 100644 --- a/idea/testData/android/lint/toast.kt +++ b/idea/testData/android/lint/toast.kt @@ -61,7 +61,7 @@ class ToastTest(context: Context) : Activity() { private fun checkSuppress2(context: Context) { @android.annotation.SuppressLint("ShowToast") - val toast = Toast.makeText(this, "MyToast", Toast.LENGTH_LONG) + val toast = Toast.makeText(this, "MyToast", Toast.LENGTH_LONG) } class R { diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintDriver.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintDriver.java index a357003a0a5..2cc5b23172b 100644 --- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintDriver.java +++ b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintDriver.java @@ -81,7 +81,7 @@ import com.intellij.psi.PsiModifierList; import com.intellij.psi.PsiModifierListOwner; import com.intellij.psi.PsiNameValuePair; -import org.jetbrains.uast.UElement; +import org.jetbrains.uast.*; import org.jetbrains.org.objectweb.asm.ClassReader; import org.jetbrains.org.objectweb.asm.Opcodes; import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode; @@ -2609,9 +2609,8 @@ public class LintDriver { boolean checkComments = mClient.checkForSuppressComments() && context != null && context.containsCommentSuppress(); while (scope != null) { - if (scope instanceof PsiModifierListOwner) { - PsiModifierListOwner owner = (PsiModifierListOwner) scope; - if (isSuppressed(issue, owner.getModifierList())) { + if (scope instanceof UAnnotated) { + if (isSuppressed(issue, (UAnnotated) scope)) { return true; } } @@ -2621,7 +2620,7 @@ public class LintDriver { } scope = scope.getUastParent(); - if (scope instanceof PsiFile) { + if (scope instanceof UFile) { return false; } } @@ -2822,6 +2821,38 @@ public class LintDriver { return false; } + /** + * Returns true if the given AST modifier has a suppress annotation for the + * given issue (which can be null to check for the "all" annotation) + * + * @param issue the issue to be checked + * @param element the element to check + * @return true if the issue or all issues should be suppressed for this + * element + */ + public static boolean isSuppressed(@NonNull Issue issue, + @Nullable UAnnotated element) { + if (element == null) { + return false; + } + + for (UAnnotation annotation : element.getAnnotations()) { + String fqcn = annotation.getQualifiedName(); + if (fqcn != null && (fqcn.equals(FQCN_SUPPRESS_LINT) + || fqcn.equals(SUPPRESS_WARNINGS_FQCN) + || fqcn.equals(SUPPRESS_LINT))) { // when missing imports + for (UNamedExpression attribute : annotation.getAttributeValues()) { + Object value = attribute.getExpression().evaluate(); + if (value instanceof String && isSuppressed(issue, (String) value)) { + return true; + } + } + } + } + + return false; + } + private File mCachedFolder = null; private int mCachedFolderVersion = -1; /** Pattern for version qualifiers */