Search in sources :

Example 31 with MethodTree

use of com.sun.source.tree.MethodTree in project tutorials by eugenp.

the class SampleJavacPlugin method init.

@Override
public void init(JavacTask task, String... args) {
    Context context = ((BasicJavacTask) task).getContext();
    task.addTaskListener(new TaskListener() {

        @Override
        public void started(TaskEvent e) {
        }

        @Override
        public void finished(TaskEvent e) {
            if (e.getKind() != TaskEvent.Kind.PARSE) {
                return;
            }
            e.getCompilationUnit().accept(new TreeScanner<Void, Void>() {

                @Override
                public Void visitMethod(MethodTree method, Void v) {
                    List<VariableTree> parametersToInstrument = method.getParameters().stream().filter(SampleJavacPlugin.this::shouldInstrument).collect(Collectors.toList());
                    if (!parametersToInstrument.isEmpty()) {
                        // There is a possible case that more than one argument is marked by @Positive,
                        // as the checks are added to the method's body beginning, we process parameters RTL
                        // to ensure correct order.
                        Collections.reverse(parametersToInstrument);
                        parametersToInstrument.forEach(p -> addCheck(method, p, context));
                    }
                    // hence, we want to proceed with method body AST as well.
                    return super.visitMethod(method, v);
                }
            }, null);
        }
    });
}
Also used : Context(com.sun.tools.javac.util.Context) MethodTree(com.sun.source.tree.MethodTree) BasicJavacTask(com.sun.tools.javac.api.BasicJavacTask) VariableTree(com.sun.source.tree.VariableTree)

Example 32 with MethodTree

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

the class AbstractExpectedExceptionChecker method scanBlock.

Description scanBlock(MethodTree tree, BlockTree block, VisitorState state) {
    PeekingIterator<? extends StatementTree> it = Iterators.peekingIterator(block.getStatements().iterator());
    while (it.hasNext() && !MATCHER.matches(it.peek(), state)) {
        it.next();
    }
    List<Tree> expectations = new ArrayList<>();
    while (it.hasNext() && MATCHER.matches(it.peek(), state)) {
        expectations.add(it.next());
    }
    if (expectations.isEmpty()) {
        return NO_MATCH;
    }
    Deque<StatementTree> suffix = new ArrayDeque<>();
    StatementTree failure = null;
    Iterators.addAll(suffix, it);
    if (!suffix.isEmpty() && FAIL_MATCHER.matches(suffix.peekLast(), state)) {
        failure = suffix.removeLast();
    }
    return handleMatch(tree, state, expectations, ImmutableList.copyOf(suffix), failure);
}
Also used : ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) StatementTree(com.sun.source.tree.StatementTree) ArrayList(java.util.ArrayList) MethodTree(com.sun.source.tree.MethodTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) JCTree(com.sun.tools.javac.tree.JCTree) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) BlockTree(com.sun.source.tree.BlockTree) StatementTree(com.sun.source.tree.StatementTree) ArrayDeque(java.util.ArrayDeque)

Example 33 with MethodTree

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

the class AbstractMustBeClosedChecker method checkClosed.

