Search in sources :

Example 31 with StatementTree

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

the class CatchFail method deleteFix.

// Extract the argument to a call to assertWithMessage, e.g. in:
// assertWithMessage("message").fail();
Optional<Fix> deleteFix(TryTree tree, ImmutableList<CatchTree> catchBlocks, VisitorState state) {
    SuggestedFix.Builder fix = SuggestedFix.builder();
    if (tree.getFinallyBlock() != null || catchBlocks.size() < tree.getCatches().size()) {
        // If the try statement has a finally region, or other catch blocks, delete only the
        // unnecessary blocks.
        catchBlocks.stream().forEachOrdered(fix::delete);
    } else {
        // The try statement has no finally region and all catch blocks are unnecessary. Replace it
        // with the try statements, deleting all catches.
        List<? extends StatementTree> tryStatements = tree.getBlock().getStatements();
        String source = state.getSourceCode().toString();
        // Replace the full region to work around a GJF partial formatting bug that prevents it from
        // re-indenting unchanged lines. This means that fixes may overlap, but that's (hopefully)
        // unlikely.
        // TODO(b/24140798): emit more precise replacements if GJF is fixed
        fix.replace(tree, source.substring(((JCTree) tryStatements.get(0)).getStartPosition(), state.getEndPosition(Iterables.getLast(tryStatements))));
    }
    MethodTree enclosing = findEnclosing(state.getPath());
    if (enclosing == null) {
        // There isn't an enclosing method, possibly because we're in a lambda or initializer block.
        return Optional.empty();
    }
    if (isExpectedExceptionTest(ASTHelpers.getSymbol(enclosing), state)) {
        // tests, so don't use that fix for methods annotated with @Test(expected=...).
        return Optional.empty();
    }
    // Fix up the enclosing method's throws declaration to include the new thrown exception types.
    Collection<Type> thrownTypes = ASTHelpers.getSymbol(enclosing).getThrownTypes();
    Types types = state.getTypes();
    // Find all types in the deleted catch blocks that are not already in the throws declaration.
    ImmutableList<Type> toThrow = catchBlocks.stream().map(c -> ASTHelpers.getType(c.getParameter())).flatMap(t -> t instanceof UnionClassType ? ImmutableList.copyOf(((UnionClassType) t).getAlternativeTypes()).stream() : Stream.of(t)).filter(t -> thrownTypes.stream().noneMatch(x -> types.isAssignable(t, x))).collect(toImmutableList());
    if (!toThrow.isEmpty()) {
        if (!TEST_CASE.matches(enclosing, state)) {
            // not be a safe local refactoring.
            return Optional.empty();
        }
        String throwsString = toThrow.stream().map(t -> SuggestedFixes.qualifyType(state, fix, t)).distinct().collect(joining(", "));
        if (enclosing.getThrows().isEmpty()) {
            // Add a new throws declaration.
            fix.prefixWith(enclosing.getBody(), "throws " + throwsString);
        } else {
            // Append to an existing throws declaration.
            fix.postfixWith(Iterables.getLast(enclosing.getThrows()), ", " + throwsString);
        }
    }
    return Optional.of(fix.build());
}
Also used : SuggestedFixes(com.google.errorprone.fixes.SuggestedFixes) Iterables(com.google.common.collect.Iterables) Matchers.anyOf(com.google.errorprone.matchers.Matchers.anyOf) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) MethodTree(com.sun.source.tree.MethodTree) VisitorState(com.google.errorprone.VisitorState) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) Matchers.expressionStatement(com.google.errorprone.matchers.Matchers.expressionStatement) ImmutableList(com.google.common.collect.ImmutableList) TryTreeMatcher(com.google.errorprone.bugpatterns.BugChecker.TryTreeMatcher) IdentifierTree(com.sun.source.tree.IdentifierTree) CatchTree(com.sun.source.tree.CatchTree) BugPattern(com.google.errorprone.BugPattern) Matcher(com.google.errorprone.matchers.Matcher) Fix(com.google.errorprone.fixes.Fix) Tree(com.sun.source.tree.Tree) MethodNameMatcher(com.google.errorprone.matchers.method.MethodMatchers.MethodNameMatcher) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) TreePath(com.sun.source.util.TreePath) UnionClassType(com.sun.tools.javac.code.Type.UnionClassType) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) Matchers.hasAnnotation(com.google.errorprone.matchers.Matchers.hasAnnotation) Collection(java.util.Collection) Compound(com.sun.tools.javac.code.Attribute.Compound) Iterables.getOnlyElement(com.google.common.collect.Iterables.getOnlyElement) NO_MATCH(com.google.errorprone.matchers.Description.NO_MATCH) JCTree(com.sun.tools.javac.tree.JCTree) JUNIT4_TEST_ANNOTATION(com.google.errorprone.matchers.JUnitMatchers.JUNIT4_TEST_ANNOTATION) Collectors.joining(java.util.stream.Collectors.joining) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) JUnitMatchers.isJunit3TestCase(com.google.errorprone.matchers.JUnitMatchers.isJunit3TestCase) TreeScanner(com.sun.source.util.TreeScanner) Objects(java.util.Objects) List(java.util.List) MethodMatchers.staticMethod(com.google.errorprone.matchers.method.MethodMatchers.staticMethod) Types(com.sun.tools.javac.code.Types) Stream(java.util.stream.Stream) JUnitMatchers(com.google.errorprone.matchers.JUnitMatchers) Description(com.google.errorprone.matchers.Description) StatementTree(com.sun.source.tree.StatementTree) TryTree(com.sun.source.tree.TryTree) Optional(java.util.Optional) WARNING(com.google.errorprone.BugPattern.SeverityLevel.WARNING) ProvidesFix(com.google.errorprone.BugPattern.ProvidesFix) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) ASTHelpers(com.google.errorprone.util.ASTHelpers) Type(com.sun.tools.javac.code.Type) UnionClassType(com.sun.tools.javac.code.Type.UnionClassType) Types(com.sun.tools.javac.code.Types) MethodTree(com.sun.source.tree.MethodTree) JCTree(com.sun.tools.javac.tree.JCTree) UnionClassType(com.sun.tools.javac.code.Type.UnionClassType) Type(com.sun.tools.javac.code.Type) SuggestedFix(com.google.errorprone.fixes.SuggestedFix)

Example 32 with StatementTree

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

the class DeadException method matchNewClass.

@Override
public Description matchNewClass(NewClassTree newClassTree, VisitorState state) {
    if (!MATCHER.matches(newClassTree, state)) {
        return Description.NO_MATCH;
    }
    StatementTree parent = (StatementTree) state.getPath().getParentPath().getLeaf();
    boolean isLastStatement = anyOf(new ChildOfBlockOrCase<>(ChildMultiMatcher.MatchType.LAST, Matchers.<StatementTree>isSame(parent)), // it could also be a bare if statement with no braces
    parentNode(parentNode(kindIs(IF)))).matches(newClassTree, state);
    Fix fix;
    if (isLastStatement) {
        fix = SuggestedFix.prefixWith(newClassTree, "throw ");
    } else {
        fix = SuggestedFix.delete(parent);
    }
    return describeMatch(newClassTree, fix);
}
Also used : StatementTree(com.sun.source.tree.StatementTree) Fix(com.google.errorprone.fixes.Fix) ProvidesFix(com.google.errorprone.BugPattern.ProvidesFix) SuggestedFix(com.google.errorprone.fixes.SuggestedFix)

Example 33 with StatementTree

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

the class UIf method apply.

@Override
@Nullable
public Choice<UnifierWithUnconsumedStatements> apply(UnifierWithUnconsumedStatements state) {
    java.util.List<? extends StatementTree> unconsumedStatements = state.unconsumedStatements();
    if (unconsumedStatements.isEmpty()) {
        return Choice.none();
    }
    final java.util.List<? extends StatementTree> unconsumedStatementsTail = unconsumedStatements.subList(1, unconsumedStatements.size());
    StatementTree firstStatement = unconsumedStatements.get(0);
    if (firstStatement.getKind() != Kind.IF) {
        return Choice.none();
    }
    final IfTree ifTree = (IfTree) firstStatement;
    Unifier unifier = state.unifier();
    Choice<UnifierWithUnconsumedStatements> forwardMatch = getCondition().unify(ifTree.getCondition(), unifier.fork()).thenChoose(unifyUStatementWithSingleStatement(getThenStatement(), ifTree.getThenStatement())).thenChoose(unifierAfterThen -> {
        if (getElseStatement() != null && ifTree.getElseStatement() == null && ControlFlowVisitor.INSTANCE.visitStatement(ifTree.getThenStatement()) == Result.ALWAYS_RETURNS) {
            Choice<UnifierWithUnconsumedStatements> result = getElseStatement().apply(UnifierWithUnconsumedStatements.create(unifierAfterThen.fork(), unconsumedStatementsTail));
            if (getElseStatement() instanceof UBlock) {
                Choice<UnifierWithUnconsumedStatements> alternative = Choice.of(UnifierWithUnconsumedStatements.create(unifierAfterThen.fork(), unconsumedStatementsTail));
                for (UStatement stmt : ((UBlock) getElseStatement()).getStatements()) {
                    alternative = alternative.thenChoose(stmt);
                }
                result = result.or(alternative);
            }
            return result;
        } else {
            return unifyUStatementWithSingleStatement(getElseStatement(), ifTree.getElseStatement()).apply(unifierAfterThen).transform(unifierAfterElse -> UnifierWithUnconsumedStatements.create(unifierAfterElse, unconsumedStatementsTail));
        }
    });
    Choice<UnifierWithUnconsumedStatements> backwardMatch = getCondition().negate().unify(ifTree.getCondition(), unifier.fork()).thenChoose(unifierAfterCond -> {
        if (getElseStatement() == null) {
            return Choice.none();
        }
        return getElseStatement().apply(UnifierWithUnconsumedStatements.create(unifierAfterCond, List.of(ifTree.getThenStatement()))).thenOption((UnifierWithUnconsumedStatements stateAfterThen) -> stateAfterThen.unconsumedStatements().isEmpty() ? Optional.of(stateAfterThen.unifier()) : Optional.<Unifier>absent());
    }).thenChoose(unifierAfterThen -> {
        if (ifTree.getElseStatement() == null && ControlFlowVisitor.INSTANCE.visitStatement(ifTree.getThenStatement()) == Result.ALWAYS_RETURNS) {
            Choice<UnifierWithUnconsumedStatements> result = getThenStatement().apply(UnifierWithUnconsumedStatements.create(unifierAfterThen.fork(), unconsumedStatementsTail));
            if (getThenStatement() instanceof UBlock) {
                Choice<UnifierWithUnconsumedStatements> alternative = Choice.of(UnifierWithUnconsumedStatements.create(unifierAfterThen.fork(), unconsumedStatementsTail));
                for (UStatement stmt : ((UBlock) getThenStatement()).getStatements()) {
                    alternative = alternative.thenChoose(stmt);
                }
                result = result.or(alternative);
            }
            return result;
        } else {
            return unifyUStatementWithSingleStatement(getThenStatement(), ifTree.getElseStatement()).apply(unifierAfterThen).transform(unifierAfterElse -> UnifierWithUnconsumedStatements.create(unifierAfterElse, unconsumedStatementsTail));
        }
    });
    return forwardMatch.or(backwardMatch);
}
Also used : StatementTree(com.sun.source.tree.StatementTree) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) Iterables(com.google.common.collect.Iterables) IfTree(com.sun.source.tree.IfTree) Function(com.google.common.base.Function) Optional(com.google.common.base.Optional) StatementTree(com.sun.source.tree.StatementTree) AutoValue(com.google.auto.value.AutoValue) TreeVisitor(com.sun.source.tree.TreeVisitor) Result(com.google.errorprone.refaster.ControlFlowVisitor.Result) List(com.sun.tools.javac.util.List) Nullable(javax.annotation.Nullable) IfTree(com.sun.source.tree.IfTree) Nullable(javax.annotation.Nullable)

