Java Code Examples for com.android.tools.lint.detector.api.JavaContext#report()

The following examples show how to use com.android.tools.lint.detector.api.JavaContext#report() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: SupportAnnotationDetector.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
private static void reportTypeDef(@NonNull JavaContext context, @NonNull Node node,
        @Nullable Node errorNode, boolean flag, @NonNull Object[] allowedValues,
        @NonNull Iterable<ResolvedAnnotation> allAnnotations) {
    String values = listAllowedValues(allowedValues);
    String message;
    if (flag) {
        message = "Must be one or more of: " + values;
    } else {
        message = "Must be one of: " + values;
    }

    ResolvedAnnotation rangeAnnotation = findIntRange(allAnnotations);
    if (rangeAnnotation != null) {
        // Allow @IntRange on this number
        String rangeError = getIntRangeError(context, rangeAnnotation, node);
        if (rangeError != null && !rangeError.isEmpty()) {
            message += " or " + Character.toLowerCase(rangeError.charAt(0))
                    + rangeError.substring(1);
        }
    }

    if (errorNode == null) {
        errorNode = node;
    }
    context.report(TYPE_DEF, errorNode, context.getLocation(errorNode), message);
}
 
Example 2
Source File: InvalidR2UsageDetector.java    From butterknife with Apache License 2.0 6 votes vote down vote up
private static void detectR2(JavaContext context, UElement node) {
  UFile sourceFile = context.getUastFile();
  List<UClass> classes = sourceFile.getClasses();
  if (!classes.isEmpty() && classes.get(0).getName() != null) {
    String qualifiedName = classes.get(0).getName();
    if (qualifiedName.contains("_ViewBinder")
        || qualifiedName.contains("_ViewBinding")
        || qualifiedName.equals(R2)) {
      // skip generated files and R2
      return;
    }
  }
  boolean isR2 = isR2Expression(node);
  if (isR2 && !context.isSuppressedWithComment(node, ISSUE)) {
    context.report(ISSUE, node, context.getLocation(node), LINT_ERROR_BODY);
  }
}
 
Example 3
Source File: SampleCodeDetector.java    From android-custom-lint-rules with Apache License 2.0 6 votes vote down vote up
@Override
public UElementHandler createUastHandler(JavaContext context) {
    // Note: Visiting UAST nodes is a pretty general purpose mechanism;
    // Lint has specialized support to do common things like "visit every class
    // that extends a given super class or implements a given interface", and
    // "visit every call site that calls a method by a given name" etc.
    // Take a careful look at UastScanner and the various existing lint check
    // implementations before doing things the "hard way".
    // Also be aware of context.getJavaEvaluator() which provides a lot of
    // utility functionality.
    return new UElementHandler() {
        @Override
        public void visitLiteralExpression(ULiteralExpression expression) {
            String string = UastLiteralUtils.getValueIfStringLiteral(expression);
            if (string == null) {
                return;
            }

            if (string.contains("lint") && string.matches(".*\\blint\\b.*")) {
                context.report(ISSUE, expression, context.getLocation(expression),
                        "This code mentions `lint`: **Congratulations**");
            }
        }
    };
}
 
Example 4
Source File: HandlerDetector.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
@Override
public void checkClass(@NonNull JavaContext context, @Nullable ClassDeclaration declaration,
        @NonNull Node node, @NonNull ResolvedClass cls) {
    if (!isInnerClass(declaration)) {
        return;
    }

    if (isStaticClass(declaration)) {
        return;
    }

    // Only flag handlers using the default looper
    if (hasLooperConstructorParameter(cls)) {
        return;
    }

    Node locationNode = node instanceof ClassDeclaration
            ? ((ClassDeclaration) node).astName() : node;
    Location location = context.getLocation(locationNode);
    context.report(ISSUE, locationNode, location, String.format(
            "This Handler class should be static or leaks might occur (%1$s)",
            cls.getName()));
}
 
Example 5
Source File: PrivateResourceDetector.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
@Override
public void visitResourceReference(
        @NonNull JavaContext context,
        @Nullable AstVisitor visitor,
        @NonNull Node node,
        @NonNull String type,
        @NonNull String name,
        boolean isFramework) {
    if (context.getProject().isGradleProject() && !isFramework) {
        Project project = context.getProject();
        if (project.getGradleProjectModel() != null && project.getCurrentVariant() != null) {
            ResourceType resourceType = ResourceType.getEnum(type);
            if (resourceType != null && isPrivate(context, resourceType, name)) {
                String message = createUsageErrorMessage(context, resourceType, name);
                context.report(ISSUE, node, context.getLocation(node), message);
            }
        }
    }
}
 
