Search in sources :

Example 11 with StatementTree

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

the class UTemplater method createTemplate.

/**
 * Returns a template based on a method. One-line methods starting with a {@code return} statement
 * are guessed to be expression templates, and all other methods are guessed to be block
 * templates.
 */
public static Template<?> createTemplate(Context context, MethodTree decl) {
    MethodSymbol declSym = ASTHelpers.getSymbol(decl);
    ImmutableClassToInstanceMap<Annotation> annotations = UTemplater.annotationMap(declSym);
    ImmutableMap<String, VarSymbol> freeExpressionVars = freeExpressionVariables(decl);
    Context subContext = new SubContext(context);
    final UTemplater templater = new UTemplater(freeExpressionVars, subContext);
    ImmutableMap<String, UType> expressionVarTypes = ImmutableMap.copyOf(Maps.transformValues(freeExpressionVars, (VarSymbol sym) -> templater.template(sym.type)));
    UType genericType = templater.template(declSym.type);
    List<UTypeVar> typeParameters;
    UMethodType methodType;
    if (genericType instanceof UForAll) {
        UForAll forAllType = (UForAll) genericType;
        typeParameters = forAllType.getTypeVars();
        methodType = (UMethodType) forAllType.getQuantifiedType();
    } else if (genericType instanceof UMethodType) {
        typeParameters = ImmutableList.of();
        methodType = (UMethodType) genericType;
    } else {
        throw new IllegalArgumentException("Expected genericType to be either a ForAll or a UMethodType, but was " + genericType);
    }
    List<? extends StatementTree> bodyStatements = decl.getBody().getStatements();
    if (bodyStatements.size() == 1 && Iterables.getOnlyElement(bodyStatements).getKind() == Kind.RETURN && context.get(REQUIRE_BLOCK_KEY) == null) {
        ExpressionTree expression = ((ReturnTree) Iterables.getOnlyElement(bodyStatements)).getExpression();
        return ExpressionTemplate.create(annotations, typeParameters, expressionVarTypes, templater.template(expression), methodType.getReturnType());
    } else {
        List<UStatement> templateStatements = new ArrayList<>();
        for (StatementTree statement : bodyStatements) {
            templateStatements.add(templater.template(statement));
        }
        return BlockTemplate.create(annotations, typeParameters, expressionVarTypes, templateStatements);
    }
}
Also used : Context(com.sun.tools.javac.util.Context) SubContext(com.google.errorprone.SubContext) ArrayList(java.util.ArrayList) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) ReturnTree(com.sun.source.tree.ReturnTree) Annotation(java.lang.annotation.Annotation) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) LabeledStatementTree(com.sun.source.tree.LabeledStatementTree) StatementTree(com.sun.source.tree.StatementTree) EmptyStatementTree(com.sun.source.tree.EmptyStatementTree) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) SubContext(com.google.errorprone.SubContext) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) ExpressionTree(com.sun.source.tree.ExpressionTree)

Example 12 with StatementTree

use of com.sun.source.tree.StatementTree 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 13 with StatementTree

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

the class AbstractMustBeClosedChecker method tryFinallyClose.

private boolean tryFinallyClose(VarSymbol var, TreePath path, VisitorState state) {
    if ((var.flags() & (Flags.FINAL | Flags.EFFECTIVELY_FINAL)) == 0) {
        return false;
    }
    Tree parent = path.getParentPath().getLeaf();
    if (parent.getKind() != Tree.Kind.BLOCK) {
        return false;
    }
    BlockTree block = (BlockTree) parent;
    int idx = block.getStatements().indexOf(path.getLeaf());
    if (idx == -1 || idx == block.getStatements().size() - 1) {
        return false;
    }
    StatementTree next = block.getStatements().get(idx + 1);
    if (!(next instanceof TryTree)) {
        return false;
    }
    TryTree tryTree = (TryTree) next;
    if (tryTree.getFinallyBlock() == null) {
        return false;
    }
    boolean[] closed = { false };
    tryTree.getFinallyBlock().accept(new TreeScanner<Void, Void>() {

        @Override
        public Void visitMethodInvocation(MethodInvocationTree tree, Void unused) {
            if (CLOSE_METHOD.matches(tree, state) && Objects.equals(getSymbol(getReceiver(tree)), var)) {
                closed[0] = true;
            }
            return null;
        }
    }, null);
    return closed[0];
}
Also used : StatementTree(com.sun.source.tree.StatementTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) MethodTree(com.sun.source.tree.MethodTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) Tree(com.sun.source.tree.Tree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) ExpressionTree(com.sun.source.tree.ExpressionTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) BlockTree(com.sun.source.tree.BlockTree) StatementTree(com.sun.source.tree.StatementTree) TryTree(com.sun.source.tree.TryTree) BlockTree(com.sun.source.tree.BlockTree) TryTree(com.sun.source.tree.TryTree)

