Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get method body from ExecutableElement

In my AbstractProcessor I am able to get all methods from a class annotated with some annotation, I have created:

List<? extends Element> allElements = processingEnv.getElementUtils().getAllMembers((TypeElement) bean);
List<ExecutableElement> methods = ElementFilter.methodsIn(allElements);

Is is possible to get the body of the method/ExecutableElement? The API only seem to deal with the signature and modifiers.

I could probably use some variation of this answer to access classes from the proprietary .sun.* package, such as com.sun.tools.javac.tree.JCTree$MethodTree:

MethodTree methodTree = trees.getTree(executableElement);

where trees is an instance of com.sun.source.util.Trees set in the AbstractProcessor's init() method as so:

trees = Trees.instance(processingEnv);

But these classes come with the warning:

This is NOT part of any supported API. If you write code that depends on this, you do so at your own risk. This code and its internal interfaces are subject to change or deletion without notice.

I would hope that it was possible to access an annotated method's body from within the more general annotation processing framework.

like image 255
Hervian Avatar asked Jul 29 '16 11:07

Hervian


1 Answers

To my knowledge, the annotation framework does not support accessing an ExecutableElement´s body. It would be tempting to call getEnclosedElements(), but as the javadoc states:

Returns the elements that are, loosely speaking, directly enclosed by this element. A class or interface is considered to enclose the fields, methods, constructors, and member types that it directly declares. A package encloses the top-level classes and interfaces within it, but is not considered to enclose subpackages. Other kinds of elements are not currently considered to enclose any elements; however, that may change as this API or the programming language evolves.

For my project, I managed to extract the information I needed from the method body as follows:

MethodTree methodTree = trees.getTree(executableElement);
BlockTree blockTree = methodTree.getBody();
for (StatementTree statementTree : blockTree.getStatements()) {
  // *do something with the statements*
}

where com.sun.source.util.Trees trees = Trees.instance(processingEnv); is an instance field I set in the AbstractProcessor's init() method.

See this answer for information about the dependency to the referenced JDK tool classes.

like image 192
Hervian Avatar answered Nov 05 '22 13:11

Hervian