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

📄 node.java

📁 這是一個javascript 的 interpreter是了解 web browser的好材料
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
    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) {        Node prev = getChildBefore(child);        if (prev == null)            first = first.next;        else            prev.next = child.next;        if (child == last) last = prev;        child.next = null;    }    public void replaceChild(Node child, Node newChild) {        newChild.next = child.next;        if (child == first) {            first = newChild;        } else {            Node prev = getChildBefore(child);            prev.next = newChild;        }        if (child == last)            last = newChild;        child.next = null;    }    public void replaceChildAfter(Node prevChild, Node newChild) {        Node child = prevChild.next;        newChild.next = child.next;        prevChild.next = newChild;        if (child == last)            last = newChild;        child.next = null;    }    private static final String propToString(int propType)    {        if (Token.printTrees) {            // If Context.printTrees is false, the compiler            // can remove all these strings.            switch (propType) {                case FUNCTION_PROP:      return "function";                case LOCAL_PROP:         return "local";                case LOCAL_BLOCK_PROP:   return "local_block";                case REGEXP_PROP:        return "regexp";                case CASEARRAY_PROP:     return "casearray";                case TARGETBLOCK_PROP:   return "targetblock";                case VARIABLE_PROP:      return "variable";                case ISNUMBER_PROP:      return "isnumber";                case DIRECTCALL_PROP:    return "directcall";                case SPECIALCALL_PROP:   return "specialcall";                case SKIP_INDEXES_PROP:  return "skip_indexes";                case OBJECT_IDS_PROP:    return "object_ids_prop";                case INCRDECR_PROP:      return "incrdecr_prop";                case CATCH_SCOPE_PROP:   return "catch_scope_prop";                case LABEL_ID_PROP:      return "label_id_prop";                case MEMBER_TYPE_PROP:   return "member_type_prop";                case NAME_PROP:          return "name_prop";                case CONTROL_BLOCK_PROP: return "control_block_prop";                case PARENTHESIZED_PROP: return "parenthesized_prop";                case GENERATOR_END_PROP: return "generator_end";                case DESTRUCTURING_ARRAY_LENGTH:                                         return "destructuring_array_length";                case DESTRUCTURING_NAMES:return "destructuring_names";                default: Kit.codeBug();            }        }        return null;    }    private PropListItem lookupProperty(int propType)    {        PropListItem x = propListHead;        while (x != null && propType != x.type) {            x = x.next;        }        return x;    }    private PropListItem ensureProperty(int propType)    {        PropListItem item = lookupProperty(propType);        if (item == null) {            item = new PropListItem();            item.type = propType;            item.next = propListHead;            propListHead = item;        }        return item;    }    public void removeProp(int propType)    {        PropListItem x = propListHead;        if (x != null) {            PropListItem prev = null;            while (x.type != propType) {                prev = x;                x = x.next;                if (x == null) { return; }            }            if (prev == null) {                propListHead = x.next;            } else {                prev.next = x.next;            }        }    }    public Object getProp(int propType)    {        PropListItem item = lookupProperty(propType);        if (item == null) { return null; }        return item.objectValue;    }    public int getIntProp(int propType, int defaultValue)    {        PropListItem item = lookupProperty(propType);        if (item == null) { return defaultValue; }        return item.intValue;    }    public int getExistingIntProp(int propType)    {        PropListItem item = lookupProperty(propType);        if (item == null) { Kit.codeBug(); }        return item.intValue;    }    public void putProp(int propType, Object prop)    {        if (prop == null) {            removeProp(propType);        } else {            PropListItem item = ensureProperty(propType);            item.objectValue = prop;        }    }    public void putIntProp(int propType, int prop)    {        PropListItem item = ensureProperty(propType);        item.intValue = prop;    }    public int getLineno() {        return lineno;    }    /** Can only be called when <tt>getType() == Token.NUMBER</tt> */    public final double getDouble() {        return ((NumberNode)this).number;    }    public final void setDouble(double number) {        ((NumberNode)this).number = number;    }    /** Can only be called when node has String context. */    public final String getString() {        return ((StringNode)this).str;    }    /** Can only be called when node has String context. */    public final void setString(String s) {        if (s == null) Kit.codeBug();        ((StringNode)this).str = s;    }        /** Can only be called when node has String context. */    public final Scope getScope() {        return ((StringNode)this).scope;    }    /** Can only be called when node has String context. */    public final void setScope(Scope s) {        if (s == null) Kit.codeBug();        if (!(this instanceof StringNode)) {            throw Kit.codeBug();        }        ((StringNode)this).scope = s;    }    public static Node newTarget()    {        return new Node(Token.TARGET);    }    public final int labelId()    {        if (type != Token.TARGET && type != Token.YIELD) Kit.codeBug();        return getIntProp(LABEL_ID_PROP, -1);    }    public void labelId(int labelId)    {        if (type != Token.TARGET  && type != Token.YIELD) Kit.codeBug();        putIntProp(LABEL_ID_PROP, labelId);    }        /**     * Does consistent-return analysis on the function body when strict mode is     * enabled.     *     *   function (x) { return (x+1) }     * is ok, but     *   function (x) { if (x < 0) return (x+1); }     * is not becuase the function can potentially return a value when the     * condition is satisfied and if not, the function does not explicitly     * return value.     *     * This extends to checking mismatches such as "return" and "return <value>"     * used in the same function. Warnings are not emitted if inconsistent     * returns exist in code that can be statically shown to be unreachable.     * Ex.     *   function (x) { while (true) { ... if (..) { return value } ... } }     * emits no warning. However if the loop had a break statement, then a     * warning would be emitted.     *     * The consistency analysis looks at control structures such as loops, ifs,     * switch, try-catch-finally blocks, examines the reachable code paths and     * warns the user about an inconsistent set of termination possibilities.     *     * Caveat: Since the parser flattens many control structures into almost     * straight-line code with gotos, it makes such analysis hard. Hence this     * analyser is written to taken advantage of patterns of code generated by     * the parser (for loops, try blocks and such) and does not do a full     * control flow analysis of the gotos and break/continue statements.     * Future changes to the parser will affect this analysis.     */    /**     * These flags enumerate the possible ways a statement/function can     * terminate. These flags are used by endCheck() and by the Parser to     * detect inconsistent return usage.     *     * END_UNREACHED is reserved for code paths that are assumed to always be     * able to execute (example: throw, continue)     *     * END_DROPS_OFF indicates if the statement can transfer control to the     * next one. Statement such as return dont. A compound statement may have     * some branch that drops off control to the next statement.     *     * END_RETURNS indicates that the statement can return (without arguments)     * END_RETURNS_VALUE indicates that the statement can return a value.     *     * A compound statement such as     * if (condition) {     *   return value;     * }     * Will be detected as (END_DROPS_OFF | END_RETURN_VALUE) by endCheck()     */    static final int END_UNREACHED = 0;    static final int END_DROPS_OFF = 1;    static final int END_RETURNS = 2;    static final int END_RETURNS_VALUE = 4;    static final int END_YIELDS = 8;    /**     * Checks that every return usage in a function body is consistent with the     * requirements of strict-mode.     * @return true if the function satisfies strict mode requirement.     */    public boolean hasConsistentReturnUsage()    {        int n = endCheck();        return (n & END_RETURNS_VALUE) == 0 ||               (n & (END_DROPS_OFF|END_RETURNS|END_YIELDS)) == 0;    }    /**     * Returns in the then and else blocks must be consistent with each other.     * If there is no else block, then the return statement can fall through.     * @return logical OR of END_* flags     */    private int endCheckIf()    {        Node th, el;        int rv = END_UNREACHED;        th = next;        el = ((Jump)this).target;        rv = th.endCheck();        if (el != null)            rv |= el.endCheck();        else            rv |= END_DROPS_OFF;        return rv;    }    /**     * Consistency of return statements is checked between the case statements.     * If there is no default, then the switch can fall through. If there is a     * default,we check to see if all code paths in the default return or if     * there is a code path that can fall through.     * @return logical OR of END_* flags     */    private int endCheckSwitch()    {        Node n;        int rv = END_UNREACHED;        // examine the cases        for (n = first.next; n != null; n = n.next)        {            if (n.type == Token.CASE) {                rv |= ((Jump)n).target.endCheck();            } else                break;        }        // we don't care how the cases drop into each other        rv &= ~END_DROPS_OFF;        // examine the default        n = ((Jump)this).getDefault();        if (n != null)            rv |= n.endCheck();        else            rv |= END_DROPS_OFF;        // remove the switch block        rv |= getIntProp(CONTROL_BLOCK_PROP, END_UNREACHED);        return rv;    }    /**     * If the block has a finally, return consistency is checked in the     * finally block. If all code paths in the finally returns, then the     * returns in the try-catch blocks don't matter. If there is a code path     * that does not return or if there is no finally block, the returns     * of the try and catch blocks are checked for mismatch.     * @return logical OR of END_* flags     */    private int endCheckTry()    {        Node n;        int rv = END_UNREACHED;        // check the finally if it exists        n = ((Jump)this).getFinally();        if(n != null) {            rv = n.next.first.endCheck();        } else {            rv = END_DROPS_OFF;        }        // if the finally block always returns, then none of the returns        // in the try or catch blocks matter        if ((rv & END_DROPS_OFF) != 0) {            rv &= ~END_DROPS_OFF;            // examine the try block            rv |= first.endCheck();            // check each catch block            n = ((Jump)this).target;            if (n != null)            {                // point to the first catch_scope                for (n = n.next.first; n != null; n = n.next.next)                {                    // check the block of user code in the catch_scope                    rv |= n.next.first.next.first.endCheck();                }            }        }        return rv;    }    /**     * Return statement in the loop body must be consistent. The default     * assumption for any kind of a loop is that it will eventually terminate.     * The only exception is a loop with a constant true condition. Code that     * follows such a loop is examined only if one can statically determine     * that there is a break out of the loop.     *  for(<> ; <>; <>) {}     *  for(<> in <> ) {}     *  while(<>) { }     *  do { } while(<>)     * @return logical OR of END_* flags     */    private int endCheckLoop()    {        Node n;        int rv = END_UNREACHED;        // To find the loop body, we look at the second to last node of the        // loop node, which should be the predicate that the loop should        // satisfy.        // The target of the predicate is the loop-body for all 4 kinds of        // loops.        for (n = first; n.next != last; n = n.next) {            /* skip */        }        if (n.type != Token.IFEQ)            return END_DROPS_OFF;        // The target's next is the loop body block        rv = ((Jump)n).target.next.endCheck();        // check to see if the loop condition is true        if (n.first.type == Token.TRUE)            rv &= ~END_DROPS_OFF;        // look for effect of breaks        rv |= getIntProp(CONTROL_BLOCK_PROP, END_UNREACHED);        return rv;

⌨️ 快捷键说明

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