Search code examples
javaannotation-processingjava-compiler-api

Annotation Processor


I have a problem with an AnnotationProcessor.

First my sourcecode:

@SupportedAnnotationTypes("*")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class TreeAnnotationProcessor extends AbstractProcessor{

  private Trees trees;
  private Tree tree;

  @Override
  public synchronized void init(ProcessingEnvironment processingEnv) {
    super.init(processingEnv);
    trees = Trees.instance(processingEnv);
  }

  @Override
  public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    for (Element element : roundEnv.getRootElements()) {
      tree = trees.getTree(element);
    }

    return true;
  }

  public Tree getTree() {
    return tree;
  }
}

This Annotationprocessor Collect a Tree of the Compiler. In this Processor ist everything fine. If I call the funktion getTree after the compiling process, the Tree is not complete. All the children of the Tree(Node) are away.

...
JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, null, null, compilationUnits);
TreeAnnotationProcessor treeAnnotationProcessor = new TreeAnnotationProcessor();
task.setProcessors(Collections.singletonList(treeAnnotationProcessor));
task.call();
Tree tree = treeAnnotationProcessor.getTree();
...

Thank you for every help.


Solution

  • I found a solution. The Tree-interface is implemented by the class com.sun.tools.javac.tree.JCTree. This Class implement a clone-Method. When I use this Method, the clone is complete after the compiling process:

    @SupportedAnnotationTypes("*")
    @SupportedSourceVersion(SourceVersion.RELEASE_8)
    public class TreeAnnotationProcessor extends AbstractProcessor{
    
      private Trees trees;
      private Tree tree;
    
      @Override
      public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        trees = Trees.instance(processingEnv);
      }
    
      @Override
      public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        for (Element element : roundEnv.getRootElements()) {
          tree = trees.getTree(element);
    
          try {
            Method cloneMethod = tree.getClass().getMethod("clone");
            Object cloneTree = cloneMethod.invoke(tree);
            this.tree = (Tree) cloneTree;
          } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
          }
        }
    
        return true;
      }
    
      public Tree getTree() {
        return tree;
      }
    }