lombok.ast.Node Java Examples

The following examples show how to use lombok.ast.Node. 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: CleanupDetector.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
private static boolean isCommittedInChainedCalls(@NonNull JavaContext context,
        @NonNull MethodInvocation node) {
    // Look for chained calls since the FragmentManager methods all return "this"
    // to allow constructor chaining, e.g.
    //    getFragmentManager().beginTransaction().addToBackStack("test")
    //            .disallowAddToBackStack().hide(mFragment2).setBreadCrumbShortTitle("test")
    //            .show(mFragment2).setCustomAnimations(0, 0).commit();
    Node parent = node.getParent();
    while (parent instanceof MethodInvocation) {
        MethodInvocation methodInvocation = (MethodInvocation) parent;
        if (isTransactionCommitMethodCall(context, methodInvocation)
                || isShowFragmentMethodCall(context, methodInvocation)) {
            return true;
        }

        parent = parent.getParent();
    }

    return false;
}
 
Example #2
Source File: SupportAnnotationDetector.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
private static void checkIntRange(
        @NonNull JavaContext context,
        @NonNull ResolvedAnnotation annotation,
        @NonNull Node argument,
        @NonNull Iterable<ResolvedAnnotation> allAnnotations) {
    String message = getIntRangeError(context, annotation, argument);
    if (message != null) {
        if (findIntDef(allAnnotations) != null) {
            // Don't flag int range errors if there is an int def annotation there too;
            // there could be a valid @IntDef constant. (The @IntDef check will
            // perform range validation by calling getIntRange.)
            return;
        }

        context.report(RANGE, argument, context.getLocation(argument), message);
    }
}
 
Example #3
Source File: CutPasteDetector.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
@Nullable
private static String getLhs(@NonNull MethodInvocation call) {
    Node parent = call.getParent();
    if (parent instanceof Cast) {
        parent = parent.getParent();
    }

    if (parent instanceof VariableDefinitionEntry) {
        VariableDefinitionEntry vde = (VariableDefinitionEntry) parent;
        return vde.astName().astValue();
    } else if (parent instanceof BinaryExpression) {
        BinaryExpression be = (BinaryExpression) parent;
        Expression left = be.astLeft();
        if (left instanceof VariableReference || left instanceof Select) {
            return be.astLeft().toString();
        } else if (left instanceof ArrayAccess) {
            ArrayAccess aa = (ArrayAccess) left;
            return aa.astOperand().toString();
        }
    }

    return null;
}
 
Example #4
Source File: SupportAnnotationDetector.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
private static void checkFloatRange(
        @NonNull JavaContext context,
        @NonNull ResolvedAnnotation annotation,
        @NonNull Node argument) {
    Object object = ConstantEvaluator.evaluate(context, argument);
    if (!(object instanceof Number)) {
        return;
    }
    double value = ((Number)object).doubleValue();
    double from = getDoubleAttribute(annotation, ATTR_FROM, Double.NEGATIVE_INFINITY);
    double to = getDoubleAttribute(annotation, ATTR_TO, Double.POSITIVE_INFINITY);
    boolean fromInclusive = getBoolean(annotation, ATTR_FROM_INCLUSIVE, true);
    boolean toInclusive = getBoolean(annotation, ATTR_TO_INCLUSIVE, true);

    String message = getFloatRangeError(value, from, to, fromInclusive, toInclusive, argument);
    if (message != null) {
        context.report(RANGE, argument, context.getLocation(argument), message);
    }
}
 
Example #5
Source File: LogDetector.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
private static boolean checkWithinConditional(
        @NonNull JavaContext context,
        @Nullable Node curr,
        @NonNull MethodInvocation logCall) {
    while (curr != null) {
        if (curr instanceof If) {
            If ifNode = (If) curr;
            if (ifNode.astCondition() instanceof MethodInvocation) {
                MethodInvocation call = (MethodInvocation) ifNode.astCondition();
                if (IS_LOGGABLE.equals(call.astName().astValue())) {
                    checkTagConsistent(context, logCall, call);
                }
            }

            return true;
        } else if (curr instanceof MethodInvocation
                || curr instanceof ClassDeclaration) { // static block
            break;
        }
        curr = curr.getParent();
    }
    return false;
}
 
