探索类的MethodInvocation的注解处理器中的Java [英] Discover the class of a methodinvocation in the Annotation Processor for java

查看:1333
本文介绍了探索类的MethodInvocation的注解处理器中的Java的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一些工具,我们的编译系统执行在属于含有某些注释类方法的一些严格的调用约定。

I am writing some tools for our build system to enforce some strict calling conventions on methods belonging to classes containing certain annotations.

我使用的编译器API树...

I'm using the Compiler Tree API...

我不知道遍历'树',你怎么能告诉类/接口的的MethodInvocation的类型时是。

What i'm wondering is when traversing the 'tree', how can you tell the type of class/interface for a MethodInvocation.

我继承与TreePathScanner:

I'm subclassing TreePathScanner with :

@Override
public Object visitMethodInvocation(MethodInvocationTree node, Trees trees) {

}

我希望那里有一种方法来告诉你要调用方法的类(或接口)的类型。我要对这个错误的方式?感谢您的任何想法......

I'm hoping theres a way to tell the type of the class(or interface) that you're trying to invoke the method on. Am I going about this the wrong way? Thanks for any ideas...

推荐答案

有几个问题在这里。你可以有兴趣
知道方法调用接收器或只是Java类型
了解关于此方法的类被调用。 Java的信息更
信息因为它给你泛型类型为好,例如列表与LT;弦乐>
虽然元素将只为您提供一流的,例如列表< E>

There are a couple of issues here. You can either be interested in knowing the Java type of the method invocation receiver or just knowing the class on the method is invoked. Java information is more informative as it gives you generic types as well, e.g. List<String> while Elements would only provide you with the class, e.g. List<E>.

获取元素

要获得方法是在调用类的元素,你可以做
以下内容:

To get the Element of the class the method is invoked on, you can do the following:


  MethodInvocationTree node = ...;
  Element method =
        TreeInfo.symbol((JCTree)node.getMethodSelect());
  TypeElement invokedClass = (TypeElement)method.getEnclosingElement();

角情况:

1。
invokedClass可能是接收器类型的一个超类。因此运行
字符串&GT; .equals(空)将返回关于新的ArrayList&LT片段
的AbstractList ,而不是的ArrayList ,因为equals()方法实现
的AbstractList 不是的ArrayList

1. invokedClass might be a superclass of the receiver type. So running the snippet on new ArrayList<String>.equals(null) would return AbstractList rather than ArrayList, since equals() is implemented in AbstractList not ArrayList.

2。
当处理数组调用,例如新INT []的clone(),你会
获得 TypeElement 类的<​​code>阵列

获取实际类型

要获取类型,没有确定它是什么没有直接的方法
接收器类型。有一些处理方法调用的复杂性
其中,接收器没有明确给出内部类中
(例如不同于 OuterClass.this.toString())。下面是一个示例实现:

To get the type, there is no direct way for determining it what the receiver type is. There is some complexity in handling method invocations within inner classes where the receiver is not given explicitly (e.g. unlike OuterClass.this.toString()). Here is a sample implementation:


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

请注意:

接收类型必须 TypeMirror的不是的declaredType
不幸。打电话时新INT [5] .clone()接收
一个将ArrayType INT [] ,这是比previous更多的信息
方法。

The receiver type needs to be TypeMirror not DeclaredType unfortunately. When calling new int[5].clone(), receiver would be an ArrayType of int[], which is more informative than the previous method.

获取其运行

两者的previous方法需要编译器以解决此类型
对于类的信息。在通常的情况下,编译器
唯一解决方法声明的类型,但没有尸体。
因此,前面描述的方法将返回代替。

Both of the previous methods require the compiler to resolve the type information for the classes. In usual circumstances, the compiler only resolve the types for method declarations but not the bodies. Hence, the methods described earlier would return null instead.

要具备化解编译类型的信息,你可以做一个
以下几种方式:

To have the compiler resolve the type information, you can do one of the following ways:

1。
使用 AbstractTypeProcessor ​​类,刚刚加入到
编译器存储库JDK 7,检查各项工作的 JSR
308
和他们的编译器。
虽然工作主要是对注解的类型,它可能是很有用的。
编译器允许您使用提供的类处于落后
兼容的方式与Java 5。

1. Use AbstractTypeProcessor class that just got added to the compiler repository for JDK 7. Check out the work on JSR 308 and their compiler. While the work is mainly on annotated types, it might be useful for. The compiler allows you to use the provided class in a backward compatible manner with Java 5.

这个方法允许你写得到的只是调用处理器
喜欢你目前的处理器。

This approach allows you to write processors that get invoked just like your current processors.

2。
使用 JavacTask ,而不是和呼叫 JavacTask.analyze()。看着
的主要方法<一href=\"http://hg.openjdk.java.net/jdk7/jdk7/langtools/file/6855e5aa3348/test/tools/javac/api/6557752/T6557752.java\">this javac的测试怎么看
来调用类的访问者。

2. Use JavacTask instead and call JavacTask.analyze(). Look at the main method of this javac test to see how to invoke your visitor on the classes.

此方法使您的处理器看起来更像一个分析工具
而不是一个插件来编译,因为你需要调用它
而不是直接把它成为一个经常性进程。

This approach makes your processor look more like an analysis tool rather than a plug-in to the compiler, as you would need to invoke it directly rather than have it be a regular process.

这篇关于探索类的MethodInvocation的注解处理器中的Java的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