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