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());
}
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);
}
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);
}
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();
});
}
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;
}
Aggregations