Search in sources :

Example 76 with IdentifierTree

use of com.sun.source.tree.IdentifierTree in project error-prone by google.

the class MissingCasesInEnumSwitch method matchSwitch.

@Override
public Description matchSwitch(SwitchTree tree, VisitorState state) {
    Type switchType = ASTHelpers.getType(tree.getExpression());
    if (switchType.asElement().getKind() != ElementKind.ENUM) {
        return Description.NO_MATCH;
    }
    // default case is present
    if (tree.getCases().stream().anyMatch(c -> c.getExpression() == null)) {
        return Description.NO_MATCH;
    }
    ImmutableSet<String> handled = tree.getCases().stream().map(CaseTree::getExpression).filter(IdentifierTree.class::isInstance).map(e -> ((IdentifierTree) e).getName().toString()).collect(toImmutableSet());
    Set<String> unhandled = Sets.difference(ASTHelpers.enumValues(switchType.asElement()), handled);
    if (unhandled.isEmpty()) {
        return Description.NO_MATCH;
    }
    return buildDescription(tree).setMessage(buildMessage(unhandled)).build();
}
Also used : ImmutableSet(com.google.common.collect.ImmutableSet) ElementKind(javax.lang.model.element.ElementKind) Set(java.util.Set) CaseTree(com.sun.source.tree.CaseTree) SwitchTreeMatcher(com.google.errorprone.bugpatterns.BugChecker.SwitchTreeMatcher) SwitchTree(com.sun.source.tree.SwitchTree) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) VisitorState(com.google.errorprone.VisitorState) Description(com.google.errorprone.matchers.Description) IdentifierTree(com.sun.source.tree.IdentifierTree) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) BugPattern(com.google.errorprone.BugPattern) WARNING(com.google.errorprone.BugPattern.SeverityLevel.WARNING) JDK(com.google.errorprone.BugPattern.Category.JDK) ASTHelpers(com.google.errorprone.util.ASTHelpers) Type(com.sun.tools.javac.code.Type) Type(com.sun.tools.javac.code.Type) IdentifierTree(com.sun.source.tree.IdentifierTree)

Example 77 with IdentifierTree

use of com.sun.source.tree.IdentifierTree in project error-prone by google.

the class NestedInstanceOfConditions method matchIf.

@Override
public Description matchIf(IfTree ifTree, VisitorState visitorState) {
    ExpressionTree expressionTree = stripParentheses(ifTree.getCondition());
    if (expressionTree instanceof InstanceOfTree) {
        InstanceOfTree instanceOfTree = (InstanceOfTree) expressionTree;
        if (!(instanceOfTree.getExpression() instanceof IdentifierTree)) {
            return Description.NO_MATCH;
        }
        Matcher<Tree> assignmentTreeMatcher = new AssignmentTreeMatcher(instanceOfTree.getExpression());
        Matcher<Tree> containsAssignmentTreeMatcher = contains(assignmentTreeMatcher);
        if (containsAssignmentTreeMatcher.matches(ifTree, visitorState)) {
            return Description.NO_MATCH;
        }
        // set expression and type to look for in matcher
        Matcher<Tree> nestedInstanceOfMatcher = new NestedInstanceOfMatcher(instanceOfTree.getExpression(), instanceOfTree.getType());
        Matcher<Tree> containsNestedInstanceOfMatcher = contains(nestedInstanceOfMatcher);
        if (containsNestedInstanceOfMatcher.matches(ifTree.getThenStatement(), visitorState)) {
            return describeMatch(ifTree);
        }
    }
    return Description.NO_MATCH;
}
Also used : InstanceOfTree(com.sun.source.tree.InstanceOfTree) ExpressionTree(com.sun.source.tree.ExpressionTree) IdentifierTree(com.sun.source.tree.IdentifierTree) IfTree(com.sun.source.tree.IfTree) ExpressionTree(com.sun.source.tree.ExpressionTree) AssignmentTree(com.sun.source.tree.AssignmentTree) IdentifierTree(com.sun.source.tree.IdentifierTree) Tree(com.sun.source.tree.Tree) InstanceOfTree(com.sun.source.tree.InstanceOfTree)

Example 78 with IdentifierTree

use of com.sun.source.tree.IdentifierTree in project error-prone by google.

the class MyCustomCheck method matchMethodInvocation.

