protected void recursiveParse(Node node) { // Ignore null nodes or those we have seen before! if (node == null || parsedNodes.contains(node)) { return; } // Script level nodes have global list of function definitions. // Parse inner tokens for function definitions here. if (node instanceof ScriptOrFnNode) { ScriptOrFnNode sofn = (ScriptOrFnNode) node; int count = sofn.getFunctionCount() - 1; while (count > -1) { FunctionNode fn = sofn.getFunctionNode(count); recursiveParse(fn); count--; } } // Parse children from left to right. recursiveParse(node.getFirstChild()); recursiveParse(node.getLastChild()); // Parse this node and then move along to next parseNode(node); parsedNodes.add(node); recursiveParse(node.getNext()); }
protected Map<String, String> findLiteralStringValues(Node objLiteral) { Map<String, String> literalValues = new HashMap<String, String>(); // Find object literal keys from property list. Object[] propertyList = (Object[]) objLiteral.getProp(Token.EQ); // Iterate through each literal key, extracting associated value. Ignore // any non-string values, we aren't attempting inner-resolution of references. if (propertyList != null) { int numArgs = 0; // Child nodes are linked list of object values Node propertyValue = objLiteral.getFirstChild(); while (numArgs < propertyList.length) { // Convert key/value pairs into a handy format if (propertyValue.getType() == Token.STRING) { literalValues.put((String) propertyList[numArgs], propertyValue.getString()); } propertyValue = propertyValue.getNext(); numArgs++; } } return literalValues; }
// Given child nodes for a function call, object ref and arguments, return // the string value for the first argument. Ignore any complicated resolution. protected String functionCallArgument(Node functionCallNodes, int argIndex) { String fnCallArg = null; // Traverse argument nodes until we reach desired one. Node argument = functionCallNodes.getNext(); while (argument != null && argIndex > 0) { argument = argument.getNext(); argIndex--; } ; // Check we have a simple type value. if (argument != null && argument.getType() == Token.STRING) { fnCallArg = argument.getString(); } return fnCallArg; }
// Extract property name accessed. Will have two child nodes, // object reference and property name. Ignore any further // variable resolution. protected String functionPropertyName(Node propertyLookup) { String propertyName = null; // First argument is an object reference that lookup should be // performed against. Node objectReference = propertyLookup.getFirstChild(); if (objectReference != null) { // Find property identifier we are retrieving... Node propertyNameNode = objectReference.getNext(); // Only handle explicit string properties, we cannot resolve variables. if (propertyNameNode != null && propertyNameNode.getType() == Token.STRING) { propertyName = propertyNameNode.getString(); } } return propertyName; }
// Find an object literal's value for a given key. If not found, // return null. protected Node findLiteralValue(Node objLiteral, String key) { Node literalValueNode = null; // Get list of all properties Object[] propertyList = (Object[]) objLiteral.getProp(Token.EQ); // Iterate through key/values looking for a match if (propertyList != null) { Node propertyValue = objLiteral.getFirstChild(); for (int index = 0; index < propertyList.length; index++) { if (key.equals(propertyList[index])) { literalValueNode = propertyValue; break; } propertyValue = propertyValue.getNext(); } } return literalValueNode; }