if (resolved != null) { for (ResolvedAnnotation annotation : resolved.getAnnotations()) { String signature = annotation.getSignature(); if (signature.equals(COLOR_INT_ANNOTATION)) { return Collections.singletonList(COLOR_INT_MARKER_TYPE);
@NonNull Node argument, @NonNull ResolvedAnnotation annotation) { String signature = annotation.getSignature(); boolean flag = annotation.getValue(TYPE_DEF_FLAG_ATTRIBUTE) == Boolean.TRUE; checkTypeDefConstant(context, annotation, argument, null, flag); } else if (signature.equals(STRING_DEF_ANNOTATION)) {
@Nullable static ResolvedAnnotation getRelevantAnnotation(@NonNull ResolvedAnnotation annotation) { String signature = annotation.getSignature(); if (signature.startsWith(SUPPORT_ANNOTATIONS_PREFIX)) { ResolvedClass type = annotation.getClassType(); if (type != null) { for (ResolvedAnnotation inner : type.getAnnotations()) { if (inner.matches(INT_DEF_ANNOTATION) || inner.matches(STRING_DEF_ANNOTATION) || inner.matches(PERMISSION_ANNOTATION)) { return inner;
annotation = SupportAnnotationDetector.getRelevantAnnotation(annotation); if (annotation != null) { String signature = annotation.getSignature(); if (CALL_SUPER_ANNOTATION.equals(signature)) { return directSuper;
@Nullable Context context, @NonNull ResolvedAnnotation annotation) { String value = (String)annotation.getValue(ATTR_VALUE); if (value != null && !value.isEmpty()) { for (int i = 0, n = value.length(); i < n; i++) { Object v = annotation.getValue(ATTR_ANY_OF); if (v != null) { if (v instanceof String[]) { v = annotation.getValue(ATTR_ALL_OF); if (v != null) { if (v instanceof String[]) {
String name = annotation.getSignature(); if (name.startsWith(SUPPORT_ANNOTATIONS_PREFIX) && name.endsWith(THREAD_SUFFIX)) { String name = annotation.getSignature(); if (name.startsWith(SUPPORT_ANNOTATIONS_PREFIX) && name.endsWith(THREAD_SUFFIX)) {
/** * Returns whether this requirement is conditional, meaning that there are * some circumstances in which the requirement is not necessary. For * example, consider * {@code android.app.backup.BackupManager.dataChanged(java.lang.String)} . * Here the {@code android.permission.BACKUP} is required but only if the * argument is not your own package. * <p> * This is used to handle permissions differently between the "missing" and * "unused" checks. When checking for missing permissions, we err on the * side of caution: if you are missing a permission, but the permission is * conditional, you may not need it so we may not want to complain. However, * when looking for unused permissions, we don't want to flag the * conditional permissions as unused since they may be required. * * @return true if this requirement is conditional */ public boolean isConditional() { Object o = annotation.getValue(ATTR_CONDITIONAL); if (o instanceof Boolean) { return (Boolean)o; } return false; }
private static void checkResult(@NonNull JavaContext context, @NonNull MethodInvocation node, @NonNull ResolvedAnnotation annotation) { if (node.getParent() instanceof ExpressionStatement) { String methodName = node.astName().astValue(); Object suggested = annotation.getValue(ATTR_SUGGEST); // Failing to check permissions is a potential security issue (and had an existing // dedicated issue id before which people may already have configured with a // custom severity in their LintOptions etc) so continue to use that issue // (which also has category Security rather than Correctness) for these: Issue issue = CHECK_RESULT; if (methodName.startsWith("check") && methodName.contains("Permission")) { issue = CHECK_PERMISSION; } String message = String.format("The result of `%1$s` is not used", methodName); if (suggested != null) { // TODO: Resolve suggest attribute (e.g. prefix annotation class if it starts // with "#" etc? message = String.format( "The result of `%1$s` is not used; did you mean to call `%2$s`?", methodName, suggested.toString()); } context.report(issue, node, context.getLocation(node), message); } }
@Nullable public ResolvedAnnotation getAnnotation(@NonNull ResolvedMethod method, int parameterIndex, @NonNull String type) { MethodInfo m = findMethod(method); if (m == null) { return null; } if (m.getParameterAnnotations() != null) { Collection<ResolvedAnnotation> annotations = m.getParameterAnnotations().get(parameterIndex); if (annotations != null) { for (ResolvedAnnotation annotation : annotations) { if (type.equals(annotation.getSignature())) { return annotation; } } } } return null; }
private static boolean isJavaScriptAnnotated(ResolvedClass clz) { while (clz != null) { for (ResolvedAnnotation annotation : clz.getAnnotations()) { if (annotation.getType().matchesSignature(JAVASCRIPT_INTERFACE_CLS)) { return true; } } for (ResolvedMethod method : clz.getMethods(false)) { for (ResolvedAnnotation annotation : method.getAnnotations()) { if (annotation.getType().matchesSignature(JAVASCRIPT_INTERFACE_CLS)) { return true; } } } clz = clz.getSuperClass(); } return false; }
@Nullable public ResolvedAnnotation getAnnotation(@NonNull ResolvedMethod method, @NonNull String type) { MethodInfo m = findMethod(method); if (m == null) { return null; } List<ResolvedAnnotation> annotations = m.getAnnotations(); if (annotations != null) { for (ResolvedAnnotation annotation : annotations) { if (type.equals(annotation.getSignature())) { return annotation; } } } return null; }
/** * Searches for the annotation of the given type on the method * * @param type the fully qualified name of the annotation to check * @param parameterIndex the index of the parameter to look up * @return the annotation, or null if not found */ @Nullable public ResolvedAnnotation getParameterAnnotation(@NonNull String type, int parameterIndex) { for (ResolvedAnnotation annotation : getParameterAnnotations(parameterIndex)) { if (annotation.getType().matchesSignature(type)) { return annotation; } } return null; }
@Nullable public ResolvedAnnotation getAnnotation(@NonNull ResolvedClass cls, @NonNull String type) { ClassInfo c = findClass(cls); if (c == null) { return null; } List<ResolvedAnnotation> annotations = c.getAnnotations(); if (annotations != null) { for (ResolvedAnnotation annotation : annotations) { if (type.equals(annotation.getSignature())) { return annotation; } } } return null; }
private void checkMethodAnnotation( @NonNull JavaContext context, @NonNull ResolvedMethod method, @NonNull MethodInvocation node, @NonNull ResolvedAnnotation annotation) { String signature = annotation.getSignature(); if (CHECK_RESULT_ANNOTATION.equals(signature) || signature.endsWith(".CheckReturnValue")) { // support findbugs annotation too checkResult(context, node, annotation); } else if (signature.equals(PERMISSION_ANNOTATION)) { checkPermission(context, node, method, annotation); } else if (signature.endsWith(THREAD_SUFFIX) && signature.startsWith(SUPPORT_ANNOTATIONS_PREFIX)) { checkThreading(context, node, method, signature); } }
@Nullable public ResolvedAnnotation getAnnotation(@NonNull ResolvedField field, @NonNull String type) { FieldInfo f = findField(field); if (f == null) { return null; } List<ResolvedAnnotation> annotations = f.getAnnotations(); if (annotations != null) { for (ResolvedAnnotation annotation : annotations) { if (type.equals(annotation.getSignature())) { return annotation; } } } return null; }
@Nullable public ResolvedAnnotation getAnnotation(@NonNull ResolvedPackage pkg, @NonNull String type) { ClassInfo c = findPackage(pkg); if (c == null) { return null; } List<ResolvedAnnotation> annotations = c.getAnnotations(); if (annotations != null) { for (ResolvedAnnotation annotation : annotations) { if (type.equals(annotation.getSignature())) { return annotation; } } } return null; }
/** * Searches for the annotation of the given type on this node * * @param type the fully qualified name of the annotation to check * @return the annotation, or null if not found */ @Nullable public ResolvedAnnotation getAnnotation(@NonNull String type) { for (ResolvedAnnotation annotation : getAnnotations()) { if (annotation.getType().matchesSignature(type)) { return annotation; } } return null; }
@Nullable public Object getValue() { return getValue(ATTR_VALUE); }
@Nullable private ClassInfo findClass(@NonNull ResolvedAnnotation cls) { return mClassMap.get(cls.getName()); }