use of com.android.tools.klint.client.api.JavaEvaluator in project kotlin by JetBrains.
the class CallSuperDetector method getRequiredSuperMethod.
/**
* Checks whether the given method overrides a method which requires the super method
* to be invoked, and if so, returns it (otherwise returns null)
*/
@Nullable
private static PsiMethod getRequiredSuperMethod(@NonNull JavaContext context, @NonNull PsiMethod method) {
JavaEvaluator evaluator = context.getEvaluator();
PsiMethod directSuper = evaluator.getSuperMethod(method);
if (directSuper == null) {
return null;
}
String name = method.getName();
if (ON_DETACHED_FROM_WINDOW.equals(name)) {
// compileSdkVersion >= N).
if (!evaluator.isMemberInSubClassOf(method, CLASS_VIEW, false)) {
return null;
}
return directSuper;
} else if (ON_VISIBILITY_CHANGED.equals(name)) {
// the support library
if (!evaluator.isMemberInSubClassOf(method, "android.support.wearable.watchface.WatchFaceService.Engine", false)) {
return null;
}
return directSuper;
}
// Look up annotations metadata
PsiMethod superMethod = directSuper;
while (superMethod != null) {
PsiAnnotation[] annotations = superMethod.getModifierList().getAnnotations();
annotations = filterRelevantAnnotations(context.getEvaluator(), annotations);
for (PsiAnnotation annotation : annotations) {
String signature = annotation.getQualifiedName();
if (CALL_SUPER_ANNOTATION.equals(signature)) {
return directSuper;
} else if (signature != null && signature.endsWith(".OverrideMustInvoke")) {
// Handle findbugs annotation on the fly too
return directSuper;
}
}
superMethod = evaluator.getSuperMethod(superMethod);
}
return null;
}
use of com.android.tools.klint.client.api.JavaEvaluator in project kotlin by JetBrains.
the class CleanupDetector method checkResourceRecycled.
private static void checkResourceRecycled(@NonNull JavaContext context, @NonNull UCallExpression node, @NonNull PsiMethod method) {
String name = method.getName();
// Recycle detector
PsiClass containingClass = method.getContainingClass();
if (containingClass == null) {
return;
}
JavaEvaluator evaluator = context.getEvaluator();
if ((OBTAIN.equals(name) || OBTAIN_NO_HISTORY.equals(name)) && InheritanceUtil.isInheritor(containingClass, false, MOTION_EVENT_CLS)) {
checkRecycled(context, node, MOTION_EVENT_CLS, RECYCLE);
} else if (OBTAIN.equals(name) && InheritanceUtil.isInheritor(containingClass, false, PARCEL_CLS)) {
checkRecycled(context, node, PARCEL_CLS, RECYCLE);
} else if (OBTAIN.equals(name) && 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)) && (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();
if (cls != null && "android.content.res.TypedArray".equals(cls.getQualifiedName())) {
checkRecycled(context, node, "android.content.res.TypedArray", RECYCLE);
}
}
} 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)) && (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
// android.content.ContentResolver#query
// android.database.sqlite.SQLiteQueryBuilder#query
// android.provider.Browser#getAllBookmarks
// android.provider.Browser#getAllVisitedUrls
// android.provider.DocumentsProvider#queryChildDocuments
// android.provider.DocumentsProvider#qqueryDocument
// android.provider.DocumentsProvider#queryRecentDocuments
// android.provider.DocumentsProvider#queryRoots
// android.provider.DocumentsProvider#querySearchDocuments
// android.provider.MediaStore$Images$Media#query
// android.widget.FilterQueryProvider#runQuery
checkClosedOrUsed(context, node, CURSOR_CLS);
}
}
use of com.android.tools.klint.client.api.JavaEvaluator in project kotlin by JetBrains.
the class CleanupDetector method isEditorApplyMethodCall.
private static boolean isEditorApplyMethodCall(@NonNull JavaContext context, @NonNull UCallExpression call) {
String methodName = call.getMethodName();
if (APPLY.equals(methodName)) {
PsiMethod method = call.resolve();
if (method != null) {
PsiClass containingClass = method.getContainingClass();
JavaEvaluator evaluator = context.getEvaluator();
return InheritanceUtil.isInheritor(containingClass, false, ANDROID_CONTENT_SHARED_PREFERENCES_EDITOR);
}
}
return false;
}
use of com.android.tools.klint.client.api.JavaEvaluator in project kotlin by JetBrains.
the class JavaScriptInterfaceDetector method visitMethod.
@Override
public void visitMethod(@NonNull JavaContext context, @Nullable UastVisitor visitor, @NonNull UCallExpression call, @NonNull UMethod method) {
if (context.getMainProject().getTargetSdk() < 17) {
return;
}
List<UExpression> arguments = call.getValueArguments();
if (arguments.size() != 2) {
return;
}
JavaEvaluator evaluator = context.getEvaluator();
if (!JavaEvaluator.isMemberInClass(method, WEB_VIEW_CLS)) {
return;
}
UExpression first = arguments.get(0);
PsiType evaluated = TypeEvaluator.evaluate(context, first);
if (evaluated instanceof PsiClassType) {
PsiClassType classType = (PsiClassType) evaluated;
PsiClass cls = classType.resolve();
if (cls == null) {
return;
}
if (isJavaScriptAnnotated(cls)) {
return;
}
Location location = context.getUastNameLocation(call);
String message = String.format("None of the methods in the added interface (%1$s) have been annotated " + "with `@android.webkit.JavascriptInterface`; they will not " + "be visible in API 17", cls.getName());
context.report(ISSUE, call, location, message);
}
}
use of com.android.tools.klint.client.api.JavaEvaluator in project kotlin by JetBrains.
the class OverrideConcreteDetector method checkClass.
@Override
public void checkClass(@NonNull JavaContext context, @NonNull UClass declaration) {
JavaEvaluator evaluator = context.getEvaluator();
if (evaluator.isAbstract(declaration)) {
return;
}
int minSdk = Math.max(context.getProject().getMinSdk(), getTargetApi(declaration));
if (minSdk >= CONCRETE_IN) {
return;
}
String[] methodNames = { ON_NOTIFICATION_POSTED, ON_NOTIFICATION_REMOVED };
for (String methodName : methodNames) {
boolean found = false;
for (PsiMethod method : declaration.findMethodsByName(methodName, true)) {
// Make sure it's not the base method, but that it's been defined
// in a subclass, concretely
PsiClass containingClass = method.getContainingClass();
if (containingClass == null) {
continue;
}
if (NOTIFICATION_LISTENER_SERVICE_FQN.equals(containingClass.getQualifiedName())) {
continue;
}
// of the method
if (evaluator.isAbstract(method)) {
continue;
}
// Make sure it has the exact right signature
if (method.getParameterList().getParametersCount() != 1) {
// Wrong signature
continue;
}
if (!evaluator.parameterHasType(method, 0, STATUS_BAR_NOTIFICATION_FQN)) {
continue;
}
found = true;
break;
}
if (!found) {
String message = String.format("Must override `%1$s.%2$s(%3$s)`: Method was abstract until %4$d, and your `minSdkVersion` is %5$d", NOTIFICATION_LISTENER_SERVICE_FQN, methodName, STATUS_BAR_NOTIFICATION_FQN, CONCRETE_IN, minSdk);
context.reportUast(ISSUE, declaration, context.getUastNameLocation(declaration), message);
break;
}
}
}
Aggregations