示例#1
0
        AST Function(AST parent, FunctionType ft)
        {
            FunctionType synthetic_type = ft;
            string name;
            AST member_expr = null;

            if (ts.MatchToken (Token.NAME)) {
                name = ts.GetString;
                if (!ts.MatchToken (Token.LP)) {
                    if (allow_member_expr_as_function_name) {
                        // Extension to ECMA: if 'function <name>' does not follow
                        // by '(', assume <name> starts memberExpr
                        // FIXME: is StringLiteral the correct AST to build?
                        decompiler.AddName (name);
                        AST member_expr_head = new StringLiteral (null, name,
                                      new Location (ts.SourceName, ts.LineNumber));
                        name = "";
                        member_expr = MemberExprTail (parent, false, member_expr_head);
                    }
                    MustMatchToken (Token.LP, "msg.no.paren.parms");
                }
            } else if (ts.MatchToken (Token.LP)) {
                // Anonymous function
                name = "";
            } else {
                name = "";
                if (allow_member_expr_as_function_name) {
                    // Note that memberExpr can not start with '(' like
                    // in function (1+2).toString(), because 'function (' already
                    // processed as anonymous function
                    member_expr = MemberExpr (parent, false);
                }
                MustMatchToken (Token.LP, "msg.no.paren.parms");
            }

            if (member_expr != null) {
                synthetic_type = FunctionType.Expression;
                decompiler.AddToken (Token.ASSIGN);
            }

            bool nested = InsideFunction;
            Function fn = CreateFunction (parent, synthetic_type, name);

            if (nested)
                fn.CheckThis = true;

            if (nested || nesting_of_with > 0) {
                // 1. Nested functions are not affected by the dynamic scope flag
                // as dynamic scope is already a parent of their scope.
                // 2. Functions defined under the with statement also immune to
                // this setup, in which case dynamic scope is ignored in favor
                // of with object.
                fn.IgnoreDynamicScope = true;
            }

            // FIXME: which is old version of Decompiler.MarkFunctionStart
            int functionSourceStart = decompiler.MarkFunctionStart ((int) synthetic_type);

            if (name != "")
                decompiler.AddName (name);

            int saved_nesting_of_with = nesting_of_with;
            nesting_of_with = 0;

            FormalParameterList _params = new FormalParameterList (new Location (ts.SourceName, ts.LineNumber));
            Block body;

            try {
                decompiler.AddToken (Token.LP);
                if (!ts.MatchToken (Token.RP)) {
                    bool first = true;
                    do {
                        if (!first)
                            decompiler.AddToken (Token.COMMA);
                        first = false;
                        MustMatchToken (Token.NAME, "msg.no.parm");
                        string s = ts.GetString;
                        _params.Add (s, String.Empty, new Location (ts.SourceName, ts.LineNumber));
                        decompiler.AddName (s);
                    } while (ts.MatchToken (Token.COMMA));
                    MustMatchToken (Token.RP, "msg.no.paren.after.parms");
                }
                decompiler.AddToken (Token.RP);

                MustMatchToken (Token.LC, "msg.no.brace.body");
                decompiler.AddEOL (Token.LC);
                body = ParseFunctionBody (fn);
                MustMatchToken (Token.RC, "msg.no.brace.after.body");

                decompiler.AddToken (Token.RC);
                decompiler.MarkFunctionEnd (functionSourceStart);

                fn.func_obj.source = decompiler.SourceToString (functionSourceStart);

                if (ft != FunctionType.Expression) {
                    CheckWellTerminatedFunction ();
                    if (member_expr == null)
                        decompiler.AddToken (Token.EOL);
                    else
                        decompiler.AddEOL (Token.SEMI);
                }
            } finally {
                nesting_of_with = saved_nesting_of_with;
            }

            fn.Init (body, _params);
            AST pn;

            if (member_expr == null) {
                // FIXME
                pn = fn;

                // FIXME, research about createExprStatementNoReturn
                if (ft == FunctionType.ExpressionStatement)
                    pn = null;
            } else {
                // FIXME
                pn = fn;
                Assign assign = new Assign (null, JSToken.Assign, new Location (ts.SourceName, ts.LineNumber));
                assign.Init (member_expr, pn, false);
                pn = assign;

            #if false
                // FIXME, research about createExprStatement
                if (ft != FunctionType.Expression)
                    ;
            #endif
            }
            return pn;
        }
示例#2
0
        AST AssignExpr(AST parent, bool in_for_init)
        {
            AST pn = CondExpr (parent, in_for_init);
            int tt = ts.PeekToken ();

            // omitted: "invalid assignment left-hand side" check.
            if (tt == Token.ASSIGN) {
                ts.GetToken ();
                decompiler.AddToken (Token.ASSIGN);
                Assign assign = new Assign (parent, JSToken.Assign, new Location (ts.SourceName, ts.LineNumber));
                assign.Init (pn, AssignExpr (assign, in_for_init), false);
                pn = assign;
                return pn;
            } else if (tt == Token.ASSIGNOP) {
                ts.GetToken ();
                int op = ts.GetOp ();
                decompiler.AddAssignOp (op);
                Assign assign = new Assign (parent, ToJSToken (op, tt), new Location (ts.SourceName, ts.LineNumber));
                assign.Init (pn, AssignExpr (assign, in_for_init), false);
                pn = assign;
            }
            return pn;
        }