How to get parent tree object from JCTree in java?

421 Views Asked by At

How to get parent tree node from JCTree (com.sun.tools.javac.tree.JCTree) in Java?

For example:

public class MyTreeTranslator extends TreeTranslator {
     @Override
    public void visitMethodDef(JCTree.JCMethodDecl jcMethodDecl) {
         // get jcMethodDecl's parent tree
    }
}
2

There are 2 best solutions below

0
rzwitserloot On

You can't. The tree is one-way. Only strategy is to find the associated 'top' JCCompilationUnit and walk it recursively (this takes a very long time), keeping track of parentage. Then when you find the JCTree, you have the parent.

-- EDIT --

Paying a little closer attention to your snippet, you don't have to double-walk it here: Get rid of visitMethodDef entirely; instead, write a visitX method for every place a method can appear. Which, currently, is only within type definitions (visitTypeDef(JCTree.JCTypeDecl), I think). for-each through all the method defs defined in each (this will take some instanceof creativity, or alternatively invoking apply on it with a parameterized visitor).

0
vipcxj On

Noway, but in your case, there are many way to find the parent tree. Because the only type of tree containing the method declaration in java is class tree.

  1. just override the void visitClassDef(JCTree.JCClassDecl jcClassDecl).
  2. use api of JavacTrees
ProcessingEnvironment environment = ...
JavacTrees trees = JavacTrees.instance(environment);
// someElement get from the annotation processor
TreePath somePath = javacTrees.getPath(someElement);
// get compilation unit 
CompilationUnitTree cu = somePath.getCompilationUnit();
// get the path of tree. the tree must attach to the compilation unit.
TreePath path = trees.getPath(cu, tree);
if (path != null) {
    Element element = trees.getElement(path);
    Element parentElement = element.getEnclosingElement();
    // get tree of this parent element.
    JCTree treeElement = trees.getTree(parentElement);
}
  1. use sym field of JCMethodDecl. This field actually is the parentElement above. But it may be null sometimes. You can use TreeInfo.symbolOf to get this field. However if you have heavily changed the ast, this api may not work properly.