注释处理器

Annotation Processor

我的 AnnotationProcessor 有问题。

首先是我的源代码:

@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;
  }
}

这个注释处理器收集了编译器的树。在这个处理器中,一切都很好。如果我在编译过程之后调用 funktion getTree,树是不完整的。 Tree(Node) 的所有 children 都离开了。

...
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();
...

感谢您的每一次帮助。

我找到了解决办法。树接口由 class com.sun.tools.javac.tree.JCTree 实现。 Class 实现了一个克隆方法。当我使用此方法时,编译过程后克隆完成:

@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;
  }
}