run*_*1ME 6 java preprocessor annotations javac
我正在为我们的构建系统编写一些工具,以对属于包含某些注释的类的方法强制执行一些严格的调用约定.
我正在使用编译器树API ...
我想知道的是当遍历'tree'时,你怎么能告诉MethodInvocation的类/接口的类型.
我将TreePathScanner子类化为:
@Override
public Object visitMethodInvocation(MethodInvocationTree node, Trees trees) {
}
Run Code Online (Sandbox Code Playgroud)
我希望有一种方法可以告诉您尝试调用该方法的类(或接口)的类型.我是以错误的方式来做这件事的吗?谢谢你的任何想法......
not*_*oop 10
这里有几个问题.您可能有兴趣知道方法调用接收器的Java类型,或者只是知道调用该方法的类.Java信息更具信息性,因为它也为您提供了泛型类型,例如List<String>
,Elements只会为您提供类,例如List<E>.
获得元素
要获取调用该方法的类的元素,您可以执行以下操作:
MethodInvocationTree node = ...;
Element method =
TreeInfo.symbol((JCTree)node.getMethodSelect());
TypeElement invokedClass = (TypeElement)method.getEnclosingElement();
Run Code Online (Sandbox Code Playgroud)
拐角案件:
1. invokedClass可能是接收器类型的超类.所以运行代码片段new ArrayList<String>.equals(null)会返回
AbstractList而不是ArrayList,因为equals()是AbstractList不实现的ArrayList.
2.处理数组调用时,例如new int[].clone(),你会得到TypeElement类Array.
获得实际类型
要获得类型,没有直接的方法来确定接收器类型是什么.在内部类中处理方法调用存在一些复杂性,其中未明确给出接收器(例如,不同OuterClass.this.toString()).这是一个示例实现:
MethodInvocationTree node = ...;
TypeMirror receiver;
if (methodSel.getKind() == Tree.Kind.MEMBER_SELECT) {
ExpressionTree receiver = ((MemberSelectTree)methodSel).getExpression();
receiverType = ((JCTree)receiver).type;
} else if (methodSel.getKind() == Tree.Kind.IDENTIFIER) {
// need to resolve implicit this, which is described in
// JLS3 15.12.1 and 15.9.2
// A bit too much work that I don't want to work on now
// Look at source code of
// Attr.visitApply(JCMethodInvocation)
// resolveImplicitThis(DiagnosticPosition, Env, Type)
} else
throw new AssertionError("Unexpected type: " + methodSel.getKind());
Run Code Online (Sandbox Code Playgroud)
注意:
不幸的receiver是,这种类型TypeMirror不是必须的DeclaredType.拨打电话时new int[5].clone(),receiver将是一个ArrayType的int[],这比以前的方法更多的信息.
让它运行
以上两种方法都要求编译器解析类的类型信息.在通常情况下,编译器仅解析方法声明的类型而不解析主体.因此,前面描述的方法将返回null.
要让编译器解析类型信息,您可以执行以下方法之一:
1.使用AbstractTypeProcessor刚刚添加到JDK 7的编译器存储库中的类.查看有关JSR 308及其编译器的工作.虽然工作主要是注释类型,但它可能是有用的.编译器允许您以与Java 5向后兼容的方式使用提供的类.
此方法允许您编写与当前处理器一样调用的处理器.
2. JavacTask改为使用并致电JavacTask.analyze().查看此javac测试的主要方法,了解如何在类上调用访问者.
这种方法使您的处理器看起来更像分析工具而不是编译器的插件,因为您需要直接调用它而不是将其作为常规进程.
| 归档时间: |
|
| 查看次数: |
2441 次 |
| 最近记录: |