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.
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?
As an alternative to the great answer from @emory, you can consider using the pluggable type-checking annotation processing provided by the Checker Framework. The advantage is it can help you to easily determinate the type of the method invoker. Here is an example processor based on the checker framework (add checker.jar to the classpath when compile).
Which is processing the following input source.
Here is the output:
You can do something like:
I used that processor to process the below class
and achieved this result:
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 useprocessingEnv.getElementUtils().getAllMembers()
to get every single member of the system class. Iterate through that to findout
. Use theasType
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 importedjava.lang
package. So your code will have to try and fail to find the following classesSystem
andjava.util.System
(because it is in the imports),System.out
,java.util.System.out
, andjava.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.