Note that there are some explanatory texts on larger screens.

plurals
  1. POHow do I get the type of the expression in a MemberSelectTree from a javac plugin?
    primarykey
    data
    text
    <p>I am trying to write an annotation processor in the JSR 269 format which uses javac's Compiler Tree API to do some source code analysis. I am interested in member select expressions, such as method calls.</p> <p>I can easily get the name of the method (or field, etc.) being selected. But I want to know what type the member is being selected from, and I cannot seem to find a straightforward way to do this. <code>Trees.getTypeMirror</code> returns <code>null</code> for everything I try calling it on (and the Javadoc gives no hints).</p> <p>I suppose I could exhaustively analyze every kind of expression on the left side of the member select and determine the static type of the expression by recursive analysis: <code>NewClassTree</code>, <code>TypeCastTree</code>, <code>MethodInvocationTree</code>, <code>ArrayAccessTree</code>, and many others. But this seems like a lot of error-prone work, and clearly javac already knows the static type of the expression since it needs this information for many purposes. But how do I get access to this type information?</p> <p>What I have so far:</p> <pre><code>import com.sun.source.tree.MemberSelectTree; import com.sun.source.tree.MethodInvocationTree; import com.sun.source.util.TreePath; import com.sun.source.util.TreePathScanner; import com.sun.source.util.Trees; import java.util.Set; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.annotation.processing.SupportedSourceVersion; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; @SupportedAnnotationTypes("*") @SupportedSourceVersion(SourceVersion.RELEASE_6) public class PublicProcessor extends AbstractProcessor { public @Override boolean process(Set&lt;? extends TypeElement&gt; annotations, RoundEnvironment roundEnv) { for (Element e : roundEnv.getRootElements()) { final Trees trees = Trees.instance(processingEnv); final TreePath root = trees.getPath(e); new TreePathScanner&lt;Void,Void&gt;() { public @Override Void visitMethodInvocation(MethodInvocationTree node, Void p) { System.err.println("visiting method invocation: " + node + " of kind: " + node.getMethodSelect().getKind()); TreePath expr = TreePath.getPath(root, node); System.err.println(" of type: " + trees.getTypeMirror(expr)); return super.visitMethodInvocation(node, p); } public @Override Void visitMemberSelect(MemberSelectTree node, Void p) { System.err.println("accessing member: " + node.getIdentifier()); System.err.println(" from: " + getCurrentPath().getCompilationUnit().getSourceFile().toUri()); TreePath expr = TreePath.getPath(root, node.getExpression()); System.err.println(" in expr: " + expr.getLeaf()); System.err.println(" of type: " + trees.getTypeMirror(expr)); return super.visitMemberSelect(node, p); } }.scan(root, null); } return true; } } </code></pre> <p>and what it prints when run on some simple code making method calls:</p> <pre><code>visiting method invocation: new Class().method() of kind: MEMBER_SELECT of type: null accessing member: method from: .../Whatever.java in expr: new Class() of type: null </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload