public int addFunction(FunctionNode fnNode)
 {
     if (fnNode == null)
     {
         Context.CodeBug();
     }
     if (functions == null)
     {
         functions = new ObjArray();
     }
     functions.add(fnNode);
     return(functions.size() - 1);
 }
        internal Node initFunction(FunctionNode fnNode, int functionIndex, Node statements, int functionType)
        {
            fnNode.itsFunctionType = functionType;
            fnNode.addChildToBack (statements);

            int functionCount = fnNode.FunctionCount;
            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.FunctionType == FunctionNode.FUNCTION_EXPRESSION_STATEMENT) {
                        string name = fn.FunctionName;
                        if (name != null && name.Length != 0) {
                            fnNode.removeParamOrVar (name);
                        }
                    }
                }
            }

            if (functionType == FunctionNode.FUNCTION_EXPRESSION) {
                string name = fnNode.FunctionName;
                if (name != null && name.Length != 0 && !fnNode.hasParamOrVar (name)) {
                    // 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.
                    fnNode.addVar (name);
                    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.LastChild;
            if (lastStmt == null || lastStmt.Type != Token.RETURN) {
                statements.addChildToBack (new Node (Token.RETURN));
            }

            Node result = Node.newString (Token.FUNCTION, fnNode.FunctionName);
            result.putIntProp (Node.FUNCTION_PROP, functionIndex);
            return result;
        }
示例#3
0
        private void toString(ObjToIntMap printIds, System.Text.StringBuilder sb)
        {
            if (Token.printTrees)
            {
                sb.Append(Token.name(this.Type));
                if (this is StringNode)
                {
                    sb.Append(' ');
                    sb.Append(String);
                }
                else if (this is ScriptOrFnNode)
                {
                    ScriptOrFnNode sof = (ScriptOrFnNode)this;
                    if (this is FunctionNode)
                    {
                        FunctionNode fn = (FunctionNode)this;
                        sb.Append(' ');
                        sb.Append(fn.FunctionName);
                    }
                    sb.Append(" [source name: ");
                    sb.Append(sof.SourceName);
                    sb.Append("] [encoded source length: ");
                    sb.Append(sof.EncodedSourceEnd - sof.EncodedSourceStart);
                    sb.Append("] [base line: ");
                    sb.Append(sof.BaseLineno);
                    sb.Append("] [end line: ");
                    sb.Append(sof.EndLineno);
                    sb.Append(']');
                }
                else if (this is Jump)
                {
                    Jump jump = (Jump)this;
                    if (this.Type == Token.BREAK || this.Type == Token.CONTINUE)
                    {
                        sb.Append(" [label: ");
                        appendPrintId(jump.JumpStatement, printIds, sb);
                        sb.Append(']');
                    }
                    else if (this.Type == Token.TRY)
                    {
                        Node catchNode     = jump.target;
                        Node finallyTarget = jump.Finally;
                        if (catchNode != null)
                        {
                            sb.Append(" [catch: ");
                            appendPrintId(catchNode, printIds, sb);
                            sb.Append(']');
                        }
                        if (finallyTarget != null)
                        {
                            sb.Append(" [finally: ");
                            appendPrintId(finallyTarget, printIds, sb);
                            sb.Append(']');
                        }
                    }
                    else if (this.Type == Token.LABEL || this.Type == Token.LOOP || this.Type == Token.SWITCH)
                    {
                        sb.Append(" [break: ");
                        appendPrintId(jump.target, printIds, sb);
                        sb.Append(']');
                        if (this.Type == Token.LOOP)
                        {
                            sb.Append(" [continue: ");
                            appendPrintId(jump.Continue, printIds, sb);
                            sb.Append(']');
                        }
                    }
                    else
                    {
                        sb.Append(" [target: ");
                        appendPrintId(jump.target, printIds, sb);
                        sb.Append(']');
                    }
                }
                else if (this.Type == Token.NUMBER)
                {
                    sb.Append(' ');
                    sb.Append(Double);
                }
                else if (this.Type == Token.TARGET)
                {
                    sb.Append(' ');
                    appendPrintId(this, printIds, sb);
                }
                if (lineno != -1)
                {
                    sb.Append(' ');
                    sb.Append(lineno);
                }

                for (PropListItem x = propListHead; x != null; x = x.next)
                {
                    int Type = x.Type;
                    sb.Append(" [");
                    sb.Append(propToString(Type));
                    sb.Append(": ");
                    string value;
                    switch (Type)
                    {
                    case TARGETBLOCK_PROP:      // can't add this as it recurses
                        value = "target block property";
                        break;

                    case LOCAL_BLOCK_PROP:      // can't add this as it is dull
                        value = "last local block";
                        break;

                    case ISNUMBER_PROP:
                        switch (x.intValue)
                        {
                        case BOTH:
                            value = "both";
                            break;

                        case RIGHT:
                            value = "right";
                            break;

                        case LEFT:
                            value = "left";
                            break;

                        default:
                            throw Context.CodeBug();
                        }
                        break;

                    case SPECIALCALL_PROP:
                        switch (x.intValue)
                        {
                        case SPECIALCALL_EVAL:
                            value = "eval";
                            break;

                        case SPECIALCALL_WITH:
                            value = "with";
                            break;

                        default:
                            // NON_SPECIALCALL should not be stored
                            throw Context.CodeBug();
                        }
                        break;

                    default:
                        object obj = x.objectValue;
                        if (obj != null)
                        {
                            value = obj.ToString();
                        }
                        else
                        {
                            value = Convert.ToString(x.intValue);
                        }
                        break;
                    }
                    sb.Append(value);
                    sb.Append(']');
                }
            }
        }
 public int addFunction(FunctionNode fnNode)
 {
     if (fnNode == null)
         Context.CodeBug ();
     if (functions == null) {
         functions = new ObjArray ();
     }
     functions.add (fnNode);
     return functions.size () - 1;
 }