private Node TransformGenExpr(GeneratorExpression node) { Node pn; FunctionNode fn = new FunctionNode(); fn.SetSourceName(currentScriptOrFn.GetNextTempName()); fn.SetIsGenerator(); fn.SetFunctionType(FunctionNode.FUNCTION_EXPRESSION); fn.SetRequiresActivation(); int functionType = fn.GetFunctionType(); int start = decompiler.MarkFunctionStart(functionType); Node mexpr = DecompileFunctionHeader(fn); int index = currentScriptOrFn.AddFunction(fn); Parser.PerFunctionVariables savedVars = new Parser.PerFunctionVariables(this, fn); try { // If we start needing to record much more codegen metadata during // function parsing, we should lump it all into a helper class. Node destructuring = (Node)fn.GetProp(Node.DESTRUCTURING_PARAMS); fn.RemoveProp(Node.DESTRUCTURING_PARAMS); int lineno = node.lineno; ++nestingOfFunction; // only for body, not params Node body = GenExprTransformHelper(node); if (!fn.IsExpressionClosure()) { decompiler.AddToken(Token.RC); } fn.SetEncodedSourceBounds(start, decompiler.MarkFunctionEnd(start)); if (functionType != FunctionNode.FUNCTION_EXPRESSION && !fn.IsExpressionClosure()) { // Add EOL only if function is not part of expression // since it gets SEMI + EOL from Statement in that case decompiler.AddToken(Token.EOL); } if (destructuring != null) { body.AddChildToFront(new Node(Token.EXPR_VOID, destructuring, lineno)); } int syntheticType = fn.GetFunctionType(); pn = InitFunction(fn, index, body, syntheticType); if (mexpr != null) { pn = CreateAssignment(Token.ASSIGN, mexpr, pn); if (syntheticType != FunctionNode.FUNCTION_EXPRESSION) { pn = CreateExprStatementNoReturn(pn, fn.GetLineno()); } } } finally { --nestingOfFunction; savedVars.Restore(); } Node call = CreateCallOrNew(Token.CALL, pn); call.SetLineno(node.GetLineno()); decompiler.AddToken(Token.LP); decompiler.AddToken(Token.RP); return call; }