Java8,如何发现visitMethodInvocation中的类和方法名? [英] Java8, how discover the class and method name in visitMethodInvocation?

查看:24
本文介绍了Java8,如何发现visitMethodInvocation中的类和方法名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于 Java7 和 Java8,如果调用了某些方法,我想生成警告.如果用户编译时存在特定的 jar,则会打印警告.

With Java7 and Java8, I would like to generate a warning if some methods was called. The warning will be print if a specific jar is present when then user compile.

我编写了一个注解处理器并捕获了visitMethodInvocation().现在,我想提取将调用的类和方法名称.

I write an Annotation Processor and catch the visitMethodInvocation(). Now, I want extract the class and method names will be invoked.

可以这样做吗?或者如何解决这个问题?

Is it possible to do that ? Or how to approach this?

推荐答案

您可以执行以下操作:

package mystuff;

import com.sun.source.tree.*;
import com.sun.source.util.*;
import java.util.*;
import javax.annotation.processing.*;
import javax.lang.model.element.*;
import javax.tools.*;

@SupportedAnnotationTypes("*")
    public class Proc extends AbstractProcessor{
    @Override
        public boolean process(Set<?extends TypeElement>annotations,RoundEnvironment roundEnvironment){
        final Trees trees=Trees.instance(processingEnv);
        for(Element element:roundEnvironment.getRootElements()){
        TreePath path=trees.getPath(element);
        final CompilationUnitTree compilationUnit=path.getCompilationUnit();
        compilationUnit.accept(new TreeScanner<Object,Object>(){
            @Override
                public Object visitMethodInvocation(MethodInvocationTree tree,Object data){
                tree.getMethodSelect().accept(new SimpleTreeVisitor<Object,Object>(){
                    @Override
                    public Object visitMemberSelect(MemberSelectTree tree,Object data){
                    processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,String.format("class:  %1$s
method: %2$s",tree.getExpression(),tree.getIdentifier()));
                    return null;
                    }
                },null);
                return null;
            }
            },null);
        }
        return true;
    }
    }

我用那个处理器来处理下面的类

I used that processor to process the below class

package stuff;

import java.util.*;

@MyAnnotation
class MyProgram{
    public void run(){
    System.out.println("Hello World!");
    }
}

并取得了这个结果:

class:  System.out
  method: println

我很确定生成的方法名称正是您要查找的.我很确定班级"并不完全是您要找的,但它是一个不错的开始.

I am pretty sure that the method name generated is what you are looking for. I am pretty sure that the "class" is not exactly what you are looking for, but is a pretty good start.

在我的示例中,您可能希望它为类打印java.io.PrintStream".要获得它,您可以使用 processingEnv.getElementUtils().getTypeElement("java.lang.System") 来获取表示系统类的 TypeElement.然后你可以使用 processingEnv.getElementUtils().getAllMembers() 来获取系统类的每个成员.遍历它以找到 out.使用 asType 方法获取其类型.

In my example you probably wanted it to print "java.io.PrintStream" for the class. To get that you could use processingEnv.getElementUtils().getTypeElement("java.lang.System") to get a TypeElement representing the system class. Then you can use processingEnv.getElementUtils().getAllMembers() to get every single member of the system class. Iterate through that to find out. Use the asType method to get its type.

上一段是粗略的简化.处理器事先不知道 out 是一个类的静态成员,该类是隐式导入的 java.lang 包的一部分.因此,您的代码将不得不尝试并无法找到以下类 Systemjava.util.System(因为它在导入中),System.outjava.util.System.outjava.lang.System.out.

The preceding paragraph was a gross simplification. The processor did not know a priori that out is a static member of a class that is part of the implicitly imported java.lang package. So your code will have to try and fail to find the following classes System and java.util.System (because it is in the imports), System.out, java.util.System.out, and java.lang.System.out.

我只处理过 MemberSelect.您将不得不处理其他可能性,包括 MethodInvocation.例如 new Object().toString().hashCode() 应该是 class=Object, method=hashCode.

I only dealt with MemberSelect. You will have to deal with other possibilities including MethodInvocation. For example new Object().toString().hashCode() should be class=Object, method=hashCode.

这篇关于Java8,如何发现visitMethodInvocation中的类和方法名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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