After digging through Parser.java and IRFactory.java I finally figured
out how to do this.  It might not be the best approach but it's the
only one I've found so far.

When the Parser is building the tree it only adds the property values
to the node tree and puts the property names in a "prop" value on the
Node.  So when the code gets to the OBJECTLIT Node, it needs to
retrieve that property name list
( "node.getProp(Node.OBJECT_IDS_PROP)" ) and keep an index counter as
it loops through the property values.  Here's my new JavaCode (having
properties as a global variable is not a good idea and will break on
nested Object Literals, I indent to refactor that):

/* ------- CODE START ------- */
public static Object[] properties = new Object[0];
public static void readTree(ScriptOrFnNode tree, Node parent, int
indent, int funcIndex){
    Node node = null;
    int propertyIndex = 0;

    // Generate indent padding
    String padding = "";
    for(int i = 0; i < indent; i++){
        padding += "\t";
    }

    // Loop through sibling nodes
    for (;;) {

        // Get node
        Node previous = null;
        if (node == null) {
            node = parent.getFirstChild();
        } else{
            previous = node;
            node = node.getNext();
        }
        if (node == null) {
            break;
        }

        String val = "";
        int type = node.getType();
        int parentType = parent.getType();

        if(type == Token.STRING || type == Token.NAME || type ==
Token.FUNCTION){
            val = node.getString();
        }

        // Print node description
        if(parentType == Token.OBJECTLIT && properties.length >
propertyIndex){
            System.out.println(padding +"["+ node.getLineno() +":"+
node.getOffset() +"] "+ (String)properties[propertyIndex++] +" : "+
Token.name(type) +" "+ val);
        }
        else{
            System.out.println(padding +"["+ node.getLineno() +":"+
node.getOffset() +"] "+ Token.name(type) +" "+ val);
        }

        // Get object literal property names
        if(type == Token.OBJECTLIT){
            properties = (Object[])node.getProp(Node.OBJECT_IDS_PROP);
        }

        // Traverse into function node
        if(type == Token.FUNCTION){
            ScriptOrFnNode func = tree.getFunctionNode(funcIndex++);
            readTree(func, func, indent + 1, 0);
        }


        // Get children
        readTree(tree, node, indent + 1, funcIndex);

        // Reset properties
        if(type == Token.OBJECTLIT){
            properties = new Object[0];
        }
    }
}
/* ------- CODE END ------- */

And the output looks like this:

[53:365] VAR
        [-1:-1] NAME User
                [-1:-1] OBJECTLIT
                        [-1:-1] id : NUMBER
                        [-1:-1] balance : NUMBER
                        [-1:-1] name : STRING John Doe


Please let me know if you know of an easier way.
_______________________________________________
dev-tech-js-engine-rhino mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-js-engine-rhino

Reply via email to