use of com.sun.source.util.TreeScanner in project lombok by rzwitserloot.
the class HandleHelper method handle.
@Override
public void handle(AnnotationValues<Helper> annotation, JCAnnotation ast, JavacNode annotationNode) {
handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.HELPER_FLAG_USAGE, "@Helper");
deleteAnnotationIfNeccessary(annotationNode, Helper.class);
JavacNode annotatedType = annotationNode.up();
JavacNode containingBlock = annotatedType == null ? null : annotatedType.directUp();
List<JCStatement> origStatements = getStatementsFromJcNode(containingBlock == null ? null : containingBlock.get());
if (annotatedType == null || annotatedType.getKind() != Kind.TYPE || origStatements == null) {
annotationNode.addError("@Helper is legal only on method-local classes.");
return;
}
JCClassDecl annotatedType_ = (JCClassDecl) annotatedType.get();
Iterator<JCStatement> it = origStatements.iterator();
while (it.hasNext()) {
if (it.next() == annotatedType_) {
break;
}
}
java.util.List<String> knownMethodNames = new ArrayList<String>();
for (JavacNode ch : annotatedType.down()) {
if (ch.getKind() != Kind.METHOD)
continue;
String n = ch.getName();
if (n == null || n.isEmpty() || n.charAt(0) == '<')
continue;
knownMethodNames.add(n);
}
Collections.sort(knownMethodNames);
final String[] knownMethodNames_ = knownMethodNames.toArray(new String[knownMethodNames.size()]);
final Name helperName = annotationNode.toName("$" + annotatedType_.name);
final boolean[] helperUsed = new boolean[1];
final JavacTreeMaker maker = annotationNode.getTreeMaker();
TreeVisitor<Void, Void> visitor = new TreeScanner<Void, Void>() {
@Override
public Void visitMethodInvocation(MethodInvocationTree node, Void p) {
JCMethodInvocation jcmi = (JCMethodInvocation) node;
apply(jcmi);
return super.visitMethodInvocation(node, p);
}
private void apply(JCMethodInvocation jcmi) {
if (!(jcmi.meth instanceof JCIdent))
return;
JCIdent jci = (JCIdent) jcmi.meth;
if (Arrays.binarySearch(knownMethodNames_, jci.name.toString()) < 0)
return;
jcmi.meth = maker.Select(maker.Ident(helperName), jci.name);
helperUsed[0] = true;
}
};
while (it.hasNext()) {
JCStatement stat = it.next();
stat.accept(visitor, null);
}
if (!helperUsed[0]) {
annotationNode.addWarning("No methods of this helper class are ever used.");
return;
}
ListBuffer<JCStatement> newStatements = new ListBuffer<JCStatement>();
boolean mark = false;
for (JCStatement stat : origStatements) {
newStatements.append(stat);
if (mark || stat != annotatedType_)
continue;
mark = true;
JCExpression init = maker.NewClass(null, List.<JCExpression>nil(), maker.Ident(annotatedType_.name), List.<JCExpression>nil(), null);
JCExpression varType = maker.Ident(annotatedType_.name);
JCVariableDecl decl = maker.VarDef(maker.Modifiers(Flags.FINAL), helperName, varType, init);
newStatements.append(decl);
}
setStatementsOfJcNode(containingBlock.get(), newStatements.toList());
}
use of com.sun.source.util.TreeScanner in project error-prone by google.
the class UFreeIdent method defaultAction.
@Override
protected Choice<Unifier> defaultAction(Tree target, final Unifier unifier) {
if (target instanceof JCExpression) {
JCExpression expression = (JCExpression) target;
JCExpression currentBinding = unifier.getBinding(key());
// Check that the expression does not reference any template-local variables.
boolean isGood = trueOrNull(new TreeScanner<Boolean, Void>() {
@Override
public Boolean reduce(@Nullable Boolean left, @Nullable Boolean right) {
return trueOrNull(left) && trueOrNull(right);
}
@Override
public Boolean visitIdentifier(IdentifierTree ident, Void v) {
Symbol identSym = ASTHelpers.getSymbol(ident);
for (ULocalVarIdent.Key key : Iterables.filter(unifier.getBindings().keySet(), ULocalVarIdent.Key.class)) {
if (identSym == unifier.getBinding(key).getSymbol()) {
return false;
}
}
return true;
}
}.scan(expression, null));
if (!isGood) {
return Choice.none();
} else if (currentBinding == null) {
unifier.putBinding(key(), expression);
return Choice.of(unifier);
} else if (currentBinding.toString().equals(expression.toString())) {
// If it's the same code, treat it as the same expression.
return Choice.of(unifier);
}
}
return Choice.none();
}
use of com.sun.source.util.TreeScanner in project ceylon by eclipse.
the class TestPos method main.
public static void main(String... args) throws IOException {
final boolean[] sawError = { false };
final StringBuilder log = new StringBuilder();
class MyFileObject extends SimpleJavaFileObject {
MyFileObject() {
super(URI.create("myfo:///Test.java"), SOURCE);
}
@Override
public String getCharContent(boolean ignoreEncodingErrors) {
// 0123456789012345678901234567890123456789012345678901234
return "class Test { { Object[] o = new <T,e,s,t>Object[0]; } }";
}
}
class Scanner extends TreeScanner<Void, Trees> {
CompilationUnitTree toplevel = null;
@Override
public Void visitCompilationUnit(CompilationUnitTree node, Trees trees) {
toplevel = node;
return super.visitCompilationUnit(node, trees);
}
@Override
public Void visitErroneous(ErroneousTree node, Trees trees) {
sawError[0] = true;
long startPos = trees.getSourcePositions().getStartPosition(toplevel, node);
long endPos = trees.getSourcePositions().getEndPosition(toplevel, node);
log.append(String.format("begin=%s, end=%s : %s%n", startPos, endPos, node.getErrorTrees()));
if (startPos != 28)
error("Start pos for %s is incorrect (%s)!", node, startPos);
if (endPos != 50)
error("End pos for %s is incorrect (%s)!", node, endPos);
return null;
}
}
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
List<JavaFileObject> compilationUnits = Collections.<JavaFileObject>singletonList(new MyFileObject());
DiagnosticListener<JavaFileObject> dl = new DiagnosticListener<JavaFileObject>() {
public void report(Diagnostic<? extends JavaFileObject> diag) {
log.append(String.format("%s @ %s%n", diag.getCode(), diag.getPosition()));
if (!diag.getCode().equals(errCode))
error("unexpected error");
if (diag.getPosition() != 33)
error("Error pos for %s is incorrect (%s)!", diag.getCode(), diag.getPosition());
sawError[0] = true;
}
};
JavacTask task = (JavacTask) javac.getTask(null, null, dl, null, null, compilationUnits);
Trees trees = Trees.instance(task);
Iterable<? extends Tree> toplevels = task.parse();
if (!sawError[0])
error("No parse error detected");
sawError[0] = false;
new Scanner().scan(toplevels, trees);
if (!sawError[0])
error("No error tree detected");
if (!log.toString().equals(expected))
error("Unexpected log message: %n%s%n", log);
System.out.print(log);
System.out.flush();
}
use of com.sun.source.util.TreeScanner in project error-prone by google.
the class FindIdentifiers method createFindIdentifiersScanner.
/**
* Finds all identifiers in a tree. Takes an optional stop point as its argument: the depth-first
* walk will stop if this node is encountered.
*/
private static final TreeScanner<Void, Void> createFindIdentifiersScanner(ImmutableSet.Builder<Symbol> builder, @Nullable Tree stoppingPoint) {
return new TreeScanner<Void, Void>() {
@Override
public Void scan(Tree tree, Void unused) {
return Objects.equals(stoppingPoint, tree) ? null : super.scan(tree, unused);
}
@Override
public Void scan(Iterable<? extends Tree> iterable, Void unused) {
if (stoppingPoint != null && iterable != null) {
ImmutableList.Builder<Tree> builder = ImmutableList.builder();
for (Tree t : iterable) {
if (stoppingPoint.equals(t)) {
break;
}
builder.add(t);
}
iterable = builder.build();
}
return super.scan(iterable, unused);
}
@Override
public Void visitIdentifier(IdentifierTree identifierTree, Void unused) {
Symbol symbol = ASTHelpers.getSymbol(identifierTree);
if (symbol != null) {
builder.add(symbol);
}
return null;
}
};
}
use of com.sun.source.util.TreeScanner in project error-prone by google.
the class AssertionFailureIgnored method matchMethodInvocation.
@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
if (!ASSERTION.matches(tree, state)) {
return NO_MATCH;
}
JCTry tryStatement = enclosingTry(state);
if (tryStatement == null) {
return NO_MATCH;
}
Optional<JCCatch> maybeCatchTree = catchesType(tryStatement, state.getSymtab().assertionErrorType, state);
if (!maybeCatchTree.isPresent()) {
return NO_MATCH;
}
JCCatch catchTree = maybeCatchTree.get();
VarSymbol parameter = ASTHelpers.getSymbol(catchTree.getParameter());
boolean rethrows = firstNonNull(new TreeScanner<Boolean, Void>() {
@Override
public Boolean visitThrow(ThrowTree tree, Void unused) {
if (Objects.equals(parameter, ASTHelpers.getSymbol(tree.getExpression()))) {
return true;
}
if (NEW_THROWABLE.matches(tree.getExpression(), state) && ((NewClassTree) tree.getExpression()).getArguments().stream().anyMatch(arg -> Objects.equals(parameter, ASTHelpers.getSymbol(arg)))) {
return true;
}
return super.visitThrow(tree, null);
}
@Override
public Boolean reduce(Boolean a, Boolean b) {
return firstNonNull(a, false) || firstNonNull(b, false);
}
}.scan(catchTree.getBlock(), null), false);
if (rethrows) {
return NO_MATCH;
}
Description.Builder description = buildDescription(tree);
buildFix(tryStatement, tree, state).ifPresent(description::addFix);
return description.build();
}
Aggregations