Search in sources :

Example 1 with ArrayComprehensionLoop

use of org.mozilla.javascript.ast.ArrayComprehensionLoop in project HL4A by HL4A.

the class IRFactory method arrayCompTransformHelper.

private Node arrayCompTransformHelper(ArrayComprehension node, String arrayName) {
    decompiler.addToken(Token.LB);
    int lineno = node.getLineno();
    Node expr = transform(node.getResult());
    List<ArrayComprehensionLoop> loops = node.getLoops();
    int numLoops = loops.size();
    // Walk through loops, collecting and defining their iterator symbols.
    Node[] iterators = new Node[numLoops];
    Node[] iteratedObjs = new Node[numLoops];
    for (int i = 0; i < numLoops; i++) {
        ArrayComprehensionLoop acl = loops.get(i);
        decompiler.addName(" ");
        decompiler.addToken(Token.FOR);
        if (acl.isForEach()) {
            decompiler.addName("each ");
        }
        decompiler.addToken(Token.LP);
        AstNode iter = acl.getIterator();
        String name = null;
        if (iter.getType() == Token.NAME) {
            name = iter.getString();
            decompiler.addName(name);
        } else {
            // destructuring assignment
            decompile(iter);
            name = currentScriptOrFn.getNextTempName();
            defineSymbol(Token.LP, name, false);
            expr = createBinary(Token.COMMA, createAssignment(Token.ASSIGN, iter, createName(name)), expr);
        }
        Node init = createName(name);
        // Define as a let since we want the scope of the variable to
        // be restricted to the array comprehension
        defineSymbol(Token.LET, name, false);
        iterators[i] = init;
        if (acl.isForOf()) {
            decompiler.addName("of ");
        } else {
            decompiler.addToken(Token.IN);
        }
        iteratedObjs[i] = transform(acl.getIteratedObject());
        decompiler.addToken(Token.RP);
    }
    // generate code for tmpArray.push(body)
    Node call = createCallOrNew(Token.CALL, createPropertyGet(createName(arrayName), null, "push", 0));
    Node body = new Node(Token.EXPR_VOID, call, lineno);
    if (node.getFilter() != null) {
        decompiler.addName(" ");
        decompiler.addToken(Token.IF);
        decompiler.addToken(Token.LP);
        body = createIf(transform(node.getFilter()), body, null, lineno);
        decompiler.addToken(Token.RP);
    }
    // Now walk loops in reverse to build up the body statement.
    int pushed = 0;
    try {
        for (int i = numLoops - 1; i >= 0; i--) {
            ArrayComprehensionLoop acl = loops.get(i);
            Scope loop = createLoopNode(// no label
            null, acl.getLineno());
            pushScope(loop);
            pushed++;
            body = createForIn(Token.LET, loop, iterators[i], iteratedObjs[i], body, acl.isForEach(), acl.isForOf());
        }
    } finally {
        for (int i = 0; i < pushed; i++) {
            popScope();
        }
    }
    decompiler.addToken(Token.RB);
    // Now that we've accumulated any destructuring forms,
    // add expr to the call node; it's pushed on each iteration.
    call.addChildToBack(expr);
    return body;
}
Also used : Scope(org.mozilla.javascript.ast.Scope) ArrayComprehensionLoop(org.mozilla.javascript.ast.ArrayComprehensionLoop) ScriptNode(org.mozilla.javascript.ast.ScriptNode) AstNode(org.mozilla.javascript.ast.AstNode) LetNode(org.mozilla.javascript.ast.LetNode) FunctionNode(org.mozilla.javascript.ast.FunctionNode) XmlString(org.mozilla.javascript.ast.XmlString) AstNode(org.mozilla.javascript.ast.AstNode)

Example 2 with ArrayComprehensionLoop

use of org.mozilla.javascript.ast.ArrayComprehensionLoop in project HL4A by HL4A.

the class Parser method arrayComprehension.

/**
 * Parse a JavaScript 1.7 Array comprehension.
 * @param result the first expression after the opening left-bracket
 * @param pos start of LB token that begins the array comprehension
 * @return the array comprehension or an error node
 */
