Summary
ForwardingAstVisitorhas 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.
visitXxxcomes firstvisitNodecomes second for dive into the nodeafterVisitXxxcomes if there is no more method call insidevisitXxx- Finally,
endVisitcomes 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
visitPackageDeclarationforpackage 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 | |