internal Node DecompileFunctionHeader(FunctionNode fn) { Node mexpr = null; if (fn.GetFunctionName() != null) { decompiler.AddName(fn.GetName()); } else { if (fn.GetMemberExprNode() != null) { mexpr = Transform(fn.GetMemberExprNode()); } } decompiler.AddToken(Token.LP); IList<AstNode> @params = fn.GetParams(); for (int i = 0; i < @params.Count; i++) { Decompile(@params[i]); if (i < @params.Count - 1) { decompiler.AddToken(Token.COMMA); } } decompiler.AddToken(Token.RP); if (!fn.IsExpressionClosure()) { decompiler.AddEOL(Token.LC); } return mexpr; }
private Node InitFunction(FunctionNode fnNode, int functionIndex, Node statements, int functionType) { fnNode.SetFunctionType(functionType); fnNode.AddChildToBack(statements); int functionCount = fnNode.GetFunctionCount(); if (functionCount != 0) { // Functions containing other functions require activation objects fnNode.SetRequiresActivation(); } if (functionType == FunctionNode.FUNCTION_EXPRESSION) { Name name = fnNode.GetFunctionName(); if (name != null && name.Length() != 0 && fnNode.GetSymbol(name.GetIdentifier()) == null) { // 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, but only if the // function doesn't already define a formal parameter, var, // or nested function with the same name. fnNode.PutSymbol(new Symbol(Token.FUNCTION, name.GetIdentifier())); Node setFn = new Node(Token.EXPR_VOID, new Node(Token.SETNAME, Node.NewString(Token.BINDNAME, name.GetIdentifier()), new Node(Token.THISFN))); statements.AddChildrenToFront(setFn); } } // Add return to end if needed. Node lastStmt = statements.GetLastChild(); if (lastStmt == null || lastStmt.GetType() != Token.RETURN) { statements.AddChildToBack(new Node(Token.RETURN)); } Node result = Node.NewString(Token.FUNCTION, fnNode.GetName()); result.PutIntProp(Node.FUNCTION_PROP, functionIndex); return result; }