Example 6
Source File: WrongCallDetector.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
private static void report(JavaContext context, MethodInvocation node) {
    // Make sure the call is on a view
    JavaParser.ResolvedNode resolved = context.resolve(node);
    if (resolved instanceof JavaParser.ResolvedMethod) {
        JavaParser.ResolvedMethod method = (JavaParser.ResolvedMethod) resolved;
        JavaParser.ResolvedClass containingClass = method.getContainingClass();
        if (!containingClass.isSubclassOf(CLASS_VIEW, false)) {
            return;
        }
    }

    String name = node.astName().astValue();
    String suggestion = Character.toLowerCase(name.charAt(2)) + name.substring(3);
    String message = String.format(
            // Keep in sync with {@link #getOldValue} and {@link #getNewValue} below!
            "Suspicious method call; should probably call \"`%1$s`\" rather than \"`%2$s`\"",
            suggestion, name);
    context.report(ISSUE, node, context.getLocation(node.astName()), message);
}
 
Example 7
Source File: LogDetector.java    From MeituanLintDemo with Apache License 2.0 6 votes vote down vote up
@Override
public AstVisitor createJavaVisitor(final JavaContext context) {
    return new ForwardingAstVisitor() {
        @Override
        public boolean visitMethodInvocation(MethodInvocation node) {
            JavaParser.ResolvedNode resolve = context.resolve(node);
            if (resolve instanceof JavaParser.ResolvedMethod) {
                JavaParser.ResolvedMethod method = (JavaParser.ResolvedMethod) resolve;
                // 方法所在的类校验
                JavaParser.ResolvedClass containingClass = method.getContainingClass();
                if (containingClass.matches("android.util.Log")) {
                    context.report(ISSUE, node, context.getLocation(node),
                                   "请使用Ln,避免使用Log");
                    return true;
                }
                if (node.toString().startsWith("System.out.println")) {
                    context.report(ISSUE, node, context.getLocation(node),
                                   "请使用Ln,避免使用System.out.println");
                    return true;
                }
            }
            return super.visitMethodInvocation(node);
        }
    };
}
 
Example 8
Source File: AppCompatCallDetector.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
@Override
public void visitMethod(@NonNull JavaContext context, @Nullable AstVisitor visitor,
        @NonNull MethodInvocation node) {
    if (mDependsOnAppCompat && isAppBarActivityCall(context, node)) {
        String name = node.astName().astValue();
        String replace = null;
        if (GET_ACTION_BAR.equals(name)) {
            replace = "getSupportActionBar";
        } else if (START_ACTION_MODE.equals(name)) {
            replace = "startSupportActionMode";
        } else if (SET_PROGRESS_BAR_VIS.equals(name)) {
            replace = "setSupportProgressBarVisibility";
        } else if (SET_PROGRESS_BAR_IN_VIS.equals(name)) {
            replace = "setSupportProgressBarIndeterminateVisibility";
        } else if (SET_PROGRESS_BAR_INDETERMINATE.equals(name)) {
            replace = "setSupportProgressBarIndeterminate";
        } else if (REQUEST_WINDOW_FEATURE.equals(name)) {
            replace = "supportRequestWindowFeature";
        }

        if (replace != null) {
            String message = String.format(ERROR_MESSAGE_FORMAT, replace, name);
            context.report(ISSUE, node, context.getLocation(node), message);
        }
    }
}
 
Example 9
Source File: AlarmDetector.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
private static void ensureAtLeast(@NonNull JavaContext context,
        @NonNull MethodInvocation node, int parameter, long min) {
    Iterator<Expression> iterator = node.astArguments().iterator();
    Expression argument = null;
    for (int i = 0; i <= parameter; i++) {
        if (!iterator.hasNext()) {
            return;
        }
        argument = iterator.next();
    }
    if (argument == null) {
        return;
    }

    long value = getLongValue(context, argument);
    if (value < min) {
        String message = String.format("Value will be forced up to %d as of Android 5.1; "
                + "don't rely on this to be exact", min);
        context.report(ISSUE, argument, context.getLocation(argument), message);
    }
}
 
