Search in sources :

Example 26 with Description

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

the class WaitNotInLoop method matchMethodInvocation.

@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
    if (!matcher.matches(tree, state)) {
        return Description.NO_MATCH;
    }
    Description.Builder description = buildDescription(tree);
    MethodSymbol sym = ASTHelpers.getSymbol(tree);
    if (sym != null) {
        description.setMessage(String.format(MESSAGE_TEMPLATE, sym));
    }
    // mechanically, so we provide detailed instructions in the wiki content.
    if (!waitMethodWithTimeout.matches(tree, state)) {
        JCIf enclosingIf = ASTHelpers.findEnclosingNode(state.getPath().getParentPath(), JCIf.class);
        if (enclosingIf != null && enclosingIf.getElseStatement() == null) {
            CharSequence ifSource = state.getSourceForNode(enclosingIf);
            if (ifSource == null) {
                // Source isn't available, so we can't construct a fix
                return description.build();
            }
            String replacement = ifSource.toString().replaceFirst("if", "while");
            return description.addFix(SuggestedFix.replace(enclosingIf, replacement)).build();
        }
    }
    return description.build();
}
Also used : Description(com.google.errorprone.matchers.Description) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) JCIf(com.sun.tools.javac.tree.JCTree.JCIf)

Example 27 with Description

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

the class DescriptionBasedDiffTest method addImport.

@Test
public void addImport() {
    DescriptionBasedDiff diff = DescriptionBasedDiff.create(compilationUnit);
    diff.onDescribed(new Description(null, "message", SuggestedFix.builder().addImport("com.google.foo.Bar").build(), SeverityLevel.SUGGESTION));
    diff.applyDifferences(sourceFile);
    assertThat(sourceFile.getLines()).containsExactly("package foo.bar;", "import com.foo.Bar;", "import com.google.foo.Bar;", "", "class Foo {", "  public static void main(String[] args) {", "    System.out.println(\"foo\");", "  }", "}").inOrder();
}
Also used : DescriptionBasedDiff(com.google.errorprone.apply.DescriptionBasedDiff) Description(com.google.errorprone.matchers.Description) Test(org.junit.Test)

Example 28 with Description

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

the class HashtableContains method matchMethodInvocation.

@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
    if (!CONTAINS_MATCHER.matches(tree, state)) {
        return Description.NO_MATCH;
    }
    Description.Builder result = buildDescription(tree);
    // If the collection is not raw, try to figure out if the argument looks like a key
    // or a value.
    List<Type> tyargs = ASTHelpers.getReceiverType(tree).getTypeArguments();
    if (tyargs.size() == 2) {
        // map capture variables to their bounds, e.g. `? extends Number` -> `Number`
        Types types = state.getTypes();
        Type key = ASTHelpers.getUpperBound(tyargs.get(0), types);
        Type value = ASTHelpers.getUpperBound(tyargs.get(1), types);
        Type arg = ASTHelpers.getType(Iterables.getOnlyElement(tree.getArguments()));
        boolean valueShaped = types.isAssignable(arg, value);
        boolean keyShaped = types.isAssignable(arg, key);
        if (keyShaped && !valueShaped) {
            // definitely a key
            result.addFix(replaceMethodName(tree, state, "containsKey"));
            result.setMessage(String.format("contains() is a legacy method that is equivalent to containsValue(), but the " + "argument type '%s' looks like a key", key));
        } else if (valueShaped && !keyShaped) {
            // definitely a value
            result.addFix(replaceMethodName(tree, state, "containsValue"));
        } else if (valueShaped && keyShaped) {
            // ambiguous
            result.addFix(replaceMethodName(tree, state, "containsValue"));
            result.addFix(replaceMethodName(tree, state, "containsKey"));
            result.setMessage(String.format("contains() is a legacy method that is equivalent to containsValue(), but the " + "argument type '%s' could be a key or a value", key));
        } else {
            // this shouldn't have compiled!
            throw new AssertionError(String.format("unexpected argument to contains(): key: %s, value: %s, argument: %s", key, value, arg));
        }
    } else {
        result.addFix(replaceMethodName(tree, state, "containsValue"));
    }
    return result.build();
}
Also used : Types(com.sun.tools.javac.code.Types) Type(com.sun.tools.javac.code.Type) Description(com.google.errorprone.matchers.Description)

