0

Longtime reader, first time poster here. I have been working on a project which requires me to use an annotation processor. I know that what I am doing is covered by AspectJ but unfortunately AspectJ requires using the AJC compiler and this causes certain headaches when working on some projects. Essentially the goal is given a method doSomething() with a body, I need to add some code above it's body and after the body if I annotate it with @SpecialMethod.

I assume that whoever is reading this is familiar with annotation processing, as to achieve this I have class which extends AbstractProcessor.

The full code is below:

public class MethodStatsAnnotationProcessor extends AbstractProcessor {

    private Trees trees;

    @Override
    public void init (ProcessingEnvironment processingEnv) {
        super.init( processingEnv );
        trees = Trees.instance( processingEnv );
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        for (TypeElement annotation : annotations) {
            Set<? extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(annotation);
            for(Element element : annotatedElements){
                processingEnv.getMessager().printMessage(Diagnostic.Kind.MANDATORY_WARNING,element.getSimpleName());
                processingEnv.getMessager().printMessage(Diagnostic.Kind.MANDATORY_WARNING,element.getKind().toString());
                MethodTree methodTree = (MethodTree) trees.getTree(element);
                BlockTree blockTree = methodTree.getBody();
                for (StatementTree statementTree : blockTree.getStatements()) {
                    processingEnv.getMessager().printMessage(Diagnostic.Kind.MANDATORY_WARNING,statementTree.toString());
                }
            }
            processingEnv.getMessager().printMessage(Diagnostic.Kind.MANDATORY_WARNING,annotation.getSimpleName());
        }
        return true;
    }
}

I know the code is very generic - so far the processor successfully prints out the method's name and the statements in the body, but I don't understand how I could add statements given that StatementTree is an interface which doesn't seem to have a very clear API. Ideally if anyone could provide even a simple hint such as how to add a System.out.println("Hello") at the start of the method body that would be highly appreciated. Thanks to everyone in advance.

  • Not a simple hint but you can look at [how Project Lombok does it](https://github.com/rzwitserloot/lombok), though I'm not familiar enough with it to be more specific. Of course, I'm not sure if they have anything that _modifies the body_ of a method or just mechanisms to _add_ methods (e.g. getters and setters) and fields (e.g. loggers). – Slaw Dec 21 '19 at 23:40
  • 2
    Unfortunately you cannot modify existing code using the public api. You can only add new files and new classes. So you would need to either use some sort of pattern where you generate a subclass or use non public apis. Project lombok is indeed a good example of this - I've poked around a bit but never gotten around to implementing anything. – jbunting Dec 23 '19 at 00:57

0 Answers0