⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 irfactory.java

📁 這是一個javascript 的 interpreter是了解 web browser的好材料
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): *   Norris Boyd *   Igor Bukanov *   Ethan Hugg *   Bob Jervis *   Terry Lucas *   Milen Nankov * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */package org.mozilla.javascript;import java.util.List;import java.util.ArrayList;/** * This class allows the creation of nodes, and follows the Factory pattern. * * @see Node * @author Mike McCabe * @author Norris Boyd */final class IRFactory{    IRFactory(Parser parser)    {        this.parser = parser;    }    ScriptOrFnNode createScript()    {        return new ScriptOrFnNode(Token.SCRIPT);    }    /**     * Script (for associating file/url names with toplevel scripts.)     */    void initScript(ScriptOrFnNode scriptNode, Node body)    {        Node children = body.getFirstChild();        if (children != null) { scriptNode.addChildrenToBack(children); }    }    /**     * Leaf     */    Node createLeaf(int nodeType)    {        return new Node(nodeType);    }    /**     * Statement leaf nodes.     */    Node createSwitch(Node expr, int lineno)    {        //        // 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        // the transformed code would contain after the switch instead of        //     goto labelDefault;        // the following goto:        //     goto breakLabel;        //        Node.Jump switchNode = new Node.Jump(Token.SWITCH, expr, lineno);        Node block = new Node(Token.BLOCK, switchNode);        return block;    }    /**     * If caseExpression argument is null it indicate default label.     */    void addSwitchCase(Node switchBlock, Node caseExpression, Node statements)    {        if (switchBlock.getType() != Token.BLOCK) throw Kit.codeBug();        Node.Jump switchNode = (Node.Jump)switchBlock.getFirstChild();        if (switchNode.getType() != Token.SWITCH) throw Kit.codeBug();        Node gotoTarget = Node.newTarget();        if (caseExpression != null) {            Node.Jump caseNode = new Node.Jump(Token.CASE, caseExpression);            caseNode.target = gotoTarget;            switchNode.addChildToBack(caseNode);        } else {            switchNode.setDefault(gotoTarget);        }        switchBlock.addChildToBack(gotoTarget);        switchBlock.addChildToBack(statements);    }    void closeSwitch(Node switchBlock)    {        if (switchBlock.getType() != Token.BLOCK) throw Kit.codeBug();        Node.Jump switchNode = (Node.Jump)switchBlock.getFirstChild();        if (switchNode.getType() != Token.SWITCH) throw Kit.codeBug();        Node switchBreakTarget = Node.newTarget();        // switchNode.target is only used by NodeTransformer        // to detect switch end        switchNode.target = switchBreakTarget;        Node defaultTarget = switchNode.getDefault();        if (defaultTarget == null) {            defaultTarget = switchBreakTarget;        }        switchBlock.addChildAfter(makeJump(Token.GOTO, defaultTarget),                                  switchNode);        switchBlock.addChildToBack(switchBreakTarget);    }    Node createVariables(int token, int lineno)    {        return new Node(token, lineno);    }    Node createExprStatement(Node expr, int lineno)    {        int type;        if (parser.insideFunction()) {            type = Token.EXPR_VOID;        } else {            type = Token.EXPR_RESULT;        }        return new Node(type, expr, lineno);    }    Node createExprStatementNoReturn(Node expr, int lineno)    {        return new Node(Token.EXPR_VOID, expr, lineno);    }    Node createDefaultNamespace(Node expr, int lineno)    {        // default xml namespace requires activation        setRequiresActivation();        Node n = createUnary(Token.DEFAULTNAMESPACE, expr);        Node result = createExprStatement(n, lineno);        return result;    }    /**     * Name     */    Node createName(String name)    {        checkActivationName(name, Token.NAME);        return Node.newString(Token.NAME, name);    }        private Node createName(int type, String name, Node child)    {        Node result = createName(name);        result.setType(type);        if (child != null)            result.addChildToBack(child);        return result;    }    /**     * String (for literals)     */    Node createString(String string)    {        return Node.newString(string);    }    /**     * Number (for literals)     */    Node createNumber(double number)    {        return Node.newNumber(number);    }    /**     * Catch clause of try/catch/finally     * @param varName the name of the variable to bind to the exception     * @param catchCond the condition under which to catch the exception.     *                  May be null if no condition is given.     * @param stmts the statements in the catch clause     * @param lineno the starting line number of the catch clause     */    Node createCatch(String varName, Node catchCond, Node stmts, int lineno)    {        if (catchCond == null) {            catchCond = new Node(Token.EMPTY);        }        return new Node(Token.CATCH, createName(varName),                        catchCond, stmts, lineno);    }    /**     * Throw     */    Node createThrow(Node expr, int lineno)    {        return new Node(Token.THROW, expr, lineno);    }    /**     * Return     */    Node createReturn(Node expr, int lineno)    {        return expr == null            ? new Node(Token.RETURN, lineno)            : new Node(Token.RETURN, expr, lineno);    }    /**     * Debugger     */    Node createDebugger(int lineno)    {        return new Node(Token.DEBUGGER,  lineno);    }      /**     * Label     */    Node createLabel(int lineno)    {        return new Node.Jump(Token.LABEL, lineno);    }    Node getLabelLoop(Node label)    {        return ((Node.Jump)label).getLoop();    }    /**     * Label     */    Node createLabeledStatement(Node labelArg, Node statement)    {        Node.Jump label = (Node.Jump)labelArg;        // Make a target and put it _after_ the statement        // node.  And in the LABEL node, so breaks get the        // right target.        Node breakTarget = Node.newTarget();        Node block = new Node(Token.BLOCK, label, statement, breakTarget);        label.target = breakTarget;        return block;    }    /**     * Break (possibly labeled)     */    Node createBreak(Node breakStatement, int lineno)    {        Node.Jump n = new Node.Jump(Token.BREAK, lineno);        Node.Jump jumpStatement;        int t = breakStatement.getType();        if (t == Token.LOOP || t == Token.LABEL) {            jumpStatement = (Node.Jump)breakStatement;        } else if (t == Token.BLOCK                   && breakStatement.getFirstChild().getType() == Token.SWITCH)        {            jumpStatement = (Node.Jump)breakStatement.getFirstChild();        } else {            throw Kit.codeBug();        }        n.setJumpStatement(jumpStatement);        return n;    }    /**     * Continue (possibly labeled)     */    Node createContinue(Node loop, int lineno)    {        if (loop.getType() != Token.LOOP) Kit.codeBug();        Node.Jump n = new Node.Jump(Token.CONTINUE, lineno);        n.setJumpStatement((Node.Jump)loop);        return n;    }    /**     * Statement block     * Creates the empty statement block     * Must make subsequent calls to add statements to the node     */    Node createBlock(int lineno)    {        return new Node(Token.BLOCK, lineno);    }    FunctionNode createFunction(String name)    {        return new FunctionNode(name);    }    Node initFunction(FunctionNode fnNode, int functionIndex,                      Node statements, int functionType)    {        fnNode.itsFunctionType = functionType;        fnNode.addChildToBack(statements);        int functionCount = fnNode.getFunctionCount();        if (functionCount != 0) {            // Functions containing other functions require activation objects            fnNode.itsNeedsActivation = true;        }        if (functionType == FunctionNode.FUNCTION_EXPRESSION) {            String name = fnNode.getFunctionName();            if (name != null && name.length() != 0) {                // A function expression needs to have its name as a                // variable (if it isn't already allocated as a variable).                // See ECMA Ch. 13.  We add code to the beginning of the                // function to initialize a local variable of the                // function's name to the function value.                Node setFn = new Node(Token.EXPR_VOID,                                 new Node(Token.SETNAME,                                     Node.newString(Token.BINDNAME, name),                                     new Node(Token.THISFN)));                statements.addChildrenToFront(setFn);            }        }        // Add return to end if needed.        Node lastStmt = statements.getLastChild();        if (lastStmt == null || lastStmt.getType() != Token.RETURN) {            statements.addChildToBack(new Node(Token.RETURN));        }        Node result = Node.newString(Token.FUNCTION,                                     fnNode.getFunctionName());        result.putIntProp(Node.FUNCTION_PROP, functionIndex);        return result;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -