Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I refer to implementations of a method in annotation processing?

Tags:

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.

like image 263
hotkey Avatar asked Jul 10 '16 12:07

hotkey


People also ask

What does the annotation processor do?

Our annotation processor will catch all these Todo annotations at compile time and fails the compilation. This will help developers to either implement this method or if it is already implemented then developer should remove it so the compilation will succeed.

How to create and process annotation in Java?

This annotation acts like tagging. We will go through below steps to create and process annotations: Create a new java file Todo.java to declare an annotation. Annotation declaration looks similar to interface except the keyword interface is preceded with @ Todo annotation is declared with two meta-annotations.

How to indicate errors in the annotation processing?

This class provides a Messager which can be used to indicate errors in the annotation processing. In this case we printed the error message which contains value of the Todo annotation and the method name on which it is used. <9> true is returned to mention that we complemented our processing.

Do annotations change the action of a compiled program?

Annotations do not change the action of a compiled program. Annotations help to associate metadata (information) to the program elements i.e. instance variables, constructors, methods, classes, etc. Annotations are not pure comments as they can change the way a program is treated by the compiler.


1 Answers

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.

Step 1:

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.

Step 2:

Use getRootElements to get the entire set of elements every round.

Step 3:

Create an ElementScanner8 to traverse any element that you find to look for ExecutableElements. 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.

Step 4:

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.

Step 5:

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.

like image 90
gk5885 Avatar answered Oct 11 '22 19:10

gk5885