Search in sources :

Example 6 with Block

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

the class IRFactory method transformSwitch.

private Node transformSwitch(SwitchStatement node) {
    // The switch will be rewritten from:
    // 
    // switch (expr) {
    // case test1: statements1;
    // ...
    // default: statementsDefault;
    // ...
    // case testN: statementsN;
    // }
    // 
    // to:
    // 
    // {
    // switch (expr) {
    // case test1: goto label1;
    // ...
    // case testN: goto labelN;
    // }
    // goto labelDefault;
    // label1:
    // statements1;
    // ...
    // labelDefault:
    // statementsDefault;
    // ...
    // labelN:
    // statementsN;
    // breakLabel:
    // }
    // 
    // where inside switch each "break;" without label will be replaced
    // by "goto breakLabel".
    // 
    // If the original switch does not have the default label, then
    // after the switch he transformed code would contain this goto:
    // goto breakLabel;
    // instead of:
    // goto labelDefault;
    decompiler.addToken(Token.SWITCH);
    decompiler.addToken(Token.LP);
    Node switchExpr = transform(node.getExpression());
    decompiler.addToken(Token.RP);
    node.addChildToBack(switchExpr);
    Node block = new Node(Token.BLOCK, node, node.getLineno());
    decompiler.addEOL(Token.LC);
    for (SwitchCase sc : node.getCases()) {
        AstNode expr = sc.getExpression();
        Node caseExpr = null;
        if (expr != null) {
            decompiler.addToken(Token.CASE);
            caseExpr = transform(expr);
        } else {
            decompiler.addToken(Token.DEFAULT);
        }
        decompiler.addEOL(Token.COLON);
        List<AstNode> stmts = sc.getStatements();
        Node body = new Block();
        if (stmts != null) {
            for (AstNode kid : stmts) {
                body.addChildToBack(transform(kid));
            }
        }
        addSwitchCase(block, caseExpr, body);
    }
    decompiler.addEOL(Token.RC);
    closeSwitch(block);
    return block;
}
Also used : SwitchCase(org.mozilla.javascript.ast.SwitchCase) ScriptNode(org.mozilla.javascript.ast.ScriptNode) AstNode(org.mozilla.javascript.ast.AstNode) LetNode(org.mozilla.javascript.ast.LetNode) FunctionNode(org.mozilla.javascript.ast.FunctionNode) Block(org.mozilla.javascript.ast.Block) AstNode(org.mozilla.javascript.ast.AstNode)

Example 7 with Block

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

the class Parser method parseFunctionBody.

private AstNode parseFunctionBody(int type, FunctionNode fnNode) throws IOException {
    boolean isExpressionClosure = false;
    if (!matchToken(Token.LC)) {
        if (compilerEnv.getLanguageVersion() < Context.VERSION_1_8 && type != FunctionNode.ARROW_FUNCTION) {
            reportError("msg.no.brace.body");
        } else {
            isExpressionClosure = true;
        }
    }
    boolean isArrow = type == FunctionNode.ARROW_FUNCTION;
    ++nestingOfFunction;
    int pos = ts.tokenBeg;
    // starts at LC position
    Block pn = new Block(pos);
    boolean inDirectivePrologue = true;
    boolean savedStrictMode = inUseStrictDirective;
    // Don't set 'inUseStrictDirective' to false: inherit strict mode.
    pn.setLineno(ts.lineno);
    try {
        if (isExpressionClosure) {
            AstNode returnValue = assignExpr();
            ReturnStatement n = new ReturnStatement(returnValue.getPosition(), returnValue.getLength(), returnValue);
            // expression closure flag is required on both nodes
            n.putProp(Node.EXPRESSION_CLOSURE_PROP, Boolean.TRUE);
            pn.putProp(Node.EXPRESSION_CLOSURE_PROP, Boolean.TRUE);
            if (isArrow) {
                n.putProp(Node.ARROW_FUNCTION_PROP, Boolean.TRUE);
            }
            pn.addStatement(n);
        } else {
            bodyLoop: for (; ; ) {
                AstNode n;
                int tt = peekToken();
                switch(tt) {
                    case Token.ERROR:
                    case Token.EOF:
                    case Token.RC:
                        break bodyLoop;
                    case Token.FUNCTION:
                        consumeToken();
                        n = function(FunctionNode.FUNCTION_STATEMENT);
                        break;
                    default:
                        n = statement();
                        if (inDirectivePrologue) {
                            String directive = getDirective(n);
                            if (directive == null) {
                                inDirectivePrologue = false;
                            } else if (directive.equals("严格模式")) {
                                inUseStrictDirective = true;
                                fnNode.setInStrictMode(true);
                                if (!savedStrictMode) {
                                    setRequiresActivation();
                                }
                            }
                        }
                        break;
                }
                pn.addStatement(n);
            }
        }
    } catch (ParserException e) {
    // Ignore it
    } finally {
        --nestingOfFunction;
        inUseStrictDirective = savedStrictMode;
    }
    int end = ts.tokenEnd;
    getAndResetJsDoc();
    if (!isExpressionClosure && mustMatchToken(Token.RC, "msg.no.brace.after.body"))
        end = ts.tokenEnd;
    pn.setLength(end - pos);
    return pn;
}
Also used : ReturnStatement(org.mozilla.javascript.ast.ReturnStatement) Block(org.mozilla.javascript.ast.Block) XmlString(org.mozilla.javascript.ast.XmlString) AstNode(org.mozilla.javascript.ast.AstNode)

Example 8 with Block

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

the class Parser method statements.

// This function does not match the closing RC: the caller matches
// the RC so it can provide a suitable error message if not matched.
// This means it's up to the caller to set the length of the node to
// include the closing RC.  The node start pos is set to the
// absolute buffer start position, and the caller should fix it up
// to be relative to the parent node.  All children of this block
// node are given relative start positions and correct lengths.
private AstNode statements(AstNode parent) throws IOException {
    if (// assertion can be invalid in bad code
    currentToken != Token.LC && !compilerEnv.isIdeMode())
        codeBug();
    int pos = ts.tokenBeg;
    AstNode block = parent != null ? parent : new Block(pos);
    block.setLineno(ts.lineno);
    int tt;
    while ((tt = peekToken()) > Token.EOF && tt != Token.RC) {
        block.addChild(statement());
    }
    block.setLength(ts.tokenBeg - pos);
    return block;
}
Also used : Block(org.mozilla.javascript.ast.Block) AstNode(org.mozilla.javascript.ast.AstNode)

Aggregations

Block (org.mozilla.javascript.ast.Block)8 AstNode (org.mozilla.javascript.ast.AstNode)5 CatchClause (org.mozilla.javascript.ast.CatchClause)3 FunctionNode (org.mozilla.javascript.ast.FunctionNode)3 XmlString (org.mozilla.javascript.ast.XmlString)3 LetNode (org.mozilla.javascript.ast.LetNode)2 Name (org.mozilla.javascript.ast.Name)2 ScriptNode (org.mozilla.javascript.ast.ScriptNode)2 ArrayList (java.util.ArrayList)1 Comment (org.mozilla.javascript.ast.Comment)1 EmptyExpression (org.mozilla.javascript.ast.EmptyExpression)1 ReturnStatement (org.mozilla.javascript.ast.ReturnStatement)1 SwitchCase (org.mozilla.javascript.ast.SwitchCase)1 TryStatement (org.mozilla.javascript.ast.TryStatement)1