Example 34 with StatementTree

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

the class UPlaceholderStatement method apply.

@Override
public Choice<UnifierWithUnconsumedStatements> apply(final UnifierWithUnconsumedStatements initState) {
    final PlaceholderUnificationVisitor visitor = PlaceholderUnificationVisitor.create(TreeMaker.instance(initState.unifier().getContext()), arguments());
    PlaceholderVerificationVisitor verification = new PlaceholderVerificationVisitor(Collections2.transform(placeholder().requiredParameters(), Functions.forMap(arguments())), arguments().values());
    // The choices where we might conceivably have a completed placeholder match.
    Choice<State<ConsumptionState>> realOptions = Choice.none();
    // The choice of consumption states to this point in the block.
    Choice<State<ConsumptionState>> choiceToHere = Choice.of(State.create(List.<UVariableDecl>nil(), initState.unifier(), ConsumptionState.empty()));
    if (verification.allRequiredMatched()) {
        realOptions = choiceToHere.or(realOptions);
    }
    for (final StatementTree targetStatement : initState.unconsumedStatements()) {
        if (!verification.scan(targetStatement, initState.unifier())) {
            // we saw a variable that's not allowed to be referenced
            break;
        }
        // Consume another statement, or if that fails, fall back to the previous choices...
        choiceToHere = choiceToHere.thenChoose((final State<ConsumptionState> consumptionState) -> visitor.unifyStatement(targetStatement, consumptionState).transform((State<? extends JCStatement> stmtState) -> stmtState.withResult(consumptionState.result().consume(stmtState.result()))));
        if (verification.allRequiredMatched()) {
            realOptions = choiceToHere.or(realOptions);
        }
    }
    return realOptions.thenOption((State<ConsumptionState> consumptionState) -> {
        if (ImmutableSet.copyOf(consumptionState.seenParameters()).containsAll(placeholder().requiredParameters())) {
            Unifier resultUnifier = consumptionState.unifier().fork();
            int nConsumedStatements = consumptionState.result().consumedStatements();
            java.util.List<? extends StatementTree> remainingStatements = initState.unconsumedStatements().subList(nConsumedStatements, initState.unconsumedStatements().size());
            UnifierWithUnconsumedStatements result = UnifierWithUnconsumedStatements.create(resultUnifier, remainingStatements);
            List<JCStatement> impl = consumptionState.result().placeholderImplInReverseOrder().reverse();
            ControlFlowVisitor.Result implFlow = ControlFlowVisitor.INSTANCE.visitStatements(impl);
            if (implFlow == implementationFlow()) {
                List<JCStatement> prevBinding = resultUnifier.getBinding(placeholder().blockKey());
                if (prevBinding != null && prevBinding.toString().equals(impl.toString())) {
                    return Optional.of(result);
                } else if (prevBinding == null) {
                    resultUnifier.putBinding(placeholder().blockKey(), impl);
                    return Optional.of(result);
                }
            }
        }
        return Optional.absent();
    });
}
Also used : JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) StatementTree(com.sun.source.tree.StatementTree) State(com.google.errorprone.refaster.PlaceholderUnificationVisitor.State)

Example 35 with StatementTree

use of com.sun.source.tree.StatementTree in project j2objc by google.

the class TreeConverter method convertForLoop.

private TreeNode convertForLoop(ForLoopTree node, TreePath parent) {
    TreePath path = getTreePath(parent, node);
    ForStatement newNode = new ForStatement().setExpression((Expression) convert(node.getCondition(), path)).setBody((Statement) convert(node.getStatement(), path));
    VariableDeclarationExpression lastVar = null;
    for (StatementTree initializer : node.getInitializer()) {
        if (initializer.getKind() == Kind.VARIABLE) {
            VariableTree var = (VariableTree) initializer;
            VariableDeclarationExpression newVar = convertVariableExpression(var, path);
            if (lastVar == null) {
                newNode.addInitializer(newVar);
                lastVar = newVar;
            } else {
                lastVar.addFragment(TreeUtil.remove(newVar.getFragment(0)));
            }
        } else {
            assert initializer.getKind() == Kind.EXPRESSION_STATEMENT;
            TreePath initializerPath = getTreePath(path, initializer);
            TreeNode expr = convert(((ExpressionStatementTree) initializer).getExpression(), initializerPath);
            newNode.addInitializer((Expression) expr);
        }
    }
    for (ExpressionStatementTree updater : node.getUpdate()) {
        newNode.addUpdater((Expression) convert(updater.getExpression(), getTreePath(path, updater)));
    }
    return newNode;
}
Also used : ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) LabeledStatementTree(com.sun.source.tree.LabeledStatementTree) StatementTree(com.sun.source.tree.StatementTree) TreePath(com.sun.source.util.TreePath) PostfixExpression(com.google.devtools.j2objc.ast.PostfixExpression) InstanceofExpression(com.google.devtools.j2objc.ast.InstanceofExpression) Expression(com.google.devtools.j2objc.ast.Expression) ConditionalExpression(com.google.devtools.j2objc.ast.ConditionalExpression) InfixExpression(com.google.devtools.j2objc.ast.InfixExpression) ParenthesizedExpression(com.google.devtools.j2objc.ast.ParenthesizedExpression) JCFunctionalExpression(com.sun.tools.javac.tree.JCTree.JCFunctionalExpression) LambdaExpression(com.google.devtools.j2objc.ast.LambdaExpression) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) PrefixExpression(com.google.devtools.j2objc.ast.PrefixExpression) ThisExpression(com.google.devtools.j2objc.ast.ThisExpression) FunctionalExpression(com.google.devtools.j2objc.ast.FunctionalExpression) CastExpression(com.google.devtools.j2objc.ast.CastExpression) VariableDeclarationExpression(com.google.devtools.j2objc.ast.VariableDeclarationExpression) TreeNode(com.google.devtools.j2objc.ast.TreeNode) VariableDeclarationExpression(com.google.devtools.j2objc.ast.VariableDeclarationExpression) VariableTree(com.sun.source.tree.VariableTree) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) ForStatement(com.google.devtools.j2objc.ast.ForStatement) EnhancedForStatement(com.google.devtools.j2objc.ast.EnhancedForStatement)

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