Lint: Fix compilation errors after replacing diagnostics

This commit is contained in:
Yan Zhulanow
2016-10-13 20:18:55 +03:00
committed by Yan Zhulanow
parent 2be9a083ad
commit 565ca0f7a3
15 changed files with 60 additions and 93 deletions
@@ -35,27 +35,18 @@ import com.intellij.psi.PsiParameter;
import com.intellij.psi.PsiParameterList;
import com.intellij.psi.PsiReference;
import com.intellij.psi.PsiType;
import com.intellij.psi.util.InheritanceUtil;
import java.io.File;
@SuppressWarnings("MethodMayBeStatic") // Some of these methods may be overridden by LintClients
public abstract class JavaEvaluator {
public abstract boolean extendsClass(
@Nullable PsiClass cls,
@NonNull String className,
boolean strict);
public abstract boolean implementsInterface(
@NonNull PsiClass cls,
@NonNull String interfaceName,
boolean strict);
public boolean isMemberInSubClassOf(
@NonNull PsiMember method,
@NonNull String className,
boolean strict) {
PsiClass containingClass = method.getContainingClass();
return containingClass != null && extendsClass(containingClass, className, strict);
return containingClass != null && InheritanceUtil.isInheritor(containingClass, strict, className);
}
public static boolean isMemberInClass(
@@ -72,18 +63,6 @@ public abstract class JavaEvaluator {
return method.getParameterList().getParametersCount();
}
/**
* Checks whether the class extends a super class or implements a given interface. Like calling
* both {@link #extendsClass(PsiClass, String, boolean)} and {@link
* #implementsInterface(PsiClass, String, boolean)}.
*/
public boolean inheritsFrom(
@NonNull PsiClass cls,
@NonNull String className,
boolean strict) {
return extendsClass(cls, className, strict) || implementsInterface(cls, className, strict);
}
/**
* Returns true if the given method (which is typically looked up by resolving a method call) is
* either a method in the exact given class, or if {@code allowInherit} is true, a method in a
@@ -545,7 +545,7 @@ public class AnnotationDetector extends Detector implements Detector.UastScanner
PsiAnnotation[] annotations = mContext.getEvaluator().getAllAnnotations(
(PsiModifierListOwner)resolved);
PsiAnnotation annotation = SupportAnnotationDetector.findIntDef(
filterRelevantAnnotations(annotations));
filterRelevantAnnotations(mContext.getEvaluator(), annotations));
if (annotation != null) {
return annotation;
}
@@ -568,7 +568,7 @@ public class AnnotationDetector extends Detector implements Detector.UastScanner
PsiAnnotation[] annotations = mContext.getEvaluator()
.getAllAnnotations(method);
PsiAnnotation annotation = SupportAnnotationDetector.findIntDef(
filterRelevantAnnotations(annotations));
filterRelevantAnnotations(mContext.getEvaluator(), annotations));
if (annotation != null) {
return annotation;
}
@@ -34,6 +34,7 @@ import com.android.tools.klint.detector.api.Severity;
import com.android.tools.klint.detector.api.TextFormat;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.util.InheritanceUtil;
import org.jetbrains.uast.UCallExpression;
import org.jetbrains.uast.UClass;
import org.jetbrains.uast.UMethod;
@@ -124,8 +125,8 @@ public class AppCompatCallDetector extends Detector implements Detector.UastScan
// we don't want to flag these calls if they are in non-appcompat activities
// such as PreferenceActivity (see b.android.com/58512)
UClass cls = UastUtils.getParentOfType(node, UClass.class, true);
return cls != null && evaluator.extendsClass(cls,
"android.support.v7.app.ActionBarActivity", false);
return cls != null && InheritanceUtil.isInheritor(
cls, false, "android.support.v7.app.ActionBarActivity");
}
return false;
}
@@ -61,6 +61,7 @@ import com.google.common.collect.Sets;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiField;
import com.intellij.psi.util.InheritanceUtil;
import org.jetbrains.uast.UCallExpression;
import org.jetbrains.uast.UClass;
import org.jetbrains.uast.UElement;
@@ -234,7 +235,7 @@ public class AppIndexingApiDetector extends Detector implements XmlScanner, Dete
}
// In case linting the base class itself.
if (!context.getEvaluator().extendsClass(declaration, CLASS_ACTIVITY, true)) {
if (!InheritanceUtil.isInheritor(declaration, true, CLASS_ACTIVITY)) {
return;
}
@@ -151,7 +151,7 @@ public class CallSuperDetector extends Detector implements Detector.UastScanner
PsiMethod superMethod = directSuper;
while (superMethod != null) {
PsiAnnotation[] annotations = superMethod.getModifierList().getAnnotations();
annotations = filterRelevantAnnotations(annotations);
annotations = filterRelevantAnnotations(context.getEvaluator(), annotations);
for (PsiAnnotation annotation : annotations) {
String signature = annotation.getQualifiedName();
if (CALL_SUPER_ANNOTATION.equals(signature)) {
@@ -46,6 +46,7 @@ import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiType;
import com.intellij.psi.PsiVariable;
import com.intellij.psi.util.InheritanceUtil;
import org.jetbrains.uast.UBinaryExpression;
import org.jetbrains.uast.UCallExpression;
import org.jetbrains.uast.UDoWhileExpression;
@@ -244,18 +245,18 @@ public class CleanupDetector extends Detector implements Detector.UastScanner {
}
JavaEvaluator evaluator = context.getEvaluator();
if ((OBTAIN.equals(name) || OBTAIN_NO_HISTORY.equals(name)) &&
evaluator.extendsClass(containingClass, MOTION_EVENT_CLS, false)) {
InheritanceUtil.isInheritor(containingClass, false, MOTION_EVENT_CLS)) {
checkRecycled(context, node, MOTION_EVENT_CLS, RECYCLE);
} else if (OBTAIN.equals(name) && evaluator.extendsClass(containingClass, PARCEL_CLS, false)) {
} else if (OBTAIN.equals(name) && InheritanceUtil.isInheritor(containingClass, false, PARCEL_CLS)) {
checkRecycled(context, node, PARCEL_CLS, RECYCLE);
} else if (OBTAIN.equals(name) &&
evaluator.extendsClass(containingClass, VELOCITY_TRACKER_CLS, false)) {
InheritanceUtil.isInheritor(containingClass, false, VELOCITY_TRACKER_CLS)) {
checkRecycled(context, node, VELOCITY_TRACKER_CLS, RECYCLE);
} else if ((OBTAIN_STYLED_ATTRIBUTES.equals(name)
|| OBTAIN_ATTRIBUTES.equals(name)
|| OBTAIN_TYPED_ARRAY.equals(name)) &&
(evaluator.extendsClass(containingClass, CLASS_CONTEXT, false) ||
evaluator.extendsClass(containingClass, SdkConstants.CLASS_RESOURCES, false))) {
(InheritanceUtil.isInheritor(containingClass, false, CLASS_CONTEXT) ||
InheritanceUtil.isInheritor(containingClass, false, SdkConstants.CLASS_RESOURCES))) {
PsiType returnType = method.getReturnType();
if (returnType instanceof PsiClassType) {
PsiClass cls = ((PsiClassType)returnType).resolve();
@@ -263,17 +264,17 @@ public class CleanupDetector extends Detector implements Detector.UastScanner {
checkRecycled(context, node, "android.content.res.TypedArray", RECYCLE);
}
}
} else if (ACQUIRE_CPC.equals(name) && evaluator.extendsClass(containingClass,
CONTENT_RESOLVER_CLS, false)) {
} else if (ACQUIRE_CPC.equals(name) && InheritanceUtil.isInheritor(containingClass,
false, CONTENT_RESOLVER_CLS)) {
checkRecycled(context, node, CONTENT_PROVIDER_CLIENT_CLS, RELEASE);
} else if ((QUERY.equals(name)
|| RAW_QUERY.equals(name)
|| QUERY_WITH_FACTORY.equals(name)
|| RAW_QUERY_WITH_FACTORY.equals(name))
&& (evaluator.extendsClass(containingClass, SQLITE_DATABASE_CLS, false) ||
evaluator.extendsClass(containingClass, CONTENT_RESOLVER_CLS, false) ||
evaluator.extendsClass(containingClass, CLASS_CONTENTPROVIDER, false) ||
evaluator.extendsClass(containingClass, CONTENT_PROVIDER_CLIENT_CLS, false))) {
&& (InheritanceUtil.isInheritor(containingClass, false, SQLITE_DATABASE_CLS) ||
InheritanceUtil.isInheritor(containingClass, false, CONTENT_RESOLVER_CLS) ||
InheritanceUtil.isInheritor(containingClass, false, CLASS_CONTENTPROVIDER) ||
InheritanceUtil.isInheritor(containingClass, false, CONTENT_PROVIDER_CLIENT_CLS))) {
// Other potential cursors-returning methods that should be tracked:
// android.app.DownloadManager#query
// android.content.ContentProviderClient#query
@@ -313,7 +314,7 @@ public class CleanupDetector extends Detector implements Detector.UastScanner {
PsiMethod method = call.resolve();
if (method != null) {
PsiClass containingClass = method.getContainingClass();
if (mContext.getEvaluator().extendsClass(containingClass, recycleType, false)) {
if (InheritanceUtil.isInheritor(containingClass, false, recycleType)) {
// Yes, called the right recycle() method; now make sure
// we're calling it on the right variable
UExpression operand = call.getReceiver();
@@ -478,8 +479,8 @@ public class CleanupDetector extends Detector implements Detector.UastScanner {
if (method != null) {
PsiClass containingClass = method.getContainingClass();
JavaEvaluator evaluator = context.getEvaluator();
return evaluator.extendsClass(containingClass, fragmentClass, false) ||
evaluator.extendsClass(containingClass, v4FragmentClass, false);
return InheritanceUtil.isInheritor(containingClass, false, fragmentClass) ||
InheritanceUtil.isInheritor(containingClass, false, v4FragmentClass);
} else {
// If we *can't* resolve the method call, caller can decide
// whether to consider the method called or not
@@ -561,8 +562,8 @@ public class CleanupDetector extends Detector implements Detector.UastScanner {
if (EDIT.equals(methodName)) {
PsiClass containingClass = method.getContainingClass();
JavaEvaluator evaluator = context.getEvaluator();
return evaluator.extendsClass(containingClass, ANDROID_CONTENT_SHARED_PREFERENCES,
false);
return InheritanceUtil.isInheritor(
containingClass, false, ANDROID_CONTENT_SHARED_PREFERENCES);
}
return false;
@@ -593,8 +594,8 @@ public class CleanupDetector extends Detector implements Detector.UastScanner {
if (method != null) {
PsiClass containingClass = method.getContainingClass();
JavaEvaluator evaluator = context.getEvaluator();
if (evaluator.extendsClass(containingClass,
ANDROID_CONTENT_SHARED_PREFERENCES_EDITOR, false)) {
if (InheritanceUtil.isInheritor(containingClass, false,
ANDROID_CONTENT_SHARED_PREFERENCES_EDITOR)) {
suggestApplyIfApplicable(context, call);
return true;
}
@@ -612,8 +613,8 @@ public class CleanupDetector extends Detector implements Detector.UastScanner {
if (method != null) {
PsiClass containingClass = method.getContainingClass();
JavaEvaluator evaluator = context.getEvaluator();
return evaluator.extendsClass(containingClass,
ANDROID_CONTENT_SHARED_PREFERENCES_EDITOR, false);
return InheritanceUtil.isInheritor(containingClass, false,
ANDROID_CONTENT_SHARED_PREFERENCES_EDITOR);
}
}
@@ -717,8 +718,8 @@ public class CleanupDetector extends Detector implements Detector.UastScanner {
if (BEGIN_TRANSACTION.equals(methodName)) {
PsiClass containingClass = method.getContainingClass();
JavaEvaluator evaluator = context.getEvaluator();
if (evaluator.extendsClass(containingClass, FRAGMENT_MANAGER_CLS, false)
|| evaluator.extendsClass(containingClass, FRAGMENT_MANAGER_V4_CLS, false)) {
if (InheritanceUtil.isInheritor(containingClass, false, FRAGMENT_MANAGER_CLS)
|| InheritanceUtil.isInheritor(containingClass, false, FRAGMENT_MANAGER_V4_CLS)) {
return true;
}
}
@@ -184,7 +184,7 @@ public class CommentDetector extends Detector implements Detector.UastScanner {
// TODO: Only flag this issue in release mode??
Location location;
if (node != null) {
location = context.getLocation(node);
location = context.getUastLocation(node);
} else {
location = Location.create(context.file, source,
offset + i - 1, offset + i - 1 + STOPSHIP_COMMENT.length());
@@ -33,6 +33,7 @@ import com.android.tools.klint.detector.api.JavaContext;
import com.android.tools.klint.detector.api.Scope;
import com.android.tools.klint.detector.api.Severity;
import com.intellij.psi.PsiClass;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.uast.UCallExpression;
@@ -122,7 +123,7 @@ public class CustomViewDetector extends Detector implements Detector.UastScanner
}
String className = cls.getName();
if (context.getEvaluator().extendsClass(cls, CLASS_VIEW, false)) {
if (InheritanceUtil.isInheritor(cls, false, CLASS_VIEW)) {
if (!styleableName.equals(className)) {
String message = String.format(
"By convention, the custom view (`%1$s`) and the declare-styleable (`%2$s`) "
@@ -131,8 +132,8 @@ public class CustomViewDetector extends Detector implements Detector.UastScanner
className, styleableName);
context.report(ISSUE, node, context.getUastLocation(expression), message);
}
} else if (context.getEvaluator().extendsClass(cls,
CLASS_VIEWGROUP + DOT_LAYOUT_PARAMS, false)) {
} else if (InheritanceUtil.isInheritor(cls, false,
CLASS_VIEWGROUP + DOT_LAYOUT_PARAMS)) {
PsiClass outer = PsiTreeUtil.getParentOfType(cls, PsiClass.class, true);
if (outer == null) {
return;
@@ -22,13 +22,11 @@ import static com.android.SdkConstants.CLASS_VIEW;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.tools.klint.client.api.JavaEvaluator;
import com.android.tools.klint.detector.api.Category;
import com.android.tools.klint.detector.api.Detector;
import com.android.tools.klint.detector.api.Implementation;
import com.android.tools.klint.detector.api.Issue;
import com.android.tools.klint.detector.api.JavaContext;
import com.android.tools.klint.detector.api.Location;
import com.android.tools.klint.detector.api.Scope;
import com.android.tools.klint.detector.api.Severity;
import com.intellij.psi.PsiClass;
@@ -39,6 +37,7 @@ import com.intellij.psi.PsiModifier;
import com.intellij.psi.PsiModifierList;
import com.intellij.psi.PsiType;
import com.intellij.psi.util.InheritanceUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.uast.UClass;
import org.jetbrains.uast.UElement;
@@ -125,7 +124,7 @@ public class LeakDetector extends Detector implements Detector.UastScanner {
return;
}
if (fqn.startsWith("android.")) {
if (isLeakCandidate(cls, mContext.getEvaluator())) {
if (isLeakCandidate(cls)) {
String message = "Do not place Android context classes in static fields; "
+ "this is a memory leak (and also breaks Instant Run)";
report(field, message);
@@ -155,7 +154,7 @@ public class LeakDetector extends Detector implements Detector.UastScanner {
continue;
}
if (fqn.startsWith("android.")) {
if (isLeakCandidate(innerCls, mContext.getEvaluator())) {
if (isLeakCandidate(innerCls)) {
String message =
"Do not place Android context classes in static fields "
+ "(static reference to `"
@@ -176,11 +175,9 @@ public class LeakDetector extends Detector implements Detector.UastScanner {
}
}
private static boolean isLeakCandidate(
@NonNull PsiClass cls,
@NonNull JavaEvaluator evaluator) {
return evaluator.extendsClass(cls, CLASS_CONTEXT, false)
|| evaluator.extendsClass(cls, CLASS_VIEW, false)
|| evaluator.extendsClass(cls, CLASS_FRAGMENT, false);
private static boolean isLeakCandidate(@NonNull PsiClass cls) {
return InheritanceUtil.isInheritor(cls, false, CLASS_CONTEXT)
|| InheritanceUtil.isInheritor(cls, false, CLASS_VIEW)
|| InheritanceUtil.isInheritor(cls, false, CLASS_FRAGMENT);
}
}
@@ -32,6 +32,7 @@ import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.util.InheritanceUtil;
import org.jetbrains.uast.UAnonymousClass;
import org.jetbrains.uast.UClass;
@@ -89,8 +90,7 @@ public class ParcelDetector extends Detector implements Detector.UastScanner {
}
// Parceling spans is handled in TextUtils#CHAR_SEQUENCE_CREATOR
if (context.getEvaluator().implementsInterface(declaration,
"android.text.ParcelableSpan", false)) {
if (InheritanceUtil.isInheritor(declaration, false, "android.text.ParcelableSpan")) {
return;
}
@@ -39,6 +39,7 @@ import com.android.tools.klint.detector.api.XmlContext;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.util.InheritanceUtil;
import org.jetbrains.uast.UClass;
import org.w3c.dom.Element;
@@ -132,8 +133,8 @@ public class PreferenceActivityDetector extends Detector
}
JavaEvaluator evaluator = context.getEvaluator();
String className = declaration.getQualifiedName();
if (evaluator.extendsClass(declaration, PREFERENCE_ACTIVITY, false)
&& mExportedActivities.containsKey(className)) {
if (InheritanceUtil.isInheritor(declaration, false, PREFERENCE_ACTIVITY)
&& mExportedActivities.containsKey(className)) {
// Ignore the issue if we target an API greater than 19 and the class in
// question specifically overrides isValidFragment() and thus knowingly white-lists
// valid fragments.
@@ -50,6 +50,7 @@ import com.android.utils.SdkUtils;
import com.google.common.collect.Maps;
import com.intellij.psi.PsiClass;
import com.intellij.psi.util.InheritanceUtil;
import org.jetbrains.uast.UClass;
import org.w3c.dom.Element;
@@ -184,7 +185,7 @@ public class RegistrationDetector extends LayoutDetector implements Detector.Uas
String framework = mManifestRegistrations.get(className);
if (framework == null) {
reportMissing(context, cls, className, rightTag);
} else if (!evaluator.extendsClass(cls, framework, false)) {
} else if (!InheritanceUtil.isInheritor(cls, false, framework)) {
reportWrongTag(context, cls, rightTag, className, framework);
}
} else {
@@ -266,7 +267,7 @@ public class RegistrationDetector extends LayoutDetector implements Detector.Uas
private static String getTag(@NonNull JavaEvaluator evaluator, @NonNull PsiClass cls) {
String tag = null;
for (String s : sClasses) {
if (evaluator.extendsClass(cls, s, false)) {
if (InheritanceUtil.isInheritor(cls, false, s)) {
tag = classToTag(s);
break;
}
@@ -28,6 +28,7 @@ import com.android.tools.klint.detector.api.Severity;
import com.intellij.psi.PsiClassType;
import com.intellij.psi.PsiType;
import com.intellij.psi.util.InheritanceUtil;
import org.jetbrains.uast.UCallExpression;
import org.jetbrains.uast.UExpression;
import org.jetbrains.uast.UMethod;
@@ -99,8 +100,8 @@ public class SslCertificateSocketFactoryDetector extends Detector implements Det
PsiType type = args.get(0).getExpressionType();
if (type != null
&& (INET_ADDRESS_CLASS.equals(type.getCanonicalText())
|| context.getEvaluator().extendsClass(((PsiClassType)type).resolve(),
INET_ADDRESS_CLASS, false))) {
|| InheritanceUtil.isInheritor(((PsiClassType)type).resolve(), false,
INET_ADDRESS_CLASS))) {
context.report(CREATE_SOCKET, call, context.getUastLocation(call),
"Use of `SSLCertificateSocketFactory.createSocket()` " +
"with an InetAddress parameter can cause insecure " +
@@ -34,6 +34,7 @@ import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiClassType;
import com.intellij.psi.PsiType;
import com.intellij.psi.util.InheritanceUtil;
import org.jetbrains.uast.UCallExpression;
import org.jetbrains.uast.UExpression;
import org.jetbrains.uast.UMethod;
@@ -111,9 +112,9 @@ public class ViewTagDetector extends Detector implements Detector.UastScanner {
}
String objectType;
if (evaluator.extendsClass(typeClass, CLASS_VIEW, false)) {
if (InheritanceUtil.isInheritor(typeClass, false, CLASS_VIEW)) {
objectType = "views";
} else if (evaluator.implementsInterface(typeClass, CURSOR_CLS, false)) {
} else if (InheritanceUtil.isInheritor(typeClass, false, CURSOR_CLS)) {
objectType = "cursors";
} else if (typeClass.getName() != null && typeClass.getName().endsWith("ViewHolder")) {
objectType = "view holders";
@@ -152,23 +152,6 @@ public class IdeaJavaParser extends JavaParser {
myProject = project;
}
@Override
public boolean extendsClass(@Nullable PsiClass cls, @NonNull String className, boolean strict) {
// TODO: This checks interfaces too. Let's find a cheaper method which only checks direct super classes!
return InheritanceUtil.isInheritor(cls, strict, className);
}
@Override
public boolean implementsInterface(@NonNull PsiClass cls, @NonNull String interfaceName, boolean strict) {
// TODO: This checks superclasses too. Let's find a cheaper method which only checks interfaces.
return false;
}
@Override
public boolean inheritsFrom(@NonNull PsiClass cls, @NonNull String className, boolean strict) {
return InheritanceUtil.isInheritor(cls, strict, className);
}
@Nullable
@Override
public PsiClass findClass(@NonNull String qualifiedName) {
@@ -184,7 +167,7 @@ public class IdeaJavaParser extends JavaParser {
@NonNull
@Override
public PsiAnnotation[] getAllAnnotations(@NonNull PsiModifierListOwner owner) {
return AnnotationUtil.getAllAnnotations(owner, inHierarchy, null, true);
return AnnotationUtil.getAllAnnotations(owner, true, null, true);
}
@Nullable