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

📄 nodetransformer.java

📁 這是一個javascript 的 interpreter是了解 web browser的好材料
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
                visitNew(node, tree);                break;              case Token.LETEXPR:              case Token.LET: {                Node child = node.getFirstChild();                if (child.getType() == Token.LET) {                  // We have a let statement or expression rather than a                  // let declaration                  boolean createWith = tree.getType() != Token.FUNCTION                      || ((FunctionNode)tree).requiresActivation();                  node = visitLet(createWith, parent, previous, node);                  break;                } else {                  // fall through to process let declaration...                }              }              /* fall through */              case Token.CONST:              case Token.VAR:              {                Node result = new Node(Token.BLOCK);                for (Node cursor = node.getFirstChild(); cursor != null;) {                    // Move cursor to next before createAssignment gets chance                    // to change n.next                    Node n = cursor;                    cursor = cursor.getNext();                    if (n.getType() == Token.NAME) {                        if (!n.hasChildren())                            continue;                        Node init = n.getFirstChild();                        n.removeChild(init);                        n.setType(Token.BINDNAME);                        n = new Node(type == Token.CONST ?                                         Token.SETCONST :                                         Token.SETNAME,                                     n, init);                    } else {                        // May be a destructuring assignment already transformed                        // to a LETEXPR                        if (n.getType() != Token.LETEXPR)                            throw Kit.codeBug();                    }                    Node pop = new Node(Token.EXPR_VOID, n, node.getLineno());                    result.addChildToBack(pop);                }                node = replaceCurrent(parent, previous, node, result);                break;              }              case Token.TYPEOFNAME: {                Node.Scope defining = scope.getDefiningScope(node.getString());                if (defining != null) {                    node.setScope(defining);                }              }              break;              case Token.TYPEOF:              case Token.IFNE: {                  /* We want to suppress warnings for undefined property o.p                   * for the following constructs: typeof o.p, if (o.p),                    * if (!o.p), if (o.p == undefined), if (undefined == o.p)                   */            	  Node child = node.getFirstChild();            	  if (type == Token.IFNE) {                	  while (child.getType() == Token.NOT) {                	      child = child.getFirstChild();                	  }                	  if (child.getType() == Token.EQ ||                	      child.getType() == Token.NE)                	  {                	      Node first = child.getFirstChild();                	      Node last = child.getLastChild();                	      if (first.getType() == Token.NAME &&                	          first.getString().equals("undefined"))                	          child = last;                	      else if (last.getType() == Token.NAME &&                	               last.getString().equals("undefined"))                              child = first;                	  }            	  }            	  if (child.getType() == Token.GETPROP)            		  child.setType(Token.GETPROPNOWARN);            	  break;              }              case Token.NAME:              case Token.SETNAME:              case Token.SETCONST:              case Token.DELPROP:              {                // Turn name to var for faster access if possible                if (createScopeObjects) {                    break;                }                Node nameSource;                if (type == Token.NAME) {                    nameSource = node;                } else {                    nameSource = node.getFirstChild();                    if (nameSource.getType() != Token.BINDNAME) {                        if (type == Token.DELPROP) {                            break;                        }                        throw Kit.codeBug();                    }                }                if (nameSource.getScope() != null) {                    break; // already have a scope set                }                String name = nameSource.getString();                Node.Scope defining = scope.getDefiningScope(name);                if (defining != null) {                    nameSource.setScope(defining);                    if (type == Token.NAME) {                        node.setType(Token.GETVAR);                    } else if (type == Token.SETNAME) {                        node.setType(Token.SETVAR);                        nameSource.setType(Token.STRING);                    } else if (type == Token.SETCONST) {                        node.setType(Token.SETCONSTVAR);                        nameSource.setType(Token.STRING);                    } else if (type == Token.DELPROP) {                        // Local variables are by definition permanent                        Node n = new Node(Token.FALSE);                        node = replaceCurrent(parent, previous, node, n);                    } else {                        throw Kit.codeBug();                    }                }                break;              }            }            transformCompilationUnit_r(tree, node,                 node instanceof Node.Scope ? (Node.Scope)node : scope,                createScopeObjects);        }    }    protected void visitNew(Node node, ScriptOrFnNode tree) {    }    protected void visitCall(Node node, ScriptOrFnNode tree) {    }        protected Node visitLet(boolean createWith, Node parent, Node previous,                             Node scopeNode)    {        Node vars = scopeNode.getFirstChild();        Node body = vars.getNext();        scopeNode.removeChild(vars);        scopeNode.removeChild(body);        boolean isExpression = scopeNode.getType() == Token.LETEXPR;        Node result;        Node newVars;        if (createWith) {            result = new Node(isExpression ? Token.WITHEXPR : Token.BLOCK);            result = replaceCurrent(parent, previous, scopeNode, result);            ArrayList<Object> list = new ArrayList<Object>();            Node objectLiteral = new Node(Token.OBJECTLIT);            for (Node v=vars.getFirstChild(); v != null; v = v.getNext()) {                Node current = v;                if (current.getType() == Token.LETEXPR) {                    // destructuring in let expr, e.g. let ([x, y] = [3, 4]) {}                    List<?> destructuringNames = (List<?>)                        current.getProp(Node.DESTRUCTURING_NAMES);                    Node c = current.getFirstChild();                    if (c.getType() != Token.LET) throw Kit.codeBug();                    // Add initialization code to front of body                    if (isExpression) {                        body = new Node(Token.COMMA, c.getNext(), body);                    } else {                        body = new Node(Token.BLOCK,                            new Node(Token.EXPR_VOID, c.getNext()),                            body);                    }                    // Update "list" and "objectLiteral" for the variables                    // defined in the destructuring assignment                    if (destructuringNames != null) {                        list.addAll(destructuringNames);                        for (int i=0; i < destructuringNames.size(); i++) {                            objectLiteral.addChildToBack(                                new Node(Token.VOID, Node.newNumber(0.0)));                        }                    }                    current = c.getFirstChild(); // should be a NAME, checked below                }                if (current.getType() != Token.NAME) throw Kit.codeBug();                list.add(ScriptRuntime.getIndexObject(current.getString()));                Node init = current.getFirstChild();                if (init == null) {                    init = new Node(Token.VOID, Node.newNumber(0.0));                }                objectLiteral.addChildToBack(init);             }             objectLiteral.putProp(Node.OBJECT_IDS_PROP, list.toArray());             newVars = new Node(Token.ENTERWITH, objectLiteral);             result.addChildToBack(newVars);             result.addChildToBack(new Node(Token.WITH, body));             result.addChildToBack(new Node(Token.LEAVEWITH));        } else {            result = new Node(isExpression ? Token.COMMA : Token.BLOCK);            result = replaceCurrent(parent, previous, scopeNode, result);            newVars = new Node(Token.COMMA);            for (Node v=vars.getFirstChild(); v != null; v = v.getNext()) {                Node current = v;                if (current.getType() == Token.LETEXPR) {                    // destructuring in let expr, e.g. let ([x, y] = [3, 4]) {}                    Node c = current.getFirstChild();                    if (c.getType() != Token.LET) throw Kit.codeBug();                    // Add initialization code to front of body                    if (isExpression) {                        body = new Node(Token.COMMA, c.getNext(), body);                    } else {                        body = new Node(Token.BLOCK,                            new Node(Token.EXPR_VOID, c.getNext()),                            body);                    }                    // We're removing the LETEXPR, so move the symbols                    Node.Scope.joinScopes((Node.Scope)current,                                          (Node.Scope)scopeNode);                    current = c.getFirstChild(); // should be a NAME, checked below                }                if (current.getType() != Token.NAME) throw Kit.codeBug();                Node stringNode = Node.newString(current.getString());                stringNode.setScope((Node.Scope)scopeNode);                Node init = current.getFirstChild();                if (init == null) {                    init = new Node(Token.VOID, Node.newNumber(0.0));                }                newVars.addChildToBack(new Node(Token.SETVAR, stringNode, init));            }            if (isExpression) {                result.addChildToBack(newVars);                scopeNode.setType(Token.COMMA);                result.addChildToBack(scopeNode);                scopeNode.addChildToBack(body);            } else {                result.addChildToBack(new Node(Token.EXPR_VOID, newVars));                scopeNode.setType(Token.BLOCK);                result.addChildToBack(scopeNode);                scopeNode.addChildrenToBack(body);            }        }        return result;    }    private static Node addBeforeCurrent(Node parent, Node previous,                                         Node current, Node toAdd)    {        if (previous == null) {            if (!(current == parent.getFirstChild())) Kit.codeBug();            parent.addChildToFront(toAdd);        } else {            if (!(current == previous.getNext())) Kit.codeBug();            parent.addChildAfter(toAdd, previous);        }        return toAdd;    }    private static Node replaceCurrent(Node parent, Node previous,                                       Node current, Node replacement)    {        if (previous == null) {            if (!(current == parent.getFirstChild())) Kit.codeBug();            parent.replaceChild(current, replacement);        } else if (previous.next == current) {            // Check cachedPrev.next == current is necessary due to possible            // tree mutations            parent.replaceChildAfter(previous, replacement);        } else {            parent.replaceChild(current, replacement);        }        return replacement;    }    private ObjArray loops;    private ObjArray loopEnds;    private boolean hasFinally;}

⌨️ 快捷键说明

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