private static StatementTree getLastStatement(BlockTree blockTree) { return getLast(blockTree.getStatements()); }
@Override public Boolean visitBlock(BlockTree tree, Void unused) { switch (tree.getStatements().size()) { case 0: return true; case 1: return scan(getOnlyElement(tree.getStatements()), null); default: return false; } }
@Override public boolean matches(T statement, VisitorState state) { BlockTree block = state.findEnclosing(BlockTree.class); return block != null && Iterables.getLast(block.getStatements()).equals(statement); } }
@Override protected Iterable<? extends StatementTree> getChildNodes(TryTree tree, VisitorState state) { return tree.getBlock().getStatements(); } }
@Override public Result visitBlock(BlockTree node, BreakContext cxt) { return visitStatements(node.getStatements(), cxt); }
@Override public Boolean visitBlock(BlockTree tree, Void unused) { return scan(tree.getStatements()); }
@Override public T visitBlock(BlockTree node, Void p) { return visit(node.getStatements()); }
@Override public Description matchBlock(BlockTree tree, VisitorState state) { return checkDeclarations(tree.getStatements(), state); }
@Override public Description visitMethod(MethodTree node, Void aVoid) { BlockTree methodBody = node.getBody(); if (methodBody == null) { return Description.NO_MATCH; } return methodBody.getStatements().stream() .map(tree -> tree.accept(this, null)) .filter(notNull()) .findFirst() .orElse(Description.NO_MATCH); }
/** does the constructor invoke another constructor in the same class via this(...)? */ private boolean constructorInvokesAnother(MethodTree constructor, VisitorState state) { BlockTree body = constructor.getBody(); List<? extends StatementTree> statements = body.getStatements(); if (statements.size() > 0) { StatementTree statementTree = statements.get(0); if (isThisCall(statementTree, state)) { return true; } } return false; }
private static boolean isLastStatementInBlock(@Nullable TreePath pathToStatement) { if (pathToStatement == null) { return false; } Tree parent = pathToStatement.getParentPath().getLeaf(); if (!(parent instanceof BlockTree)) { return false; } return getLast(((BlockTree) parent).getStatements()).equals(pathToStatement.getLeaf()); }
@Override protected Iterable<? extends StatementTree> getChildNodes(T tree, VisitorState state) { Tree enclosing = state.findEnclosing(CaseTree.class, BlockTree.class); if (enclosing == null) { return ImmutableList.of(); } if (enclosing instanceof BlockTree) { return ((BlockTree) enclosing).getStatements(); } else if (enclosing instanceof CaseTree) { return ((CaseTree) enclosing).getStatements(); } else { // findEnclosing given two types must return something of one of those types throw new IllegalStateException("enclosing tree not a BlockTree or CaseTree"); } } }
@Override public UBlock visitBlock(BlockTree tree, Void v) { return UBlock.create(templateStatements(tree.getStatements())); }
@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); } }
@Override public Choice<Unifier> visitBlock(BlockTree block, Unifier unifier) { return unifyStatementList(getStatements(), block.getStatements(), unifier); }
private static int caseEndPosition(VisitorState state, JCTree.JCCase caseTree) { // if the statement group is a single block statement, handle fall through comments at the // end of the block if (caseTree.stats.size() == 1) { JCTree.JCStatement only = getOnlyElement(caseTree.stats); if (only.hasTag(JCTree.Tag.BLOCK)) { BlockTree blockTree = (BlockTree) only; return blockTree.getStatements().isEmpty() ? ((JCTree) blockTree).getStartPosition() : state.getEndPosition(getLast(blockTree.getStatements())); } } return state.getEndPosition(caseTree); } }
private static boolean invokedConstructorMustBeClosed(VisitorState state, MethodTree methodTree) { // The first statement in a constructor should be an invocation of the super/this constructor. List<? extends StatementTree> statements = methodTree.getBody().getStatements(); if (statements.isEmpty()) { // Not sure how the body would be empty, but just filter it out in case. return false; } ExpressionStatementTree est = (ExpressionStatementTree) statements.get(0); MethodInvocationTree mit = (MethodInvocationTree) est.getExpression(); MethodSymbol invokedConstructorSymbol = ASTHelpers.getSymbol(mit); return ASTHelpers.hasAnnotation(invokedConstructorSymbol, MustBeClosed.class, state); } }
@Override public Choice<State<JCBlock>> visitBlock(BlockTree node, State<?> state) { return chooseSubtrees( state, s -> unifyStatements(node.getStatements(), s), stmts -> maker().Block(0, stmts)); }
@Override public Description matchTry(TryTree tree, VisitorState state) { if (tryTreeMatches(tree, state)) { List<? extends StatementTree> tryStatements = tree.getBlock().getStatements(); StatementTree lastTryStatement = tryStatements.get(tryStatements.size() - 1); Optional<Fix> assertThrowsFix = AssertThrowsUtils.tryFailToAssertThrows(tree, tryStatements, state); Fix failFix = addFailCall(tree, lastTryStatement, state); return buildDescription(lastTryStatement).addFix(assertThrowsFix).addFix(failFix).build(); } else { return Description.NO_MATCH; } }
@Override protected Description handleStatements( MethodTree tree, VisitorState state, JCExpression expectedException, SuggestedFix baseFix) { return describeMatch( tree, buildFix( state, SuggestedFix.builder().merge(baseFix), expectedException, tree.getBody().getStatements())); } }