Example 10
Source File: ThinrDetector.java    From thinr with Apache License 2.0 5 votes vote down vote up
private void markLeakSuspects(PsiElement element, PsiElement lambdaBody, @NonNull final JavaContext context) {
    if (element instanceof PsiReferenceExpression) {
        PsiReferenceExpression ref = (PsiReferenceExpression) element;

        if (ref.getQualifierExpression() == null) {

            PsiElement res = ref.resolve();
            if (!(res instanceof PsiParameter)) {
                if (!(res instanceof PsiClass)) {

                    boolean error = false;
                    if (res instanceof PsiLocalVariable) {
                        PsiLocalVariable lVar = (PsiLocalVariable) res;
                        if (!isParent(lambdaBody, lVar.getParent())) {
                            error = true;
                        }
                    }

                    if (res instanceof PsiField) {
                        PsiField field = (PsiField) res;
                        final PsiModifierList modifierList = field.getModifierList();
                        if (modifierList == null) {
                            error = true;
                        } else if (!modifierList.hasExplicitModifier(PsiModifier.STATIC)) {
                            error = true;
                        }
                    }

                    if (error) {
                        context.report(ISSUE, element, context.getNameLocation(element), "Possible leak");
                    }
                }
            }
        }
    }

    for (PsiElement psiElement : element.getChildren()) {
        markLeakSuspects(psiElement, lambdaBody, context);
    }
}
 
Example 11
Source File: HashMapForJDK7Detector.java    From MeituanLintDemo with Apache License 2.0 5 votes vote down vote up
/**
 * copy from lint source code
 */
private void checkCore(JavaContext context, Node node, TypeReference reference) {
    // reference.hasTypeArguments returns false where it should not
    StrictListAccessor<TypeReference, TypeReference> types = reference.getTypeArguments();
    if (types != null && types.size() == 2) {
        TypeReference first = types.first();
        String typeName = first.getTypeName();
        int minSdk = context.getMainProject().getMinSdk();
        if (typeName.equals(INTEGER) || typeName.equals(BYTE)) {
            String valueType = types.last().getTypeName();
            if (valueType.equals(INTEGER)) {
                context.report(ISSUE, node, context.getLocation(node),
                        "Use new SparseIntArray(...) instead for better performance");
            } else if (valueType.equals(LONG) && minSdk >= 18) {
                context.report(ISSUE, node, context.getLocation(node),
                        "Use new SparseLongArray(...) instead for better performance");
            } else if (valueType.equals(BOOLEAN)) {
                context.report(ISSUE, node, context.getLocation(node),
                        "Use new SparseBooleanArray(...) instead for better performance");
            } else {
                context.report(ISSUE, node, context.getLocation(node),
                        String.format(
                                "Use new SparseArray<%1$s>(...) instead for better performance",
                                valueType));
            }
        } else if (typeName.equals(LONG) && (minSdk >= 16 ||
                Boolean.TRUE == context.getMainProject().dependsOn(
                        SdkConstants.SUPPORT_LIB_ARTIFACT))) {
            boolean useBuiltin = minSdk >= 16;
            String message = useBuiltin ?
                    "Use new LongSparseArray(...) instead for better performance" :
                    "Use new android.support.v4.util.LongSparseArray(...) instead for better performance";
            context.report(ISSUE, node, context.getLocation(node),
                    message);
        }
    }
}
 
Example 12
Source File: CallSuperDetector.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
private static void checkCallSuper(@NonNull JavaContext context,
        @NonNull MethodDeclaration declaration,
        @NonNull ResolvedMethod method) {

    ResolvedMethod superMethod = getRequiredSuperMethod(method);
    if (superMethod != null) {
        if (!SuperCallVisitor.callsSuper(context, declaration, superMethod)) {
            String methodName = method.getName();
            String message = "Overriding method should call `super."
                    + methodName + "`";
            Location location = context.getLocation(declaration.astMethodName());
            context.report(ISSUE, declaration, location, message);
        }
    }
}
 
Example 13
Source File: DialogExtendLintDetector.java    From SimpleDialogFragments with Apache License 2.0 5 votes vote down vote up
@Override
public void visitClass(JavaContext context, UClass declaration) {
    PsiModifierList classModifiers = declaration.getModifierList();
    if (classModifiers == null || !classModifiers.hasModifierProperty("abstract")) {
        // check for static build method
        boolean hasBuildMethod = false;
        for (PsiMethod method : declaration.getMethods()) {
            if ("build".equals(method.getName()) && method.getModifierList()
                    .hasModifierProperty("static")) {
                hasBuildMethod = true;
                break;
            }
        }
        if (!hasBuildMethod){
            context.report(BUILD_OVERWRITE, context.getLocation(declaration.getExtendsList()),
                    BUILD_OVERWRITE_MESSAGE);
        }

        // check for public static String TAG
        boolean hasTag = false;
        for (UField field : declaration.getFields()) {
            PsiModifierList modifiers = field.getModifierList();
            if ("TAG".equals(field.getName()) && LintUtils.isString(field.getType()) &&
                    modifiers != null && modifiers.hasModifierProperty("public") &&
                    modifiers.hasModifierProperty("static")) {
                hasTag = true;
                break;
            }
        }
        if (!hasTag) {
            context.report(TAG, context.getLocation(declaration.getExtendsList()), TAG_MESSAGE);
        }

    }
}
 