Example 29 with Description

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

the class InvalidPatternSyntax method matchMethodInvocation.

@Override
public Description matchMethodInvocation(MethodInvocationTree methodInvocationTree, VisitorState state) {
    if (!BAD_REGEX_USAGE.matches(methodInvocationTree, state)) {
        return Description.NO_MATCH;
    }
    // TODO: Suggest fixes for more situations.
    Description.Builder descriptionBuilder = buildDescription(methodInvocationTree);
    ExpressionTree arg = methodInvocationTree.getArguments().get(0);
    String value = (String) ((JCExpression) arg).type.constValue();
    String reasonInvalid = "";
    if (".".equals(value)) {
        descriptionBuilder.addFix(SuggestedFix.replace(arg, "\"\\\\.\""));
        reasonInvalid = "\".\" is a valid but useless regex";
    } else {
        try {
            Pattern.compile(value);
        } catch (PatternSyntaxException e) {
            reasonInvalid = e.getMessage();
        }
    }
    descriptionBuilder.setMessage(MESSAGE_BASE + reasonInvalid);
    return descriptionBuilder.build();
}
Also used : Description(com.google.errorprone.matchers.Description) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) ExpressionTree(com.sun.source.tree.ExpressionTree) PatternSyntaxException(java.util.regex.PatternSyntaxException)

Example 30 with Description

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

the class RestrictedApiChecker method matchMethodInvocation.

@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
    RestrictedApi annotation = ASTHelpers.getAnnotation(tree, RestrictedApi.class);
    if (annotation != null) {
        return checkRestriction(annotation, tree, state);
    }
    MethodSymbol methSymbol = ASTHelpers.getSymbol(tree);
    if (methSymbol == null) {
        // This shouldn't happen, but has. (See b/33758055)
        return Description.NO_MATCH;
    }
    // Try each super method for @RestrictedApi
    Optional<MethodSymbol> superWithRestrictedApi = ASTHelpers.findSuperMethods(methSymbol, state.getTypes()).stream().filter((t) -> ASTHelpers.hasAnnotation(t, RestrictedApi.class, state)).findFirst();
    if (!superWithRestrictedApi.isPresent()) {
        return Description.NO_MATCH;
    }
    return checkRestriction(ASTHelpers.getAnnotation(superWithRestrictedApi.get(), RestrictedApi.class), tree, state);
}
Also used : RestrictedApi(com.google.errorprone.annotations.RestrictedApi) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) TypeElement(javax.lang.model.element.TypeElement) NewClassTreeMatcher(com.google.errorprone.bugpatterns.BugChecker.NewClassTreeMatcher) ArrayList(java.util.ArrayList) MirroredTypesException(javax.lang.model.type.MirroredTypesException) VisitorState(com.google.errorprone.VisitorState) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) NewClassTree(com.sun.source.tree.NewClassTree) BugPattern(com.google.errorprone.BugPattern) Category(com.google.errorprone.BugPattern.Category) Matcher(com.google.errorprone.matchers.Matcher) Tree(com.sun.source.tree.Tree) JavacProcessingEnvironment(com.sun.tools.javac.processing.JavacProcessingEnvironment) Nullable(javax.annotation.Nullable) MethodInvocationTreeMatcher(com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher) RestrictedApi(com.google.errorprone.annotations.RestrictedApi) JCCompilationUnit(com.sun.tools.javac.tree.JCTree.JCCompilationUnit) List(java.util.List) TypeMirror(javax.lang.model.type.TypeMirror) Matchers(com.google.errorprone.matchers.Matchers) Description(com.google.errorprone.matchers.Description) Annotation(java.lang.annotation.Annotation) Optional(java.util.Optional) Pattern(java.util.regex.Pattern) SeverityLevel(com.google.errorprone.BugPattern.SeverityLevel) ASTHelpers(com.google.errorprone.util.ASTHelpers) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol)

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