ppr*_*dos 3 java annotations javac
对于 Java7 和 Java8,如果调用了某些方法,我想生成警告。如果用户编译时存在特定的 jar,则将打印警告。
我编写了一个注释处理器并捕获了visitMethodInvocation()。现在,我想提取将调用的类和方法名称。
有可能这样做吗?或者如何解决这个问题?
您可以执行以下操作:
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\nmethod: %2$s",tree.getExpression(),tree.getIdentifier()));
return null;
}
},null);
return null;
}
},null);
}
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
我用那个处理器来处理下面的类
package stuff;
import java.util.*;
@MyAnnotation
class MyProgram{
public void run(){
System.out.println("Hello World!");
}
}
Run Code Online (Sandbox Code Playgroud)
并取得了这个结果:
class: System.out
method: println
Run Code Online (Sandbox Code Playgroud)
我很确定生成的方法名称正是您要查找的。我很确定“班级”并不完全是您要找的,但它是一个不错的开始。
在我的示例中,您可能希望它为类打印“java.io.PrintStream”。要获得它,您可以使用processingEnv.getElementUtils().getTypeElement("java.lang.System")获取表示系统类的 TypeElement。然后你可以使用processingEnv.getElementUtils().getAllMembers()来获取系统类的每个成员。遍历它以找到out. 使用该asType方法获取其类型。
上一段是粗略的简化。处理器不知道作为out隐式导入的一部分的类的静态成员的先验java.lang包。因此,您的代码将不得不尝试但无法找到以下类System和java.util.System(因为它在导入中)System.out、java.util.System.out、 和java.lang.System.out。
我只处理过 MemberSelect。您将不得不处理其他可能性,包括 MethodInvocation。例如new Object().toString().hashCode()应该是class=Object,method=hashCode。