@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
    if (!PRINT_METHOD.matches(tree, state)) {
        return NO_MATCH;
    }
    Symbol base = tree.getMethodSelect().accept(new TreeScanner<Symbol, Void>() {

        @Override
        public Symbol visitIdentifier(IdentifierTree node, Void unused) {
            return ASTHelpers.getSymbol(node);
        }

        @Override
        public Symbol visitMemberSelect(MemberSelectTree node, Void unused) {
            return super.visitMemberSelect(node, null);
        }
    }, null);
    if (!Objects.equals(base, state.getSymtab().systemType.tsym)) {
        return NO_MATCH;
    }
    ExpressionTree arg = Iterables.getOnlyElement(tree.getArguments());
    if (!STRING_FORMAT.matches(arg, state)) {
        return NO_MATCH;
    }
    List<? extends ExpressionTree> formatArgs = ((MethodInvocationTree) arg).getArguments();
    return describeMatch(tree, SuggestedFix.builder().replace(((JCTree) tree).getStartPosition(), ((JCTree) formatArgs.get(0)).getStartPosition(), "System.err.printf(").replace(state.getEndPosition((JCTree) getLast(formatArgs)), state.getEndPosition((JCTree) tree), ")").build());
}
Also used : Symbol(com.sun.tools.javac.code.Symbol) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) IdentifierTree(com.sun.source.tree.IdentifierTree) ExpressionTree(com.sun.source.tree.ExpressionTree) JCTree(com.sun.tools.javac.tree.JCTree)

Example 79 with IdentifierTree

use of com.sun.source.tree.IdentifierTree in project error-prone by google.

the class UnnecessaryDefaultInEnumSwitch method matchSwitch.

@Override
public Description matchSwitch(SwitchTree tree, VisitorState state) {
    TypeSymbol switchType = ((JCSwitch) tree).getExpression().type.tsym;
    if (switchType.getKind() != ElementKind.ENUM) {
        return NO_MATCH;
    }
    CaseTree caseBeforeDefault = null;
    CaseTree defaultCase = null;
    for (CaseTree caseTree : tree.getCases()) {
        if (caseTree.getExpression() == null) {
            defaultCase = caseTree;
            break;
        } else {
            caseBeforeDefault = caseTree;
        }
    }
    if (defaultCase == null) {
        return NO_MATCH;
    }
    Set<String> handledCases = tree.getCases().stream().map(CaseTree::getExpression).filter(IdentifierTree.class::isInstance).map(p -> ((IdentifierTree) p).getName().toString()).collect(toImmutableSet());
    if (!ASTHelpers.enumValues(switchType).equals(handledCases)) {
        return NO_MATCH;
    }
    Fix fix;
    List<? extends StatementTree> defaultStatements = defaultCase.getStatements();
    if (trivialDefault(defaultStatements)) {
        // deleting `default:` or `default: break;` is a no-op
        fix = SuggestedFix.delete(defaultCase);
    } else {
        String defaultSource = state.getSourceCode().subSequence(((JCTree) defaultStatements.get(0)).getStartPosition(), state.getEndPosition(getLast(defaultStatements))).toString();
        String initialComments = comments(state, defaultCase, defaultStatements);
        if (!canCompleteNormally(tree)) {
            // if the switch statement cannot complete normally, then deleting the default
            // and moving its statements to after the switch statement is a no-op
            fix = SuggestedFix.builder().delete(defaultCase).postfixWith(tree, initialComments + defaultSource).build();
        } else {
            // and the code is unreachable -- so use (2) as the strategy.  Otherwise, use (1).
            if (!SuggestedFixes.compilesWithFix(SuggestedFix.delete(defaultCase), state)) {
                // case (3)
                return NO_MATCH;
            }
            if (!canCompleteNormally(caseBeforeDefault)) {
                // case (2) -- If the case before the default can't complete normally,
                // it's OK to to delete the default.
                fix = SuggestedFix.delete(defaultCase);
            } else {
                // case (1) -- If it can complete, we need to merge the default into it.
                fix = SuggestedFix.builder().delete(defaultCase).postfixWith(caseBeforeDefault, initialComments + defaultSource).build();
            }
        }
    }
    return describeMatch(defaultCase, fix);
}
Also used : SuggestedFixes(com.google.errorprone.fixes.SuggestedFixes) SwitchTreeMatcher(com.google.errorprone.bugpatterns.BugChecker.SwitchTreeMatcher) VisitorState(com.google.errorprone.VisitorState) JCSwitch(com.sun.tools.javac.tree.JCTree.JCSwitch) IdentifierTree(com.sun.source.tree.IdentifierTree) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) BugPattern(com.google.errorprone.BugPattern) JDK(com.google.errorprone.BugPattern.Category.JDK) Fix(com.google.errorprone.fixes.Fix) Tree(com.sun.source.tree.Tree) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) ElementKind(javax.lang.model.element.ElementKind) Set(java.util.Set) Iterables.getLast(com.google.common.collect.Iterables.getLast) Iterables.getOnlyElement(com.google.common.collect.Iterables.getOnlyElement) NO_MATCH(com.google.errorprone.matchers.Description.NO_MATCH) CaseTree(com.sun.source.tree.CaseTree) JCTree(com.sun.tools.javac.tree.JCTree) SwitchTree(com.sun.source.tree.SwitchTree) List(java.util.List) Description(com.google.errorprone.matchers.Description) StatementTree(com.sun.source.tree.StatementTree) WARNING(com.google.errorprone.BugPattern.SeverityLevel.WARNING) ProvidesFix(com.google.errorprone.BugPattern.ProvidesFix) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) Reachability.canCompleteNormally(com.google.errorprone.util.Reachability.canCompleteNormally) ASTHelpers(com.google.errorprone.util.ASTHelpers) CaseTree(com.sun.source.tree.CaseTree) JCSwitch(com.sun.tools.javac.tree.JCTree.JCSwitch) Fix(com.google.errorprone.fixes.Fix) ProvidesFix(com.google.errorprone.BugPattern.ProvidesFix) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) IdentifierTree(com.sun.source.tree.IdentifierTree) JCTree(com.sun.tools.javac.tree.JCTree) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol)

