Search in sources :

Example 21 with Description

use of com.google.errorprone.matchers.Description in project error-prone by google.

the class SelfEquals method matchMethodInvocation.

@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
    if (ASSERTION.matches(state.getPath().getParentPath().getLeaf(), state)) {
        return NO_MATCH;
    }
    List<? extends ExpressionTree> args = tree.getArguments();
    ExpressionTree toReplace;
    if (INSTANCE_MATCHER.matches(tree, state)) {
        toReplace = args.get(0);
    } else if (STATIC_MATCHER.matches(tree, state)) {
        if (args.get(0).getKind() == Kind.IDENTIFIER && args.get(1).getKind() != Kind.IDENTIFIER) {
            toReplace = args.get(0);
        } else {
            toReplace = args.get(1);
        }
    } else {
        return NO_MATCH;
    }
    Description.Builder description = buildDescription(tree);
    Fix fix = fieldFix(toReplace, state);
    if (fix != null) {
        description.addFix(fix);
    }
    return description.build();
}
Also used : Description(com.google.errorprone.matchers.Description) Fix(com.google.errorprone.fixes.Fix) ProvidesFix(com.google.errorprone.BugPattern.ProvidesFix) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) ExpressionTree(com.sun.source.tree.ExpressionTree)

Example 22 with Description

use of com.google.errorprone.matchers.Description in project error-prone by google.

the class ModifyingCollectionWithItself method describe.

/**
 * We expect that the lhs is a field and the rhs is an identifier, specifically a parameter to the
 * method. We base our suggested fixes on this expectation.
 *
 * <p>Case 1: If lhs is a field and rhs is an identifier, find a method parameter of the same type
 * and similar name and suggest it as the rhs. (Guess that they have misspelled the identifier.)
 *
 * <p>Case 2: If lhs is a field and rhs is not an identifier, find a method parameter of the same
 * type and similar name and suggest it as the rhs.
 *
 * <p>Case 3: If lhs is not a field and rhs is an identifier, find a class field of the same type
 * and similar name and suggest it as the lhs.
 *
 * <p>Case 4: Otherwise replace with literal meaning of functionality
 */
private Description describe(MethodInvocationTree methodInvocationTree, VisitorState state) {
    ExpressionTree receiver = ASTHelpers.getReceiver(methodInvocationTree);
    List<? extends ExpressionTree> arguments = methodInvocationTree.getArguments();
    ExpressionTree argument;
    // .addAll(int, Collection); for the true case
    argument = arguments.size() == 2 ? arguments.get(1) : arguments.get(0);
    Description.Builder builder = buildDescription(methodInvocationTree);
    for (Fix fix : buildFixes(methodInvocationTree, state, receiver, argument)) {
        builder.addFix(fix);
    }
    return builder.build();
}
Also used : Description(com.google.errorprone.matchers.Description) Fix(com.google.errorprone.fixes.Fix) ProvidesFix(com.google.errorprone.BugPattern.ProvidesFix) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) ExpressionTree(com.sun.source.tree.ExpressionTree)

Example 23 with Description

use of com.google.errorprone.matchers.Description in project error-prone by google.

the class MultipleParallelOrSequentialCalls method matchMethodInvocation.

@Override
public Description matchMethodInvocation(MethodInvocationTree t, VisitorState state) {
    if (STREAM.matches(t, state) || PARALLELSTREAM.matches(t, state)) {
        int appropriateAmount = STREAM.matches(t, state) ? 1 : 0;
        SuggestedFix.Builder builder = SuggestedFix.builder();
        TreePath pathToMet = ASTHelpers.findPathFromEnclosingNodeToTopLevel(state.getPath(), MethodInvocationTree.class);
        // counts how many instances of parallel / sequential
        int count = 0;
        String toReplace = "empty";
        while (pathToMet != null) {
            MethodInvocationTree methodInvocationTree = (MethodInvocationTree) pathToMet.getLeaf();
            // this check makes it so that we stop iterating up once it's done
            if (methodInvocationTree.getArguments().stream().map(m -> m.toString()).anyMatch(m -> m.contains(t.toString()))) {
                break;
            }
            if (methodInvocationTree.getMethodSelect() instanceof MemberSelectTree) {
                MemberSelectTree memberSelectTree = (MemberSelectTree) methodInvocationTree.getMethodSelect();
                String memberSelectIdentifier = memberSelectTree.getIdentifier().toString();
                // checks for the first instance of parallel / sequential
                if (toReplace.equals("empty") && (memberSelectIdentifier.equals("parallel") || memberSelectIdentifier.equals("sequential"))) {
                    toReplace = memberSelectIdentifier.equals("parallel") ? "parallel" : "sequential";
                }
                // immediately removes any instances of the appropriate string
                if (memberSelectIdentifier.equals(toReplace)) {
                    int endOfExpression = state.getEndPosition(memberSelectTree.getExpression());
                    builder.replace(endOfExpression, state.getEndPosition(methodInvocationTree), "");
                    count++;
                }
            }
            pathToMet = ASTHelpers.findPathFromEnclosingNodeToTopLevel(pathToMet, MethodInvocationTree.class);
        }
        // use the builder's replacements and add a postfix
        if (count > appropriateAmount) {
            // parallel stream doesn't need a postfix
            if (appropriateAmount == 1) {
                builder.postfixWith(t, "." + toReplace + "()");
            }
            return describeMatch(t, builder.build());
        }
    }
    return Description.NO_MATCH;
}
Also used : MethodInvocationTreeMatcher(com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher) TreePath(com.sun.source.util.TreePath) MemberSelectTree(com.sun.source.tree.MemberSelectTree) Matchers.instanceMethod(com.google.errorprone.matchers.Matchers.instanceMethod) VisitorState(com.google.errorprone.VisitorState) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) Description(com.google.errorprone.matchers.Description) BugPattern(com.google.errorprone.BugPattern) WARNING(com.google.errorprone.BugPattern.SeverityLevel.WARNING) ProvidesFix(com.google.errorprone.BugPattern.ProvidesFix) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) JDK(com.google.errorprone.BugPattern.Category.JDK) ASTHelpers(com.google.errorprone.util.ASTHelpers) MethodNameMatcher(com.google.errorprone.matchers.method.MethodMatchers.MethodNameMatcher) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) TreePath(com.sun.source.util.TreePath) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree)