Example #6
Source File: WrongCallDetector.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) {

    // Call is only allowed if it is both only called on the super class (invoke special)
    // as well as within the same overriding method (e.g. you can't call super.onLayout
    // from the onMeasure method)
    Expression operand = node.astOperand();
    if (!(operand instanceof Super)) {
        report(context, node);
        return;
    }

    Node method = StringFormatDetector.getParentMethod(node);
    if (!(method instanceof MethodDeclaration) ||
            !((MethodDeclaration)method).astMethodName().astValue().equals(
                    node.astName().astValue())) {
        report(context, node);
    }
}
 
Example #7
Source File: PermissionFinder.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Searches for a permission requirement for the given parameter in the given call
 *
 * @param operation the operation to look up
 * @param context   the context to use for lookup
 * @param parameter the parameter which contains the value which implies the permission
 * @return the result with the permission requirement, or null if nothing is found
 */
@Nullable
public static Result findRequiredPermissions(
        @NonNull Operation operation,
        @NonNull JavaContext context,
        @NonNull Node parameter) {

    // To find the permission required by an intent, we proceed in 3 steps:
    // (1) Locate the parameter in the start call that corresponds to
    //     the Intent
    //
    // (2) Find the place where the intent is initialized, and figure
    //     out the action name being passed to it.
    //
    // (3) Find the place where the action is defined, and look for permission
    //     annotations on that action declaration!

    return new PermissionFinder(context, operation).search(parameter);
}
 
Example #8
Source File: SupportAnnotationDetector.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
@NonNull
private static PermissionHolder addLocalPermissions(
        @NonNull JavaContext context,
        @NonNull PermissionHolder permissions,
        @NonNull Node node) {
    // Accumulate @RequirePermissions available in the local context
    Node methodNode = JavaContext.findSurroundingMethod(node);
    if (methodNode == null) {
        return permissions;
    }
    ResolvedNode resolved = context.resolve(methodNode);
    if (!(resolved instanceof ResolvedMethod)) {
        return permissions;
    }
    ResolvedMethod method = (ResolvedMethod) resolved;
    ResolvedAnnotation annotation = method.getAnnotation(PERMISSION_ANNOTATION);
    permissions = mergeAnnotationPermissions(context, permissions, annotation);
    annotation = method.getContainingClass().getAnnotation(PERMISSION_ANNOTATION);
    permissions = mergeAnnotationPermissions(context, permissions, annotation);
    return permissions;
}
 
Example #9
Source File: JavaContext.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Returns the first ancestor node of the given type
 *
 * @param element the element to search from
 * @param clz     the target node type
 * @param strict  if true, do not consider the element itself, only its parents
 * @param <T>     the target node type
 * @return the nearest ancestor node in the parent chain, or null if not found
 */
@Nullable
public static <T extends Node> T getParentOfType(
        @Nullable Node element,
        @NonNull Class<T> clz,
        boolean strict) {
    if (element == null) {
        return null;
    }

    if (strict) {
        element = element.getParent();
    }

    while (element != null) {
        if (clz.isInstance(element)) {
            //noinspection unchecked
            return (T) element;
        }
        element = element.getParent();
    }

    return null;
}
 
Example #10
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 #11
Source File: PreferenceActivityDetector.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 node,
        @NonNull Node declarationOrAnonymous, @NonNull ResolvedClass resolvedClass) {
    if (!context.getProject().getReportIssues()) {
        return;
    }
    String className = resolvedClass.getName();
    if (resolvedClass.isSubclassOf(PREFERENCE_ACTIVITY, false)
            && 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.
        if (context.getMainProject().getTargetSdk() >= 19
                && overridesIsValidFragment(resolvedClass)) {
            return;
        }

        String message = String.format(
                "`PreferenceActivity` subclass `%1$s` should not be exported",
                className);
        Location location = mExportedActivities.get(className).resolve();
        context.report(ISSUE, declarationOrAnonymous, location, message);
    }
}
 
Example #12
Source File: SupportAnnotationDetector.java    From javaide with GNU General Public License v3.0 6 votes vote down vote up
private void checkMethodAnnotation(
        @NonNull JavaContext context,
        @NonNull ResolvedMethod method,
        @NonNull Node 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)) {
        PermissionRequirement requirement = PermissionRequirement.create(context, annotation);
        checkPermission(context, node, method, null, requirement);
    } else if (signature.endsWith(THREAD_SUFFIX)
            && signature.startsWith(SUPPORT_ANNOTATIONS_PREFIX)) {
        checkThreading(context, node, method, signature);
    }
}
 