Example 14
Source File: AddJavascriptInterfaceDetector.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
@Override
public void visitMethod(@NonNull JavaContext context, @Nullable AstVisitor visitor,
        @NonNull MethodInvocation node) {
    // Ignore the issue if we never build for any API less than 17.
    if (context.getMainProject().getMinSdk() >= 17) {
        return;
    }

    // Ignore if the method doesn't fit our description.
    ResolvedNode resolved = context.resolve(node);
    if (!(resolved instanceof ResolvedMethod)) {
        return;
    }
    ResolvedMethod method = (ResolvedMethod) resolved;
    if (!method.getContainingClass().isSubclassOf(WEB_VIEW, false)) {
        return;
    }
    if (method.getArgumentCount() != 2
            || !method.getArgumentType(0).matchesName(TYPE_OBJECT)
            || !method.getArgumentType(1).matchesName(TYPE_STRING)) {
        return;
    }

    String message = "`WebView.addJavascriptInterface` should not be called with minSdkVersion < 17 for security reasons: " +
                     "JavaScript can use reflection to manipulate application";
    context.report(ISSUE, node, context.getLocation(node.astName()), message);
}
 
Example 15
Source File: RootPackageDetector.java    From lewis with Apache License 2.0 5 votes vote down vote up
/**
 * Check if the node is inside the root package and report an issue in that case.
 *
 * @param context  is the context of the Java code.
 * @param node     represents the element to evaluate.
 * @param fileName is the name of the file.
 */
private void shouldNotBeInRootPackage(JavaContext context, Node node, String fileName) {

    String packageName = context.getMainProject().getPackage();

    String filePackageString = PackageManager.getPackage(context, node);

    if (filePackageString.equals(packageName + "." + fileName + ".java")
            && !PackageManager.isGenerated(context, node)) {
        context.report(ISSUE_CLASS_IN_ROOT_PACKAGE, PackageManager.getNodeLocation(context, node),
                " Expecting " + fileName + " not to be in root package " + packageName);
    }

}
 
Example 16
Source File: ViewConstructorDetector.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
@Override
public void checkClass(@NonNull JavaContext context, @Nullable ClassDeclaration node,
        @NonNull Node declarationOrAnonymous, @NonNull ResolvedClass resolvedClass) {
    if (node == null) {
        return;
    }

    // Only applies to concrete classes
    int flags = node.astModifiers().getEffectiveModifierFlags();
    // Ignore abstract classes
    if ((flags & Modifier.ABSTRACT) != 0) {
        return;
    }

    if (node.getParent() instanceof NormalTypeBody
            && ((flags & Modifier.STATIC) == 0)) {
        // Ignore inner classes that aren't static: we can't create these
        // anyway since we'd need the outer instance
        return;
    }

    boolean found = false;
    for (ResolvedMethod constructor : resolvedClass.getConstructors()) {
        if (isXmlConstructor(constructor)) {
            found = true;
            break;
        }
    }

    if (!found) {
        String message = String.format(
                "Custom view `%1$s` is missing constructor used by tools: "
                        + "`(Context)` or `(Context,AttributeSet)` "
                        + "or `(Context,AttributeSet,int)`",
                node.astName().astValue());
        Location location = context.getLocation(node.astName());
        context.report(ISSUE, node, location, message  /*data*/);
    }
}
 
Example 17
Source File: DebugLintIssue.java    From Debug with Apache License 2.0 4 votes vote down vote up
private static void process(@NonNull JavaContext context, @NonNull UCallExpression expression) {

        // to be able to mutate (we remove first Throwable if present)
        final List<UExpression> arguments = new ArrayList<>(expression.getValueArguments());
        if (arguments.isEmpty()) {
            // if there are no arguments -> no check
            return;
        }

        // remove throwable (comes first0
        if (isSubclassOf(context, arguments.get(0), Throwable.class)) {
            arguments.remove(0);
        }

        // still check for empty arguments (method can be called with just a throwable)
        // if first argument is not a string, then also nothing to do here
        if (arguments.isEmpty()
                || !isSubclassOf(context, arguments.get(0), String.class)) {
            return;
        }

        // now, first arg is string, check if it matches the pattern
        final String pattern = (String) arguments.get(0).evaluate();
        if (pattern == null
                || pattern.length() == 0) {
            // if no pattern is available -> return
            return;
        }

        final Matcher matcher = STRING_FORMAT_PATTERN.matcher(pattern);

        // we must _find_, not _matches_
        if (matcher.find()) {
            // okay, first argument is string
            // evaluate other arguments (actually create them)

            // remove pattern
            arguments.remove(0);

            // what else can we do -> count actual placeholders and arguments
            // (if mismatch... no, we can have positioned)
            final Object[] mock = mockArguments(arguments);

            try {
                //noinspection ResultOfMethodCallIgnored
                String.format(pattern, mock);
            } catch (Throwable t) {
                context.report(
                        ISSUE,
                        expression,
                        context.getLocation(expression),
                        t.getMessage());
            }
        }
    }
 
Example 18
Source File: CutPasteDetector.java    From javaide with GNU General Public License v3.0 4 votes vote down vote up
@Override
public void visitMethod(@NonNull JavaContext context, @Nullable AstVisitor visitor,
        @NonNull MethodInvocation call) {
    String lhs = getLhs(call);
    if (lhs == null) {
        return;
    }

    Node method = JavaContext.findSurroundingMethod(call);
    if (method == null) {
        return;
    } else if (method != mLastMethod) {
        mIds = Maps.newHashMap();
        mLhs = Maps.newHashMap();
        mCallOperands = Maps.newHashMap();
        mLastMethod = method;
    }

    String callOperand = call.astOperand() != null ? call.astOperand().toString() : "";

    Expression first = call.astArguments().first();
    if (first instanceof Select) {
        Select select = (Select) first;
        String id = select.astIdentifier().astValue();
        Expression operand = select.astOperand();
        if (operand instanceof Select) {
            Select type = (Select) operand;
            if (type.astIdentifier().astValue().equals(RESOURCE_CLZ_ID)) {
                if (mIds.containsKey(id)) {
                    if (lhs.equals(mLhs.get(id))) {
                        return;
                    }
                    if (!callOperand.equals(mCallOperands.get(id))) {
                        return;
                    }
                    MethodInvocation earlierCall = mIds.get(id);
                    if (!isReachableFrom(method, earlierCall, call)) {
                        return;
                    }
                    Location location = context.getLocation(call);
                    Location secondary = context.getLocation(earlierCall);
                    secondary.setMessage("First usage here");
                    location.setSecondary(secondary);
                    context.report(ISSUE, call, location, String.format(
                        "The id `%1$s` has already been looked up in this method; possible " +
                        "cut & paste error?", first.toString()));
                } else {
                    mIds.put(id, call);
                    mLhs.put(id, lhs);
                    mCallOperands.put(id, callOperand);
                }
            }
        }
    }
}
 
Example 19
Source File: InternalFolivoraApiDetector.java    From Folivora with Apache License 2.0 4 votes vote down vote up
private void report(JavaContext context, UCallExpression call) {
  context.report(ISSUE, call, context.getLocation(call),
    "`Folivora.applyDrawableToView()` should only be called in preview stub view's (Context context, AttributeSet attrs) constructor");
}
 
Example 20
Source File: DialogMethodCallLintDetector.java    From SimpleDialogFragments with Apache License 2.0 3 votes vote down vote up
@Override
public void visitMethod(JavaContext context, UCallExpression node, PsiMethod method) {

    if (context.getEvaluator().isMemberInSubClassOf(method,
            "eltos.simpledialogfragment.SimpleDialog", false)) {

        PsiClass definingClass = method.getContainingClass();
        UExpression callingExpression = node.getReceiver();

        if (definingClass != null && callingExpression != null) {

            PsiType type = TypeEvaluator.evaluate(callingExpression);
            if (type instanceof PsiClassType) {
                // when called on instance of a class
                PsiClass callingClass = ((PsiClassType) type).resolve();

                if (callingClass != null && !Objects.equals(callingClass, definingClass)) {

                    context.report(BUILD_CALL, context.getLocation(node), String.format(
                            BUILD_CALL_MESSAGE, callingClass.getName(), definingClass.getName()));
                }

            } else {
                // when called as static reference
                if (!Objects.equals(definingClass.getName(), callingExpression.toString())) {
                    context.report(BUILD_CALL, context.getLocation(node), String.format(
                            BUILD_CALL_MESSAGE, callingExpression, definingClass.getName()));
                }
            }

        }



    }

}