?? irfactory.java
字號:
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * The contents of this file are subject to the Netscape 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/NPL/ * * 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 Netscape are * Copyright (C) 1997-1999 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * Norris Boyd * Igor Bukanov * Ethan Hugg * Terry Lucas * Milen Nankov * * Alternatively, the contents of this file may be used under the * terms of the GNU Public License (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 NPL, indicate your decision by * deleting the provisions above and replace 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 NPL or the GPL. */package org.mozilla.javascript;/** * 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); } Node createLeaf(int nodeType, int nodeOp) { return new Node(nodeType, nodeOp); } /** * 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 lineno) { return new Node(Token.VAR, 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); } /** * 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); } /** * 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; for (int i = 0; i != functionCount; ++i) { FunctionNode fn = fnNode.getFunctionNode(i); // nested function expression statements overrides var if (fn.getFunctionType() == FunctionNode.FUNCTION_EXPRESSION_STATEMENT) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -