How to process annotations using @Target (ElementType.TYPE_USE)?

I implement an annotation processor to make sure that elements marked with annotation are instances of a class that implements a specific interface, or that use types that implement a specific interface:

@Documented @Target(value = { ElementType.PARAMETER, ElementType.TYPE_USE }) @Retention(value = RetentionPolicy.RUNTIME) public @interface AuditSubject { } public interface Auditable { // methods that provide data for writing a log entry... } public class Report implements Auditable { } 

For annotated items, a journal entry must be created after the method is executed (using AOP). Examples:

 @CreateLogEntry public Result persist(@AuditSubject Report newReport) { // A log entry must be created based on the incoming 'newReport' instance. } @CreateLogEntry public UpdateResult<@AuditSubject Report> update(Report update) { // A log entry must be created based on the updated report, which is not the same instance as 'update' but an equivalent one. } @CreateLogEntry public Result persistBatch(List<@AuditSubject Report> batch) { // A log entry must be created for each element in 'batch' after this method execution. } 

Journal entries must be created provided that Report implements Auditable ; if it is not, a runtime exception is thrown (Yikes, I forgot to implement the interface!). In this way, the annotation processor helps catch programmer errors during compilation. So far, I have successfully tested all uses in parameters, but not in the use of types. The corresponding code from the annotation processor is as follows:

 @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { for (Element annotated : roundEnv.getElementsAnnotatedWith(AuditSubject.class)) { // Only prints elements with ElementKind.PARAMETER)! this.messager.printMessage(Kind.NOTE, TextUtils.replaceParams("annotated: {} ; Kind : {} ; enclosing : {}", annotated, annotated.getKind(), annotated.getEnclosingElement())); if (annotated.getKind() == ElementKind.PARAMETER) { // Code here works as expected, raises errors for annotated parameters of classes that don't implement Auditable. } else if (annotated.getKind() == ElementKind.WHAT_TO_USE) { // What ElementKind do I need to use here? } } return false; } 

ElementKind.PARAMETER only annotated elements with the view ElementKind.PARAMETER (the first line in the process loop () prints only one line for 'newReport' ). How can I verify that annotated types implement Auditable ? There is no constant " ElementKind.TYPE_USE " to use. I could not find any relevant information on this. Thank you for attention.

+7
source share
1 answer

The Java Annotation API was developed when Java only supported annotations in declarations. The API only supports visit announcements, such as fields, methods, and method parameters. It does not visit local variable declarations, other annotations in the method body, and type annotations.

If you want to process type annotations or annotations inside the method bodies, you need to write your own code to repeat the types or to check the lines of code in the method.

An alternative to this is to use a tool like the Checker Framework . It implements its own visitors, and therefore the annotation processor built on it is invoked for each occurrence of type annotation.

+5
source

Source: https://habr.com/ru/post/1264087/


All Articles