private Expression Convert(LinqExp.MethodCallExpression linqCall) { return(Expression.Call( ConvertExp(linqCall.Object), linqCall.Method, Convert(linqCall.Arguments))); }
internal Expression Reduce() { // Visit body Expression body = Visit(_generator.Body); Debug.Assert(_returnLabels.Count == 1); // Add the switch statement to the body int count = _yields.Count; var cases = new SwitchCase[count + 1]; for (int i = 0; i < count; i++) { cases[i] = Expression.SwitchCase(Expression.Goto(_yields[i].Label), AstUtils.Constant(_yields[i].State)); } cases[count] = Expression.SwitchCase(Expression.Goto(_returnLabels.Peek()), AstUtils.Constant(Finished)); Type generatorNextOfT = typeof(GeneratorNext <>).MakeGenericType(_generator.Target.Type); // Create the lambda for the GeneratorNext<T>, hoisting variables // into a scope outside the lambda var allVars = new List <ParameterExpression>(_vars); allVars.AddRange(_temps); // Collect temps that don't have to be closed over var innerTemps = new ReadOnlyCollectionBuilder <ParameterExpression>(1 + (_labelTemps != null ? _labelTemps.Count : 0)); innerTemps.Add(_gotoRouter); if (_labelTemps != null) { foreach (LabelInfo info in _labelTemps.Values) { innerTemps.Add(info.Temp); } } body = Expression.Block( allVars, Expression.Lambda( generatorNextOfT, Expression.Block( innerTemps, Expression.Switch(Expression.Assign(_gotoRouter, _state), cases), body, Expression.Assign(_state, AstUtils.Constant(Finished)), Expression.Label(_returnLabels.Peek()) ), _generator.Name, new ParameterExpression[] { _state, _current } ) ); // Enumerable factory takes Func<GeneratorNext<T>> instead of GeneratorNext<T> if (_generator.IsEnumerable) { body = Expression.Lambda(body); } // We can't create a ConstantExpression of _debugCookies array here because we walk the tree // after constants have already been rewritten. Instead we create a NewArrayExpression node // which initializes the array with contents from _debugCookies Expression debugCookiesArray = null; if (_debugCookies != null) { Expression[] debugCookies = new Expression[_debugCookies.Count]; for (int i = 0; i < _debugCookies.Count; i++) { debugCookies[i] = AstUtils.Constant(_debugCookies[i]); } debugCookiesArray = Expression.NewArrayInit( typeof(int), debugCookies); } // Generate a call to ScriptingRuntimeHelpers.MakeGenerator<T>(args) return(Expression.Call( typeof(ScriptingRuntimeHelpers), "MakeGenerator", new[] { _generator.Target.Type }, (debugCookiesArray != null) ? new[] { body, debugCookiesArray } : new[] { body } )); }