private Description checkClosed(ExpressionTree tree, VisitorState state) {
    MethodTree callerMethodTree = enclosingMethod(state);
    TreePath path = state.getPath();
    OUTER: while (true) {
        TreePath prev = path;
        path = path.getParentPath();
        switch(path.getLeaf().getKind()) {
            case RETURN:
                if (callerMethodTree != null) {
                    // expression or anonymous class.
                    if (HAS_MUST_BE_CLOSED_ANNOTATION.matches(callerMethodTree, state)) {
                        // enforced.
                        return NO_MATCH;
                    }
                    // enforced. Suggest fixing this by annotating the caller method.
                    return buildDescription(tree).addFix(SuggestedFix.builder().prefixWith(callerMethodTree, "@MustBeClosed\n").addImport(MustBeClosed.class.getCanonicalName()).build()).build();
                }
                break;
            case CONDITIONAL_EXPRESSION:
                ConditionalExpressionTree conditionalExpressionTree = (ConditionalExpressionTree) path.getLeaf();
                if (conditionalExpressionTree.getTrueExpression().equals(prev.getLeaf()) || conditionalExpressionTree.getFalseExpression().equals(prev.getLeaf())) {
                    continue OUTER;
                }
                break;
            case MEMBER_SELECT:
                MemberSelectTree memberSelectTree = (MemberSelectTree) path.getLeaf();
                if (memberSelectTree.getExpression().equals(prev.getLeaf())) {
                    Type type = getType(memberSelectTree);
                    Symbol sym = getSymbol(memberSelectTree);
                    Type streamType = state.getTypeFromString(Stream.class.getName());
                    if (isSubtype(sym.enclClass().asType(), streamType, state) && isSameType(type.getReturnType(), streamType, state)) {
                        // skip enclosing method invocation
                        path = path.getParentPath();
                        continue OUTER;
                    }
                }
                break;
            case VARIABLE:
                Symbol sym = getSymbol(path.getLeaf());
                if (sym instanceof VarSymbol) {
                    VarSymbol var = (VarSymbol) sym;
                    if (var.getKind() == ElementKind.RESOURCE_VARIABLE || tryFinallyClose(var, path, state)) {
                        return NO_MATCH;
                    }
                }
                break;
            default:
                break;
        }
        // The constructor or method invocation does not occur within the resource variable
        // initializer of a try-with-resources statement.
        Description.Builder description = buildDescription(tree);
        addFix(description, tree, state);
        return description.build();
    }
}
Also used : Matchers.toType(com.google.errorprone.matchers.Matchers.toType) ASTHelpers.getType(com.google.errorprone.util.ASTHelpers.getType) ASTHelpers.isSameType(com.google.errorprone.util.ASTHelpers.isSameType) Type(com.sun.tools.javac.code.Type) TreePath(com.sun.source.util.TreePath) MethodTree(com.sun.source.tree.MethodTree) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) ASTHelpers.getSymbol(com.google.errorprone.util.ASTHelpers.getSymbol) Symbol(com.sun.tools.javac.code.Symbol) MemberSelectTree(com.sun.source.tree.MemberSelectTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) MustBeClosed(com.google.errorprone.annotations.MustBeClosed) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol)

Example 34 with MethodTree

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

the class ByteBufferBackingArray method matchMethodInvocation.

@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
    if (!BYTE_BUFFER_ARRAY_MATCHER.matches(tree, state)) {
        return Description.NO_MATCH;
    }
    // Checks for validating use on method call chain.
    ExpressionTree receiver = tree;
    do {
        receiver = ASTHelpers.getReceiver(receiver);
        if (isValidInitializerOrNotAByteBuffer(receiver, state)) {
            return Description.NO_MATCH;
        }
    } while (receiver instanceof MethodInvocationTree);
    Symbol bufferSymbol = ASTHelpers.getSymbol(receiver);
    // Checks for validating use on method scope.
    if (bufferSymbol.owner instanceof MethodSymbol) {
        MethodTree enclosingMethod = ASTHelpers.findMethod((MethodSymbol) bufferSymbol.owner, state);
        if (enclosingMethod == null || ValidByteBufferArrayScanner.scan(enclosingMethod, state, bufferSymbol)) {
            return Description.NO_MATCH;
        }
    }
    // Checks for validating use on fields.
    if (bufferSymbol.owner instanceof ClassSymbol) {
        ClassTree enclosingClass = ASTHelpers.findClass((ClassSymbol) bufferSymbol.owner, state);
        if (enclosingClass == null) {
            return Description.NO_MATCH;
        }
        Optional<? extends Tree> validMemberTree = enclosingClass.getMembers().stream().filter(memberTree -> ValidByteBufferArrayScanner.scan(memberTree, state, bufferSymbol)).findFirst();
        if (validMemberTree.isPresent()) {
            return Description.NO_MATCH;
        }
    }
    return describeMatch(tree);
}
Also used : Matchers.anyOf(com.google.errorprone.matchers.Matchers.anyOf) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) MethodTree(com.sun.source.tree.MethodTree) MethodMatchers.instanceMethod(com.google.errorprone.matchers.method.MethodMatchers.instanceMethod) VariableTree(com.sun.source.tree.VariableTree) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) ByteBuffer(java.nio.ByteBuffer) VisitorState(com.google.errorprone.VisitorState) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AssignmentTree(com.sun.source.tree.AssignmentTree) BugPattern(com.google.errorprone.BugPattern) JDK(com.google.errorprone.BugPattern.Category.JDK) Matcher(com.google.errorprone.matchers.Matcher) Matchers.isSameType(com.google.errorprone.matchers.Matchers.isSameType) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) MethodInvocationTreeMatcher(com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher) Matchers.staticMethod(com.google.errorprone.matchers.Matchers.staticMethod) ExpressionTree(com.sun.source.tree.ExpressionTree) Symbol(com.sun.tools.javac.code.Symbol) TreeScanner(com.sun.source.util.TreeScanner) Description(com.google.errorprone.matchers.Description) Optional(java.util.Optional) MoreObjects.firstNonNull(com.google.common.base.MoreObjects.firstNonNull) WARNING(com.google.errorprone.BugPattern.SeverityLevel.WARNING) ASTHelpers(com.google.errorprone.util.ASTHelpers) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) MethodTree(com.sun.source.tree.MethodTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) Symbol(com.sun.tools.javac.code.Symbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) ClassTree(com.sun.source.tree.ClassTree) ExpressionTree(com.sun.source.tree.ExpressionTree)

