?? node.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 * Roger Lawrence * Mike McCabe * * 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 implements the root of the intermediate representation. * * @author Norris Boyd * @author Mike McCabe */public class Node{ public static final int FUNCTION_PROP = 1, LOCAL_PROP = 2, LOCAL_BLOCK_PROP = 3, REGEXP_PROP = 4, CASEARRAY_PROP = 5, /* the following properties are defined and manipulated by the optimizer - TARGETBLOCK_PROP - the block referenced by a branch node VARIABLE_PROP - the variable referenced by a BIND or NAME node ISNUMBER_PROP - this node generates code on Number children and delivers a Number result (as opposed to Objects) DIRECTCALL_PROP - this call node should emit code to test the function object against the known class and call diret if it matches. */ TARGETBLOCK_PROP = 6, VARIABLE_PROP = 7, ISNUMBER_PROP = 8, DIRECTCALL_PROP = 9, SPECIALCALL_PROP = 10, SKIP_INDEXES_PROP = 11, // array of skipped indexes of array literal OBJECT_IDS_PROP = 12, // array of properties for object literal INCRDECR_PROP = 13, // pre or post type of increment/decerement CATCH_SCOPE_PROP = 14, // index of catch scope block in catch LABEL_ID_PROP = 15, // label id: code generation uses it MEMBER_TYPE_PROP = 16, // type of element access operation NAME_PROP = 17, // property name LAST_PROP = 17; // values of ISNUMBER_PROP to specify // which of the children are Number types public static final int BOTH = 0, LEFT = 1, RIGHT = 2; public static final int // values for SPECIALCALL_PROP NON_SPECIALCALL = 0, SPECIALCALL_EVAL = 1, SPECIALCALL_WITH = 2; public static final int // flags for INCRDECR_PROP DECR_FLAG = 0x1, POST_FLAG = 0x2; public static final int // flags for MEMBER_TYPE_PROP PROPERTY_FLAG = 0x1, // property access: element is valid name ATTRIBUTE_FLAG = 0x2, // x.@y or x..@y DESCENDANTS_FLAG = 0x4; // x..y or x..@i private static class NumberNode extends Node { NumberNode(double number) { super(Token.NUMBER); this.number = number; } double number; } private static class StringNode extends Node { StringNode(int type, String str) { super(type); this.str = str; } String str; } public static class Jump extends Node { public Jump(int type) { super(type); } Jump(int type, int lineno) { super(type, lineno); } Jump(int type, Node child) { super(type, child); } Jump(int type, Node child, int lineno) { super(type, child, lineno); } public final Jump getJumpStatement() { if (!(type == Token.BREAK || type == Token.CONTINUE)) Kit.codeBug(); return jumpNode; } public final void setJumpStatement(Jump jumpStatement) { if (!(type == Token.BREAK || type == Token.CONTINUE)) Kit.codeBug(); if (jumpStatement == null) Kit.codeBug(); if (this.jumpNode != null) Kit.codeBug(); //only once this.jumpNode = jumpStatement; } public final Node getDefault() { if (!(type == Token.SWITCH)) Kit.codeBug(); return target2; } public final void setDefault(Node defaultTarget) { if (!(type == Token.SWITCH)) Kit.codeBug(); if (defaultTarget.type != Token.TARGET) Kit.codeBug(); if (target2 != null) Kit.codeBug(); //only once target2 = defaultTarget; } public final Node getFinally() { if (!(type == Token.TRY)) Kit.codeBug(); return target2; } public final void setFinally(Node finallyTarget) { if (!(type == Token.TRY)) Kit.codeBug(); if (finallyTarget.type != Token.TARGET) Kit.codeBug(); if (target2 != null) Kit.codeBug(); //only once target2 = finallyTarget; } public final Jump getLoop() { if (!(type == Token.LABEL)) Kit.codeBug(); return jumpNode; } public final void setLoop(Jump loop) { if (!(type == Token.LABEL)) Kit.codeBug(); if (loop == null) Kit.codeBug(); if (jumpNode != null) Kit.codeBug(); //only once jumpNode = loop; } public final Node getContinue() { if (type != Token.LOOP) Kit.codeBug(); return target2; } public final void setContinue(Node continueTarget) { if (type != Token.LOOP) Kit.codeBug(); if (continueTarget.type != Token.TARGET) Kit.codeBug(); if (target2 != null) Kit.codeBug(); //only once target2 = continueTarget; } public Node target; private Node target2; private Jump jumpNode; } private static class PropListItem { PropListItem next; int type; int intValue; Object objectValue; } public Node(int nodeType) { type = nodeType; } public Node(int nodeType, Node child) { type = nodeType; first = last = child; child.next = null; } public Node(int nodeType, Node left, Node right) { type = nodeType; first = left; last = right; left.next = right; right.next = null; } public Node(int nodeType, Node left, Node mid, Node right) { type = nodeType; first = left; last = right; left.next = mid; mid.next = right; right.next = null; } public Node(int nodeType, int line) { type = nodeType; lineno = line; } public Node(int nodeType, Node child, int line) { this(nodeType, child); lineno = line; } public Node(int nodeType, Node left, Node right, int line) { this(nodeType, left, right); lineno = line; } public Node(int nodeType, Node left, Node mid, Node right, int line) { this(nodeType, left, mid, right); lineno = line; } public static Node newNumber(double number) { return new NumberNode(number); } public static Node newString(String str) { return new StringNode(Token.STRING, str); } public static Node newString(int type, String str) { return new StringNode(type, str); } public int getType() { return type; } public void setType(int type) { this.type = type; } public boolean hasChildren() { return first != null; } public Node getFirstChild() { return first; } public Node getLastChild() { return last; } public Node getNext() { return next; } public Node getChildBefore(Node child) { if (child == first) return null; Node n = first; while (n.next != child) { n = n.next; if (n == null) throw new RuntimeException("node is not a child"); } return n; } public Node getLastSibling() { Node n = this; while (n.next != null) { n = n.next; } return n; } public void addChildToFront(Node child) { child.next = first; first = child; if (last == null) { last = child; } } public void addChildToBack(Node child) { child.next = null; if (last == null) { first = last = child; return; } last.next = child; last = child; } public void addChildrenToFront(Node children) { Node lastSib = children.getLastSibling(); lastSib.next = first; first = children; if (last == null) { last = lastSib; } } public void addChildrenToBack(Node children) { if (last != null) { last.next = children; } last = children.getLastSibling(); if (first == null) { first = children; } } /** * Add 'child' before 'node'. */ public void addChildBefore(Node newChild, Node node) { if (newChild.next != null) throw new RuntimeException( "newChild had siblings in addChildBefore"); if (first == node) { newChild.next = first; first = newChild; return; } Node prev = getChildBefore(node); addChildAfter(newChild, prev); } /** * Add 'child' after 'node'. */ public void addChildAfter(Node newChild, Node node) { if (newChild.next != null) throw new RuntimeException( "newChild had siblings in addChildAfter"); newChild.next = node.next; node.next = newChild; if (last == node) last = newChild; } public void removeChild(Node child) {
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -