Summary
ForwardingAstVisitor
has life cycle- visitXxx -> afterXxx -> endXxx
- Begin
visitCompilationUnit
, EndafterVisitCompilationUnit
- Go from top to bottom. No surprise, except annotation.
- Does not talk about visitIf or any of visitXxx where Xxx is keyword
Motivation
The past few weeks, I am working on creating custom lints for PermissionsDispatcher.
Using ForwardingAstVisitor
is the easiest way to implement custom lint. I found there are 75 “visit” methods in the class. For instance, visitMethodDeclaration
is called for iterating all method declarations. visitIdentifier
is for all identifiers. Trust me, there is even visitIf
and visitSwitch
that are called for each if
and switch
.
However, I could not find any documentations that describes which “visit” method comes first. So…this is the post that describes what is the “lifecycle” of ForwardingAstVisitor
.
Basic Rules
There are 4 types of methods, visit
, visitNode
, afterVisit
, endVisit
for ForwardingAstVisitor
.
visitXxx
comes firstvisitNode
comes second for dive into the nodeafterVisitXxx
comes if there is no more method call insidevisitXxx
- Finally,
endVisit
comes for wrap up.
For instance, followings are the method call for checking @Override
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
General Rules
Now, let see what’s happens if I want to lint check for a Java file.
Assuming I am going to check following class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
Here is the debuging code. It’s basically Sys-out method name and node
parameter. And the output is this
OK, Too long…let me summarize idea.
- The first visit-method is
visitCompilationUnit
- Next it checks
visitPackageDeclaration
forpackage pkg;
(Meaning, it starts from the first line of the class) - And goes one by one until it reaches the bottom of the class
- The last after-method is
afterVisitCompilationUnit
Exceptional Rules
Now, we know the lint checks goes the top to the bottom. However, there is an exception, Annotation.
@RuntimePermissions
which is located the above of the class declaration in the example above.
Actually, when we run the lint checks, visitClassDeclaration
comes first and then visitAnnotation
comes later.
It seems that the lint handles annotation as a node inside of method declaration.
For example, if we want to store class declaration object which @RuntimePermissions
, we cannot do followings:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
Instead, I would use afterVisitClassDeclaration
and call requestRepeat
to run other detector which uses class declaration objects.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|