Example #13
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 #14
Source File: HashMapForJDK7Detector.java    From MeituanLintDemo with Apache License 2.0 5 votes vote down vote up
private void checkCore2(JavaContext context, Node node, String fullTypeName) {
    final Pattern p = Pattern.compile(".*<(.*),(.*)>");
    Matcher m = p.matcher(fullTypeName);
    if (m.find()) {
        String typeName = m.group(1).trim();
        String valueType = m.group(2).trim();
        int minSdk = context.getMainProject().getMinSdk();
        if (typeName.equals(INTEGER) || typeName.equals(BYTE)) {
            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 #15
Source File: JavaPerformanceDetector.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Check whether the given invocation is done as a lazy initialization,
 * e.g. {@code if (foo == null) foo = new Foo();}.
 * <p>
 * This tries to also handle the scenario where the check is on some
 * <b>other</b> variable - e.g.
 * <pre>
 *    if (foo == null) {
 *        foo == init1();
 *        bar = new Bar();
 *    }
 * </pre>
 * or
 * <pre>
 *    if (!initialized) {
 *        initialized = true;
 *        bar = new Bar();
 *    }
 * </pre>
 */
private static boolean isLazilyInitialized(Node node) {
    Node curr = node.getParent();
    while (curr != null) {
        if (curr instanceof MethodDeclaration) {
            return false;
        } else if (curr instanceof If) {
            If ifNode = (If) curr;
            // See if the if block represents a lazy initialization:
            // compute all variable names seen in the condition
            // (e.g. for "if (foo == null || bar != foo)" the result is "foo,bar"),
            // and then compute all variables assigned to in the if body,
            // and if there is an overlap, we'll consider the whole if block
            // guarded (so lazily initialized and an allocation we won't complain
            // about.)
            List<String> assignments = new ArrayList<String>();
            AssignmentTracker visitor = new AssignmentTracker(assignments);
            ifNode.astStatement().accept(visitor);
            if (!assignments.isEmpty()) {
                List<String> references = new ArrayList<String>();
                addReferencedVariables(references, ifNode.astCondition());
                if (!references.isEmpty()) {
                    SetView<String> intersection = Sets.intersection(
                            new HashSet<String>(assignments),
                            new HashSet<String>(references));
                    return !intersection.isEmpty();
                }
            }
            return false;

        }
        curr = curr.getParent();
    }

    return false;
}
 
Example #16
Source File: CommentDetector.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
@Override
public List<Class<? extends Node>> getApplicableNodeTypes() {
    if (USE_AST) {
        return Collections.<Class<? extends Node>>singletonList(Comment.class);
    } else {
        return null;
    }
}
 
Example #17
Source File: UnsafeAndroidDetector.java    From SafelyAndroid with MIT License 5 votes vote down vote up
private boolean isInsideDialogFragment(JavaContext context, MethodInvocation node) {
    Node parent = node.getParent();
    while (parent != null) {
        Object resolvedNode = context.resolve(parent);
        if (resolvedNode instanceof JavaParser.ResolvedMethod) {
            JavaParser.ResolvedMethod method = (JavaParser.ResolvedMethod) resolvedNode;
            if (isDialogFragment(method.getContainingClass())) {
                return true;
            }
        }
        parent = parent.getParent();
    }
    return false;
}
 
Example #18
Source File: AnnotationDetector.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
private void ensureUsingFlagStyle(@NonNull List<Node> constants) {
    if (constants.size() < 3) {
        return;
    }

    List<VariableReference> references =
            Lists.newArrayListWithExpectedSize(constants.size());
    for (Node constant : constants) {
        if (constant instanceof VariableReference) {
            references.add((VariableReference) constant);
        }
    }
    List<VariableDefinitionEntry> entries = findDeclarations(
            findSurroundingClass(constants.get(0)), references);
    for (VariableDefinitionEntry entry : entries) {
        Expression declaration = entry.astInitializer();
        if (declaration == null) {
            continue;
        }
        if (declaration instanceof IntegralLiteral) {
            IntegralLiteral literal = (IntegralLiteral) declaration;
            // Allow -1, 0 and 1. You can write 1 as "1 << 0" but IntelliJ for
            // example warns that that's a redundant shift.
            long value = literal.astLongValue();
            if (Math.abs(value) <= 1) {
                continue;
            }
            // Only warn if we're setting a specific bit
            if (Long.bitCount(value) != 1) {
                continue;
            }
            int shift = Long.numberOfTrailingZeros(value);
            String message = String.format(
                    "Consider declaring this constant using 1 << %1$d instead",
                    shift);
            mContext.report(FLAG_STYLE, declaration, mContext.getLocation(declaration),
                    message);
        }
    }
}
 
Example #19
Source File: JavaContext.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
@Nullable
public static Node getParameter(@NonNull Node call, int parameter) {
    Iterator<Expression> iterator = getParameters(call);

    for (int i = 0; i < parameter - 1; i++) {
        if (!iterator.hasNext()) {
            return null;
        }
        iterator.next();
    }
    return iterator.hasNext() ? iterator.next() : null;
}
 
Example #20
Source File: EcjParser.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
@Nullable
@Override
public ResolvedClass findClass(@NonNull JavaContext context,
        @NonNull String fullyQualifiedName) {
    Node compilationUnit = context.getCompilationUnit();
    if (compilationUnit == null) {
        return null;
    }
    Object nativeObj = getNativeNode(compilationUnit);
    if (!(nativeObj instanceof CompilationUnitDeclaration)) {
        return null;
    }
    CompilationUnitDeclaration ecjUnit = (CompilationUnitDeclaration) nativeObj;

    // Convert "foo.bar.Baz" into char[][] 'foo','bar','Baz' as required for
    // ECJ name lookup
    List<char[]> arrays = Lists.newArrayList();
    for (String segment : Splitter.on('.').split(fullyQualifiedName)) {
        arrays.add(segment.toCharArray());
    }
    char[][] compoundName = new char[arrays.size()][];
    for (int i = 0, n = arrays.size(); i < n; i++) {
        compoundName[i] = arrays.get(i);
    }

    Binding typeOrPackage = ecjUnit.scope.getTypeOrPackage(compoundName);
    if (typeOrPackage instanceof TypeBinding && !(typeOrPackage instanceof ProblemReferenceBinding)) {
        return new EcjResolvedClass((TypeBinding)typeOrPackage);
    }

    return null;
}
 
Example #21
Source File: SupportAnnotationDetector.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
@Override
public
List<Class<? extends Node>> getApplicableNodeTypes() {
    //noinspection unchecked
    return Arrays.<Class<? extends Node>>asList(
      MethodInvocation.class,
      ConstructorInvocation.class,
      EnumConstant.class);
}
 
Example #22
Source File: ViewHolderDetector.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
@Override
public boolean visitMethodInvocation(MethodInvocation node) {
    if (node.astOperand() != null) {
        String methodName = node.astName().astValue();
        if (methodName.equals(INFLATE) && node.astArguments().size() >= 1) {
            // See if we're inside a conditional
            boolean insideIf = false;
            Node p = node.getParent();
            while (p != null) {
                if (p instanceof If || p instanceof InlineIfExpression
                        || p instanceof Switch) {
                    insideIf = true;
                    mHaveConditional = true;
                    break;
                } else if (p == node) {
                    break;
                }
                p = p.getParent();
            }
            if (!insideIf) {
                // Rather than reporting immediately, we only report if we didn't
                // find any conditionally executed inflate statements in the method.
                // This is because there are cases where getView method is complicated
                // and inflates not just the top level layout but also children
                // of the view, and we don't want to flag these. (To be more accurate
                // should perform flow analysis and only report unconditional inflation
                // of layouts that wind up flowing to the return value; that requires
                // more work, and this simple heuristic is good enough for nearly all test
                // cases I've come across.
                if (mNodes == null) {
                    mNodes = Lists.newArrayList();
                }
                mNodes.add(node);
            }
        }
    }

    return super.visitMethodInvocation(node);
}
 
Example #23
Source File: EcjParser.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
@NonNull
@Override
public Location getLocation(@NonNull JavaContext context, @NonNull Node node) {
    lombok.ast.Position position = node.getPosition();
    return Location.create(context.file, context.getContents(),
            position.getStart(), position.getEnd());
}
 
Example #24
Source File: EcjParser.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
@Override
public Node parseJava(@NonNull JavaContext context) {
    String code = context.getContents();
    if (code == null) {
        return null;
    }

    CompilationUnitDeclaration unit = getParsedUnit(context, code);
    try {
        EcjTreeConverter converter = new EcjTreeConverter();
        converter.visit(code, unit);
        List<? extends Node> nodes = converter.getAll();

        if (nodes != null) {
            // There could be more than one node when there are errors; pick out the
            // compilation unit node
            for (Node node : nodes) {
                if (node instanceof lombok.ast.CompilationUnit) {
                    return node;
                }
            }
        }

        return null;
    } catch (Throwable t) {
        mClient.log(t, "Failed converting ECJ parse tree to Lombok for file %1$s",
                context.file.getPath());
        return null;
    }
}
 
Example #25
Source File: SupportAnnotationDetector.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
private static void reportTypeDef(@NonNull JavaContext context,
        @NonNull ResolvedAnnotation annotation, @NonNull Node argument,
        @Nullable Node errorNode, @NonNull Iterable<ResolvedAnnotation> allAnnotations) {
    Object allowed = annotation.getValue();
    if (allowed instanceof Object[]) {
        Object[] allowedValues = (Object[]) allowed;
        reportTypeDef(context, argument, errorNode, false, allowedValues, allAnnotations);
    }
}
 
Example #26
Source File: SQLiteDetector.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) {
    ResolvedNode resolved = context.resolve(node);
    if (!(resolved instanceof ResolvedMethod)) {
        return;
    }

    ResolvedMethod method = (ResolvedMethod) resolved;
    if (!method.getContainingClass().matches("android.database.sqlite.SQLiteDatabase")) {
        return;
    }

    // Try to resolve the String and look for STRING keys
    if (method.getArgumentCount() > 0
            && method.getArgumentType(0).matchesSignature(TYPE_STRING)
            && node.astArguments().size() == method.getArgumentCount()) {
        Iterator<Expression> iterator = node.astArguments().iterator();
        Node argument = iterator.next();
        String sql = ConstantEvaluator.evaluateString(context, argument, true);
        if (sql != null && (sql.startsWith("CREATE TABLE") || sql.startsWith("ALTER TABLE"))
                && sql.matches(".*\\bSTRING\\b.*")) {
            String message = "Using column type STRING; did you mean to use TEXT? "
                    + "(STRING is a numeric type and its value can be adjusted; for example,"
                    + "strings that look like integers can drop leading zeroes. See issue "
                    + "explanation for details.)";
            context.report(ISSUE, node, context.getLocation(node), message);
        }
    }
}
 
Example #27
Source File: SupportAnnotationDetector.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
private static void checkResult(@NonNull JavaContext context, @NonNull Node node,
        @NonNull ResolvedAnnotation annotation) {
    if (node.getParent() instanceof ExpressionStatement) {
        String methodName = JavaContext.getMethodName(node);
        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 != null && 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);
    }
}
 
Example #28
Source File: SupportAnnotationDetector.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
@Nullable
private static String getIntRangeError(
        @NonNull JavaContext context,
        @NonNull ResolvedAnnotation annotation,
        @NonNull Node argument) {
    Object object = ConstantEvaluator.evaluate(context, argument);
    if (!(object instanceof Number)) {
        return null;
    }
    long value = ((Number)object).longValue();
    long from = getLongAttribute(annotation, ATTR_FROM, Long.MIN_VALUE);
    long to = getLongAttribute(annotation, ATTR_TO, Long.MAX_VALUE);

    return getIntRangeError(value, from, to);
}
 
Example #29
Source File: SupportAnnotationDetector.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
private static boolean isMinusOne(@NonNull Node argument) {
    return argument instanceof UnaryExpression
            && ((UnaryExpression) argument).astOperator() == UnaryOperator.UNARY_MINUS
            && ((UnaryExpression) argument).astOperand() instanceof IntegralLiteral
            && ((IntegralLiteral) ((UnaryExpression) argument).astOperand()).astIntValue()
            == 1;
}
 
Example #30
Source File: SupportAnnotationDetector.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
private static void checkResourceType(
        @NonNull JavaContext context,
        @NonNull Node argument,
        @Nullable ResourceType expectedType) {
    List<ResourceType> actual = getResourceTypes(context, argument);
    if (actual == null && (!isNumber(argument) || isZero(argument) || isMinusOne(argument)) ) {
        return;
    } else if (actual != null && (expectedType == null
            || actual.contains(expectedType)
            || expectedType == DRAWABLE && (actual.contains(COLOR) || actual.contains(MIPMAP)))) {
        return;
    }

    String message;
    if (actual != null && actual.size() == 1 && actual.get(0) == COLOR_INT_MARKER_TYPE) {
        message = "Expected a color resource id (`R.color.`) but received an RGB integer";
    } else if (expectedType == COLOR_INT_MARKER_TYPE) {
        message = String.format("Should pass resolved color instead of resource id here: " +
                "`getResources().getColor(%1$s)`", argument.toString());
    } else if (expectedType != null) {
        message = String.format(
                "Expected resource of type %1$s", expectedType.getName());
    } else {
        message = "Expected resource identifier (`R`.type.`name`)";
    }
    context.report(RESOURCE_TYPE, argument, context.getLocation(argument), message);
}