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;
}