private AstNode arrayComprehension(AstNode result, int pos) throws IOException {
    List<ArrayComprehensionLoop> loops = new ArrayList<ArrayComprehensionLoop>();
    while (peekToken() == Token.FOR) {
        loops.add(arrayComprehensionLoop());
    }
    int ifPos = -1;
    ConditionData data = null;
    if (peekToken() == Token.IF) {
        consumeToken();
        ifPos = ts.tokenBeg - pos;
        data = condition();
    }
    mustMatchToken(Token.RB, "msg.no.bracket.arg");
    ArrayComprehension pn = new ArrayComprehension(pos, ts.tokenEnd - pos);
    pn.setResult(result);
    pn.setLoops(loops);
    if (data != null) {
        pn.setIfPosition(ifPos);
        pn.setFilter(data.condition);
        pn.setFilterLp(data.lp - pos);
        pn.setFilterRp(data.rp - pos);
    }
    return pn;
}
Also used : ArrayComprehensionLoop(org.mozilla.javascript.ast.ArrayComprehensionLoop) ArrayList(java.util.ArrayList) ArrayComprehension(org.mozilla.javascript.ast.ArrayComprehension)

Example 3 with ArrayComprehensionLoop

use of org.mozilla.javascript.ast.ArrayComprehensionLoop in project HL4A by HL4A.

the class Parser method arrayComprehensionLoop.

private ArrayComprehensionLoop arrayComprehensionLoop() throws IOException {
    if (nextToken() != Token.FOR)
        codeBug();
    int pos = ts.tokenBeg;
    int eachPos = -1, lp = -1, rp = -1, inPos = -1;
    boolean isForIn = false, isForOf = false;
    ArrayComprehensionLoop pn = new ArrayComprehensionLoop(pos);
    pushScope(pn);
    try {
        if (matchToken(Token.NAME)) {
            if (ts.getString().equals("each")) {
                eachPos = ts.tokenBeg - pos;
            } else {
                reportError("msg.no.paren.for");
            }
        }
        if (mustMatchToken(Token.LP, "msg.no.paren.for")) {
            lp = ts.tokenBeg - pos;
        }
        AstNode iter = null;
        switch(peekToken()) {
            case Token.LB:
            case Token.LC:
                // handle destructuring assignment
                iter = destructuringPrimaryExpr();
                markDestructuring(iter);
                break;
            case Token.NAME:
                consumeToken();
                iter = createNameNode();
                break;
            default:
                reportError("msg.bad.var");
        }
        // be restricted to the array comprehension
        if (iter.getType() == Token.NAME) {
            defineSymbol(Token.LET, ts.getString(), true);
        }
        switch(nextToken()) {
            case Token.IN:
                inPos = ts.tokenBeg - pos;
                isForIn = true;
                break;
            case Token.NAME:
                if ("of".equals(ts.getString())) {
                    if (eachPos != -1) {
                        reportError("msg.invalid.for.each");
                    }
                    inPos = ts.tokenBeg - pos;
                    isForOf = true;
                    break;
                }
            // fallthru
            default:
                reportError("msg.in.after.for.name");
        }
        AstNode obj = expr();
        if (mustMatchToken(Token.RP, "msg.no.paren.for.ctrl"))
            rp = ts.tokenBeg - pos;
        pn.setLength(ts.tokenEnd - pos);
        pn.setIterator(iter);
        pn.setIteratedObject(obj);
        pn.setInPosition(inPos);
        pn.setEachPosition(eachPos);
        pn.setIsForEach(eachPos != -1);
        pn.setParens(lp, rp);
        pn.setIsForOf(isForOf);
        return pn;
    } finally {
        popScope();
    }
}
Also used : ArrayComprehensionLoop(org.mozilla.javascript.ast.ArrayComprehensionLoop) AstNode(org.mozilla.javascript.ast.AstNode)

Aggregations

ArrayComprehensionLoop (org.mozilla.javascript.ast.ArrayComprehensionLoop)3 AstNode (org.mozilla.javascript.ast.AstNode)2 ArrayList (java.util.ArrayList)1 ArrayComprehension (org.mozilla.javascript.ast.ArrayComprehension)1 FunctionNode (org.mozilla.javascript.ast.FunctionNode)1 LetNode (org.mozilla.javascript.ast.LetNode)1 Scope (org.mozilla.javascript.ast.Scope)1 ScriptNode (org.mozilla.javascript.ast.ScriptNode)1 XmlString (org.mozilla.javascript.ast.XmlString)1