Example 14 with StatementTree

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

the class FindIdentifiers method findUnusedIdentifiers.

/**
 * Finds all variable declarations which are unused at this point in the AST (i.e. they might be
 * used further on).
 */
public static ImmutableSet<VarSymbol> findUnusedIdentifiers(VisitorState state) {
    ImmutableSet.Builder<VarSymbol> definedVariables = ImmutableSet.builder();
    ImmutableSet.Builder<Symbol> usedSymbols = ImmutableSet.builder();
    Tree prev = state.getPath().getLeaf();
    for (Tree curr : state.getPath().getParentPath()) {
        createFindIdentifiersScanner(usedSymbols, prev).scan(curr, null);
        switch(curr.getKind()) {
            case BLOCK:
                // If we see a block then walk over each statement to see if it defines a variable
                for (StatementTree statement : ((BlockTree) curr).getStatements()) {
                    if (statement.equals(prev)) {
                        // declared/used before us in the tree
                        break;
                    }
                    addIfVariable(statement, definedVariables);
                }
                break;
            case FOR_LOOP:
                ForLoopTree forLoop = (ForLoopTree) curr;
                forLoop.getInitializer().stream().forEach(t -> addIfVariable(t, definedVariables));
                break;
            case ENHANCED_FOR_LOOP:
                EnhancedForLoopTree enhancedFor = (EnhancedForLoopTree) curr;
                addIfVariable(enhancedFor.getVariable(), definedVariables);
                break;
            default:
                break;
        }
        prev = curr;
    }
    return ImmutableSet.copyOf(Sets.difference(definedVariables.build(), usedSymbols.build()));
}
Also used : StatementTree(com.sun.source.tree.StatementTree) ImmutableSet(com.google.common.collect.ImmutableSet) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) Symbol(com.sun.tools.javac.code.Symbol) PackageSymbol(com.sun.tools.javac.code.Symbol.PackageSymbol) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) ForLoopTree(com.sun.source.tree.ForLoopTree) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) IdentifierTree(com.sun.source.tree.IdentifierTree) CatchTree(com.sun.source.tree.CatchTree) ForLoopTree(com.sun.source.tree.ForLoopTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) BlockTree(com.sun.source.tree.BlockTree) StatementTree(com.sun.source.tree.StatementTree) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) NewClassTree(com.sun.source.tree.NewClassTree) ImportTree(com.sun.source.tree.ImportTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) TryTree(com.sun.source.tree.TryTree) BlockTree(com.sun.source.tree.BlockTree) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree)

Example 15 with StatementTree

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

the class CatchAndPrintStackTrace method matchCatch.

@Override
public Description matchCatch(CatchTree tree, VisitorState state) {
    List<? extends StatementTree> statements = tree.getBlock().getStatements();
    if (statements.size() != 1) {
        return NO_MATCH;
    }
    StatementTree statement = Iterables.getOnlyElement(statements);
    if (!MATCHER.matches(statement, state)) {
        return NO_MATCH;
    }
    return describeMatch(statement);
}
Also used : StatementTree(com.sun.source.tree.StatementTree)

Aggregations

StatementTree (com.sun.source.tree.StatementTree)37 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)19 ExpressionStatementTree (com.sun.source.tree.ExpressionStatementTree)18 BlockTree (com.sun.source.tree.BlockTree)16 Tree (com.sun.source.tree.Tree)16 ExpressionTree (com.sun.source.tree.ExpressionTree)12 TreePath (com.sun.source.util.TreePath)9 SuggestedFix (com.google.errorprone.fixes.SuggestedFix)8 MethodTree (com.sun.source.tree.MethodTree)8 MemberSelectTree (com.sun.source.tree.MemberSelectTree)7 TryTree (com.sun.source.tree.TryTree)7 VariableTree (com.sun.source.tree.VariableTree)7 CatchTree (com.sun.source.tree.CatchTree)6 JCTree (com.sun.tools.javac.tree.JCTree)6 ClassTree (com.sun.source.tree.ClassTree)5 IdentifierTree (com.sun.source.tree.IdentifierTree)5 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)5 VisitorState (com.google.errorprone.VisitorState)4 Description (com.google.errorprone.matchers.Description)4 EnhancedForLoopTree (com.sun.source.tree.EnhancedForLoopTree)4