Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从javac插件获取MemberSelectTree中的表达式类型?_Java_Javac_Annotation Processing - Fatal编程技术网

如何从javac插件获取MemberSelectTree中的表达式类型?

如何从javac插件获取MemberSelectTree中的表达式类型?,java,javac,annotation-processing,Java,Javac,Annotation Processing,我正在尝试以JSR269格式编写一个注释处理器,它使用javac的编译器树API来进行一些源代码分析。我对成员选择表达式感兴趣,例如方法调用 我可以很容易地获得所选方法(或字段等)的名称。但我想知道该成员是从哪种类型中选择的,我似乎找不到一个简单的方法来做到这一点Trees.getTypeMirror对我尝试调用它的所有内容返回null(Javadoc没有给出任何提示) 我想我可以详尽地分析成员左侧的每种表达式,通过递归分析选择并确定表达式的静态类型:NewClassTree、typecastr

我正在尝试以JSR269格式编写一个注释处理器,它使用javac的编译器树API来进行一些源代码分析。我对成员选择表达式感兴趣,例如方法调用

我可以很容易地获得所选方法(或字段等)的名称。但我想知道该成员是从哪种类型中选择的,我似乎找不到一个简单的方法来做到这一点
Trees.getTypeMirror
对我尝试调用它的所有内容返回
null
(Javadoc没有给出任何提示)

我想我可以详尽地分析成员左侧的每种表达式,通过递归分析选择并确定表达式的静态类型:
NewClassTree
typecastree
MethodInvocationTree
ArrayAccessTree
,以及许多其他类型。但是这看起来像是很多容易出错的工作,显然javac已经知道表达式的静态类型,因为它需要这些信息用于许多目的。但是我怎样才能获得这种类型的信息呢

到目前为止,我所拥有的:

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<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        for (Element e : roundEnv.getRootElements()) {
            final Trees trees = Trees.instance(processingEnv);
            final TreePath root = trees.getPath(e);
            new TreePathScanner<Void,Void>() {
                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;
    }
}


似乎正在解决一个非常类似的问题,所以我将尝试使用这里给出的建议。不幸的是,它看起来并不简单,而且似乎需要使用
com.sun.tools.javac
包。

似乎可以工作,但只能在JDK 7下工作。我无法使用JDK6的javac让它工作。我被困在同一个问题上,无法使用Jdk7。您最终用Jdk1.6找到了这个问题的解决方案了吗?谢谢这个问题,它是编译器树API的一个非常简洁的示例。作为记录,上面的
processingev
来自一个
init(ProcessingEnvironment)
方法,该方法也应该被覆盖。哦,JRockit 1.6.029仍然显示“null”。在大多数情况下,不需要重写
AbstractProcessor.init
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