I am playing around with Java (javax) annotation processing.
Suppose I have an annotation for methods:
@Target(ElementType.METHOD)
public @interface MethodAnnotation { }
Now I want to process all the methods which are overridden from a type with the annotated method:
interface MyInterface() {
@MethodAnnotation
void f()
}
class MyClass implements MyInterface {
override void f() { } // <- I want to process this method
}
@Inherited
meta-annotation seems not to be suitable here:
Note that this meta-annotation type has no effect if the annotated type is used to annotate anything other than a class.
Also, is it possible to process an inherited class method which is not overridden in a subclass? Like this:
class MyClass {
@MethodAnnotation
void f() { }
}
class MySubClass extends MyClass { } // <- I want to process its f()
// or at least to find out that it doesn't
// override the method
How can I access the overriden methods of a certain method within AbstractProcessor
?
I guess, to achieve this I need to find subclasses of the eclosing class, but I haven't found a way to do this either.
UPD: I suppose it's possible using RoundEnvironment.getRootElements()
but still found no proper way of doing this.
The short answer is that out-of-the-box annotation processing isn't going to make this easy for you, but it can be done.
Rather than using the normal dispatch mechanism for processing, you're actually going to have to process every method and do the filtering yourself.
Define your processor so that it supports all annotations by using "*"
as its supported annotation type. This will mean that your processor will get invoked every round.
Use getRootElements
to get the entire set of elements every round.
Create an ElementScanner8
to traverse any element that you find to look for ExecutableElement
s. If you're willing to trust that overridden methods are annotated with @Override
, you can do a quick filter on those. Otherwise, just look at all of them.
Now you need to see if the method overrides a method with the annotation you're looking for. There's no easy way to get methods that a given method has overridden, so you need to get the enclosing element of the method, look at its superclass and implemented interfaces (recursively), get their enclosed elements, filter out the methods, and test to see if it has been overridden by the method in question. If it has, you can check the annotations to see if it has one you care about.
At this point, you should have the overriding method, the overridden method and the annotation mirror that you were looking for, so you should be able to implement whatever logic you wanted.