Example 35 with MethodTree

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

the class DataFlow method findEnclosingMethodOrLambdaOrInitializer.

// TODO(user), remove once we merge jdk8 specific's with core
private static <T> TreePath findEnclosingMethodOrLambdaOrInitializer(TreePath path) {
    while (path != null) {
        if (path.getLeaf() instanceof MethodTree) {
            return path;
        }
        TreePath parent = path.getParentPath();
        if (parent != null) {
            if (parent.getLeaf() instanceof ClassTree) {
                if (path.getLeaf() instanceof BlockTree) {
                    // this is a class or instance initializer block
                    return path;
                }
                if (path.getLeaf() instanceof VariableTree && ((VariableTree) path.getLeaf()).getInitializer() != null) {
                    // this is a field with an inline initializer
                    return path;
                }
            }
            if (parent.getLeaf() instanceof LambdaExpressionTree) {
                return parent;
            }
        }
        path = parent;
    }
    return null;
}
Also used : LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) TreePath(com.sun.source.util.TreePath) MethodTree(com.sun.source.tree.MethodTree) ClassTree(com.sun.source.tree.ClassTree) VariableTree(com.sun.source.tree.VariableTree) BlockTree(com.sun.source.tree.BlockTree)

Aggregations

MethodTree (com.sun.source.tree.MethodTree)91 Tree (com.sun.source.tree.Tree)46 ClassTree (com.sun.source.tree.ClassTree)45 VariableTree (com.sun.source.tree.VariableTree)39 ExpressionTree (com.sun.source.tree.ExpressionTree)36 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)28 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)22 LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)20 TreePath (com.sun.source.util.TreePath)20 IdentifierTree (com.sun.source.tree.IdentifierTree)19 NewClassTree (com.sun.source.tree.NewClassTree)19 ReturnTree (com.sun.source.tree.ReturnTree)18 ExecutableElement (javax.lang.model.element.ExecutableElement)17 Symbol (com.sun.tools.javac.code.Symbol)16 ArrayList (java.util.ArrayList)15 AssignmentTree (com.sun.source.tree.AssignmentTree)14 BlockTree (com.sun.source.tree.BlockTree)14 CompilationUnitTree (com.sun.source.tree.CompilationUnitTree)14 ConditionalExpressionTree (com.sun.source.tree.ConditionalExpressionTree)14 MemberSelectTree (com.sun.source.tree.MemberSelectTree)14