You can do something like:
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!");
}
}
and achieved this result:
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.
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.
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
.
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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…