Example 24 with Description

use of com.google.errorprone.matchers.Description in project error-prone by google.

the class UnnecessarySetDefault method matchMethodInvocation.

@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
    if (!SET_DEFAULT.matches(tree, state)) {
        return NO_MATCH;
    }
    Type type = ASTHelpers.getType(tree.getArguments().get(0));
    if (type == null) {
        return NO_MATCH;
    }
    Type classType = state.getTypes().asSuper(type, state.getSymtab().classType.asElement());
    if (classType == null || classType.getTypeArguments().isEmpty()) {
        return NO_MATCH;
    }
    String defaultTypeName = getOnlyElement(classType.getTypeArguments()).asElement().getQualifiedName().toString();
    if (!DEFAULTS.containsKey(defaultTypeName)) {
        return NO_MATCH;
    }
    Matcher<ExpressionTree> defaultType = DEFAULTS.get(defaultTypeName);
    if (!defaultType.matches(tree.getArguments().get(1), state)) {
        return NO_MATCH;
    }
    Description.Builder description = buildDescription(tree);
    ExpressionTree receiver = ASTHelpers.getReceiver(tree);
    Tree ancestor = state.getPath().getParentPath().getLeaf();
    if (ancestor instanceof ExpressionStatementTree) {
        description.addFix(SuggestedFix.delete(ancestor));
    } else if (receiver != null) {
        description.addFix(SuggestedFix.replace(state.getEndPosition(receiver), state.getEndPosition(tree), ""));
    }
    return description.build();
}
Also used : Type(com.sun.tools.javac.code.Type) Description(com.google.errorprone.matchers.Description) ExpressionTree(com.sun.source.tree.ExpressionTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree)

Example 25 with Description

use of com.google.errorprone.matchers.Description in project error-prone by google.

the class OverrideThrowableToString method matchClass.

@Override
public Description matchClass(ClassTree classTree, VisitorState visitorState) {
    Symbol throwableClass = visitorState.getSymbolFromString("java.lang.Throwable");
    if (Objects.equals(ASTHelpers.getSymbol(classTree.getExtendsClause()), throwableClass)) {
        Optional<? extends Tree> methodTree = classTree.getMembers().stream().filter(m -> m instanceof MethodTree && ((MethodTree) m).getName().contentEquals("toString")).findFirst();
        if (methodTree.isPresent()) {
            SuggestedFix.Builder builder = SuggestedFix.builder();
            MethodTree tree = (MethodTree) methodTree.get();
            if (!tree.getParameters().isEmpty()) {
                return Description.NO_MATCH;
            }
            String newTree = tree.getModifiers().toString().replaceAll("@Override[(][)]", "@Override") + "String getMessage()\n" + visitorState.getSourceForNode(tree.getBody());
            builder.replace(tree, newTree);
            return describeMatch(classTree, builder.build());
        }
    }
    return Description.NO_MATCH;
}
Also used : ClassTreeMatcher(com.google.errorprone.bugpatterns.BugChecker.ClassTreeMatcher) MethodTree(com.sun.source.tree.MethodTree) Symbol(com.sun.tools.javac.code.Symbol) Objects(java.util.Objects) VisitorState(com.google.errorprone.VisitorState) Description(com.google.errorprone.matchers.Description) BugPattern(com.google.errorprone.BugPattern) Optional(java.util.Optional) WARNING(com.google.errorprone.BugPattern.SeverityLevel.WARNING) ProvidesFix(com.google.errorprone.BugPattern.ProvidesFix) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) JDK(com.google.errorprone.BugPattern.Category.JDK) Tree(com.sun.source.tree.Tree) ASTHelpers(com.google.errorprone.util.ASTHelpers) ClassTree(com.sun.source.tree.ClassTree) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) MethodTree(com.sun.source.tree.MethodTree) Symbol(com.sun.tools.javac.code.Symbol)

Aggregations

Description (com.google.errorprone.matchers.Description)56 Tree (com.sun.source.tree.Tree)23 VisitorState (com.google.errorprone.VisitorState)22 BugPattern (com.google.errorprone.BugPattern)21 SuggestedFix (com.google.errorprone.fixes.SuggestedFix)20 ASTHelpers (com.google.errorprone.util.ASTHelpers)20 WARNING (com.google.errorprone.BugPattern.SeverityLevel.WARNING)17 ExpressionTree (com.sun.source.tree.ExpressionTree)17 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)17 JDK (com.google.errorprone.BugPattern.Category.JDK)16 Symbol (com.sun.tools.javac.code.Symbol)16 ProvidesFix (com.google.errorprone.BugPattern.ProvidesFix)14 Type (com.sun.tools.javac.code.Type)14 DescriptionBasedDiff (com.google.errorprone.apply.DescriptionBasedDiff)11 VariableTree (com.sun.source.tree.VariableTree)11 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)11 NO_MATCH (com.google.errorprone.matchers.Description.NO_MATCH)10 ClassTree (com.sun.source.tree.ClassTree)10 Optional (java.util.Optional)10 MethodTree (com.sun.source.tree.MethodTree)9