public JsFunction mapFunction(Node fnNode) throws JsParserException { int nodeType = fnNode.getType(); assert nodeType == TokenStream.FUNCTION : "Expected function node, got: " + TokenStream.tokenToName(nodeType); Node fromFnNameNode = fnNode.getFirstChild(); Node fromParamNode = fnNode.getFirstChild().getNext().getFirstChild(); Node fromBodyNode = fnNode.getFirstChild().getNext().getNext(); JsFunction toFn = scopeContext.enterFunction(); // Decide the function's name, if any. // String fnNameIdent = fromFnNameNode.getString(); if (fnNameIdent != null && fnNameIdent.length() > 0) { scopeContext.globalNameFor(fnNameIdent); } while (fromParamNode != null) { String fromParamName = fromParamNode.getString(); JsName name = scopeContext.localNameFor(fromParamName); toFn.getParameters().add(new JsParameter(name)); fromParamNode = fromParamNode.getNext(); } // Map the function's body. // JsBlock toBody = mapBlock(fromBodyNode); toFn.setBody(toBody); scopeContext.exitFunction(); return toFn; }
private JsVars mapVar(Node varNode) throws JsParserException { JsVars toVars = new JsVars(); Node fromVar = varNode.getFirstChild(); while (fromVar != null) { // Use a conservative name allocation strategy that allocates all names // from the function's scope, even the names of properties in field // literals. // String fromName = fromVar.getString(); JsName toName = scopeContext.localNameFor(fromName); JsVars.JsVar toVar = new JsVars.JsVar(toName); Node fromInit = fromVar.getFirstChild(); if (fromInit != null) { JsExpression toInit = mapExpression(fromInit); toVar.setInitExpression(toInit); } toVars.add(toVar); fromVar = fromVar.getNext(); } return toVars; }
private JsStatement mapForStatement(Node forNode) throws JsParserException { Node fromInit = forNode.getFirstChild(); Node fromTest = fromInit.getNext(); Node fromIncr = fromTest.getNext(); Node fromBody = fromIncr.getNext(); if (fromBody == null) { // This could be a "for...in" structure. // We could based on the different child layout. // Node fromIter = forNode.getFirstChild(); Node fromObjExpr = fromIter.getNext(); fromBody = fromObjExpr.getNext(); JsForIn toForIn; if (fromIter.getType() == TokenStream.VAR) { // A named iterator var. // Node fromIterVarName = fromIter.getFirstChild(); String fromName = fromIterVarName.getString(); JsName toName = scopeContext.localNameFor(fromName); toForIn = new JsForIn(toName); Node fromIterInit = fromIterVarName.getFirstChild(); if (fromIterInit != null) { // That has an initializer expression (useful only for side effects). // toForIn.setIterExpression(mapOptionalExpression(fromIterInit)); } } else { // An unnamed iterator var. // toForIn = new JsForIn(); toForIn.setIterExpression(mapExpression(fromIter)); } toForIn.setObjectExpression(mapExpression(fromObjExpr)); // The body stmt. // JsStatement bodyStmt = mapStatement(fromBody); if (bodyStmt != null) { toForIn.setBody(bodyStmt); } else { toForIn.setBody(JsEmpty.INSTANCE$); } return toForIn; } else { // Regular ol' for loop. // JsFor toFor; // The first item is either an expression or a JsVars. JsNode init = map(fromInit); JsExpression condition = mapOptionalExpression(fromTest); JsExpression increment = mapOptionalExpression(fromIncr); assert (init != null); if (init instanceof JsVars) { toFor = new JsFor((JsVars) init, condition, increment); } else { assert (init instanceof JsExpression); toFor = new JsFor((JsExpression) init, condition, increment); } JsStatement bodyStmt = mapStatement(fromBody); if (bodyStmt != null) { toFor.setBody(bodyStmt); } else { toFor.setBody(JsEmpty.INSTANCE$); } return toFor; } }