Example 80 with IdentifierTree

use of com.sun.source.tree.IdentifierTree in project error-prone by google.

the class ConstructorLeaksThis method traverse.

@Override
protected void traverse(Tree tree, VisitorState state) {
    ClassSymbol thisClass = ASTHelpers.getSymbol(state.findEnclosing(ClassTree.class));
    tree.accept(new TreeScanner<Void, Void>() {

        @Override
        public Void visitIdentifier(IdentifierTree node, Void unused) {
            checkForThis(node, node.getName(), thisClass, state);
            return super.visitIdentifier(node, null);
        }

        @Override
        public Void visitMemberSelect(MemberSelectTree node, Void unused) {
            checkForThis(node, node.getIdentifier(), thisClass, state);
            // Don't examine this.foo or MyClass.this.foo
            ExpressionTree left = node.getExpression();
            if ((left instanceof IdentifierTree && ((IdentifierTree) left).getName().contentEquals("this")) || (left instanceof MemberSelectTree && ((MemberSelectTree) left).getIdentifier().contentEquals("this"))) {
                return null;
            }
            return super.visitMemberSelect(node, unused);
        }

        @Override
        public Void visitAssignment(AssignmentTree node, Void unused) {
            scan(node.getExpression(), null);
            // ignore references to 'this' in the LHS of assignments
            return null;
        }
    }, null);
}
Also used : ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) MemberSelectTree(com.sun.source.tree.MemberSelectTree) ClassTree(com.sun.source.tree.ClassTree) IdentifierTree(com.sun.source.tree.IdentifierTree) ExpressionTree(com.sun.source.tree.ExpressionTree) AssignmentTree(com.sun.source.tree.AssignmentTree)

Aggregations

IdentifierTree (com.sun.source.tree.IdentifierTree)82 ExpressionTree (com.sun.source.tree.ExpressionTree)41 MemberSelectTree (com.sun.source.tree.MemberSelectTree)36 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)28 Element (javax.lang.model.element.Element)24 Tree (com.sun.source.tree.Tree)21 ExecutableElement (javax.lang.model.element.ExecutableElement)18 VariableTree (com.sun.source.tree.VariableTree)17 TypeElement (javax.lang.model.element.TypeElement)16 MethodTree (com.sun.source.tree.MethodTree)13 VariableElement (javax.lang.model.element.VariableElement)13 ClassTree (com.sun.source.tree.ClassTree)12 ConditionalExpressionTree (com.sun.source.tree.ConditionalExpressionTree)11 ArrayAccessTree (com.sun.source.tree.ArrayAccessTree)10 NewClassTree (com.sun.source.tree.NewClassTree)10 AssignmentTree (com.sun.source.tree.AssignmentTree)9 BinaryTree (com.sun.source.tree.BinaryTree)9 LiteralTree (com.sun.source.tree.LiteralTree)8 StatementTree (com.sun.source.tree.StatementTree)8 Symbol (com.sun.tools.javac.code.Symbol)8