You will get following output –
Yes, I know there are duplicates for object and closure – because they are first processed as variable names and then object/closure. This can be easily fixed, but I am going to leave it that way to keep the code simple.
I am not going to produce the complete source code here, but will explain some important parts of the program.
The program uses visitor pattern to first traverse AST and then to print symbol hierarchy. It contains following classes –
JSSymbol : This class holds reference to AST node and child elements. We will create hierarchy of objects of this class
JSNodeVisitor: implements Rhino’s NodeVisitor interface and builds hierarchy of JSSymbo
IJSSymbolVisitor : visitor interface for JSSymbol
JSSymbolVisitor : implements IJSSymbolVisitor and prints hierarchy of JSSymbol objects
JSErrorReporter : implements ErrorReporter interface of Rhino and prints syntax errors in the JS script
RhinoDemo : main program
paseJS function in RhinoDemo class parses the script and gets the AstRoot node. It then calls visit method of the root node, passing JSNodeVisitor to it. After building the symbol heir achy, it prints it using JSSymbolVisitor.
visit method of JSNodeVisistor calls addToParent method which actually builds symbol hierarchy
The above function uses Stack to keep track of current parent symbol (function or Object). It checks if the node being processed is child of the symbol at the top of functionsStack by comparing node’s absolute position (AstNode.getAbsolutePosition) with end offset of the current (top) symbol. Since AST is visited in depth first manner, this logic works fine.
Remaining code in this program is quite simple. Download Eclipse project for this program if you use Eclipse.
Again, I do not guarantee that the program will create error-free symbol hierarchy At best, use this code as a reference and modify it to suit your requirements. It is just one of the ways to create symbol heirachy and there could be better ways.