示例#1
0
		private Node GenExprTransformHelper(GeneratorExpression node)
		{
			decompiler.AddToken(Token.LP);
			int lineno = node.GetLineno();
			Node expr = Transform(node.GetResult());
			IList<GeneratorExpressionLoop> loops = node.GetLoops();
			int numLoops = loops.Count;
			// Walk through loops, collecting and defining their iterator symbols.
			Node[] iterators = new Node[numLoops];
			Node[] iteratedObjs = new Node[numLoops];
			for (int i = 0; i < numLoops; i++)
			{
				GeneratorExpressionLoop acl = loops[i];
				decompiler.AddName(" ");
				decompiler.AddToken(Token.FOR);
				decompiler.AddToken(Token.LP);
				AstNode iter = acl.GetIterator();
				string name = null;
				if (iter.GetType() == Token.NAME)
				{
					name = iter.GetString();
					decompiler.AddName(name);
				}
				else
				{
					// destructuring assignment
					Decompile(iter);
					name = currentScriptOrFn.GetNextTempName();
					DefineSymbol(Token.LP, name, false);
					expr = CreateBinary(Token.COMMA, CreateAssignment(Token.ASSIGN, iter, CreateName(name)), expr);
				}
				Node init = CreateName(name);
				// Define as a let since we want the scope of the variable to
				// be restricted to the array comprehension
				DefineSymbol(Token.LET, name, false);
				iterators[i] = init;
				decompiler.AddToken(Token.IN);
				iteratedObjs[i] = Transform(acl.GetIteratedObject());
				decompiler.AddToken(Token.RP);
			}
			// generate code for tmpArray.push(body)
			Node yield = new Node(Token.YIELD, expr, node.GetLineno());
			Node body = new Node(Token.EXPR_VOID, yield, lineno);
			if (node.GetFilter() != null)
			{
				decompiler.AddName(" ");
				decompiler.AddToken(Token.IF);
				decompiler.AddToken(Token.LP);
				body = CreateIf(Transform(node.GetFilter()), body, null, lineno);
				decompiler.AddToken(Token.RP);
			}
			// Now walk loops in reverse to build up the body statement.
			int pushed = 0;
			try
			{
				for (int i_1 = numLoops - 1; i_1 >= 0; i_1--)
				{
					GeneratorExpressionLoop acl = loops[i_1];
					Scope loop = CreateLoopNode(null, acl.GetLineno());
					// no label
					PushScope(loop);
					pushed++;
					body = CreateForIn(Token.LET, loop, iterators[i_1], iteratedObjs[i_1], body, acl.IsForEach());
				}
			}
			finally
			{
				for (int i_1 = 0; i_1 < pushed; i_1++)
				{
					PopScope();
				}
			}
			decompiler.AddToken(Token.RP);
			return body;
		}
示例#2
0
		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;
		}