use of com.sun.source.tree.MethodTree in project tutorials by eugenp.
the class SampleJavacPlugin method init.
@Override
public void init(JavacTask task, String... args) {
Context context = ((BasicJavacTask) task).getContext();
task.addTaskListener(new TaskListener() {
@Override
public void started(TaskEvent e) {
}
@Override
public void finished(TaskEvent e) {
if (e.getKind() != TaskEvent.Kind.PARSE) {
return;
}
e.getCompilationUnit().accept(new TreeScanner<Void, Void>() {
@Override
public Void visitMethod(MethodTree method, Void v) {
List<VariableTree> parametersToInstrument = method.getParameters().stream().filter(SampleJavacPlugin.this::shouldInstrument).collect(Collectors.toList());
if (!parametersToInstrument.isEmpty()) {
// There is a possible case that more than one argument is marked by @Positive,
// as the checks are added to the method's body beginning, we process parameters RTL
// to ensure correct order.
Collections.reverse(parametersToInstrument);
parametersToInstrument.forEach(p -> addCheck(method, p, context));
}
// hence, we want to proceed with method body AST as well.
return super.visitMethod(method, v);
}
}, null);
}
});
}
use of com.sun.source.tree.MethodTree 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.MethodTree in project error-prone by google.
the class AbstractMustBeClosedChecker method checkClosed.
private Description checkClosed(ExpressionTree tree, VisitorState state) {
MethodTree callerMethodTree = enclosingMethod(state);
TreePath path = state.getPath();
OUTER: while (true) {
TreePath prev = path;
path = path.getParentPath();
switch(path.getLeaf().getKind()) {
case RETURN:
if (callerMethodTree != null) {
// expression or anonymous class.
if (HAS_MUST_BE_CLOSED_ANNOTATION.matches(callerMethodTree, state)) {
// enforced.
return NO_MATCH;
}
// enforced. Suggest fixing this by annotating the caller method.
return buildDescription(tree).addFix(SuggestedFix.builder().prefixWith(callerMethodTree, "@MustBeClosed\n").addImport(MustBeClosed.class.getCanonicalName()).build()).build();
}
break;
case CONDITIONAL_EXPRESSION:
ConditionalExpressionTree conditionalExpressionTree = (ConditionalExpressionTree) path.getLeaf();
if (conditionalExpressionTree.getTrueExpression().equals(prev.getLeaf()) || conditionalExpressionTree.getFalseExpression().equals(prev.getLeaf())) {
continue OUTER;
}
break;
case MEMBER_SELECT:
MemberSelectTree memberSelectTree = (MemberSelectTree) path.getLeaf();
if (memberSelectTree.getExpression().equals(prev.getLeaf())) {
Type type = getType(memberSelectTree);
Symbol sym = getSymbol(memberSelectTree);
Type streamType = state.getTypeFromString(Stream.class.getName());
if (isSubtype(sym.enclClass().asType(), streamType, state) && isSameType(type.getReturnType(), streamType, state)) {
// skip enclosing method invocation
path = path.getParentPath();
continue OUTER;
}
}
break;
case VARIABLE:
Symbol sym = getSymbol(path.getLeaf());
if (sym instanceof VarSymbol) {
VarSymbol var = (VarSymbol) sym;
if (var.getKind() == ElementKind.RESOURCE_VARIABLE || tryFinallyClose(var, path, state)) {
return NO_MATCH;
}
}
break;
default:
break;
}
// The constructor or method invocation does not occur within the resource variable
// initializer of a try-with-resources statement.
Description.Builder description = buildDescription(tree);
addFix(description, tree, state);
return description.build();
}
}
use of com.sun.source.tree.MethodTree in project error-prone by google.
the class ByteBufferBackingArray method matchMethodInvocation.
@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
if (!BYTE_BUFFER_ARRAY_MATCHER.matches(tree, state)) {
return Description.NO_MATCH;
}
// Checks for validating use on method call chain.
ExpressionTree receiver = tree;
do {
receiver = ASTHelpers.getReceiver(receiver);
if (isValidInitializerOrNotAByteBuffer(receiver, state)) {
return Description.NO_MATCH;
}
} while (receiver instanceof MethodInvocationTree);
Symbol bufferSymbol = ASTHelpers.getSymbol(receiver);
// Checks for validating use on method scope.
if (bufferSymbol.owner instanceof MethodSymbol) {
MethodTree enclosingMethod = ASTHelpers.findMethod((MethodSymbol) bufferSymbol.owner, state);
if (enclosingMethod == null || ValidByteBufferArrayScanner.scan(enclosingMethod, state, bufferSymbol)) {
return Description.NO_MATCH;
}
}
// Checks for validating use on fields.
if (bufferSymbol.owner instanceof ClassSymbol) {
ClassTree enclosingClass = ASTHelpers.findClass((ClassSymbol) bufferSymbol.owner, state);
if (enclosingClass == null) {
return Description.NO_MATCH;
}
Optional<? extends Tree> validMemberTree = enclosingClass.getMembers().stream().filter(memberTree -> ValidByteBufferArrayScanner.scan(memberTree, state, bufferSymbol)).findFirst();
if (validMemberTree.isPresent()) {
return Description.NO_MATCH;
}
}
return describeMatch(tree);
}
use of com.sun.source.tree.MethodTree in project error-prone by google.
the class DataFlow method findEnclosingMethodOrLambdaOrInitializer.
// TODO(user), remove once we merge jdk8 specific's with core
private static <T> TreePath findEnclosingMethodOrLambdaOrInitializer(TreePath path) {
while (path != null) {
if (path.getLeaf() instanceof MethodTree) {
return path;
}
TreePath parent = path.getParentPath();
if (parent != null) {
if (parent.getLeaf() instanceof ClassTree) {
if (path.getLeaf() instanceof BlockTree) {
// this is a class or instance initializer block
return path;
}
if (path.getLeaf() instanceof VariableTree && ((VariableTree) path.getLeaf()).getInitializer() != null) {
// this is a field with an inline initializer
return path;
}
}
if (parent.getLeaf() instanceof LambdaExpressionTree) {
return parent;
}
}
path = parent;
}
return null;
}
Aggregations