protected internal override Expression VisitForEach(ForEachCSharpStatement node) { var args = new List <object>(); args.Add(new XElement(nameof(node.Variable), Visit(node.Variable))); if (node.Conversion != null) { args.Add(new XElement(nameof(node.Conversion), Visit(node.Conversion))); } args.Add(new XElement(nameof(node.Collection), Visit(node.Collection))); args.Add(new XElement(nameof(node.Body), Visit(node.Body))); if (node.BreakLabel != null) { args.Add(new XElement(nameof(node.BreakLabel), _parent.GetDebugView(node.BreakLabel))); } if (node.ContinueLabel != null) { args.Add(new XElement(nameof(node.ContinueLabel), _parent.GetDebugView(node.ContinueLabel))); } return(Push(node, args)); }
/// <summary> /// Creates a <see cref="ForEachCSharpStatement"/> that represents a foreach loop. /// </summary> /// <param name="variable">The iteration variable.</param> /// <param name="collection">The collection to iterate over.</param> /// <param name="body">The body of the loop.</param> /// <param name="break">The break target used by the loop body.</param> /// <param name="continue">The continue target used by the loop body.</param> /// <param name="conversion">The conversion function used to convert elements in the collection to the iteration variable type.</param> /// <returns>The created <see cref="ForEachCSharpStatement"/>.</returns> public static ForEachCSharpStatement ForEach(ParameterExpression variable, Expression collection, Expression body, LabelTarget @break, LabelTarget @continue, LambdaExpression conversion) { // NB: This is the overload the C# compiler can bind to. Note, however, that a bound foreach node in Roslyn has // information about GetEnumerator, MoveNext, Current, etc. as well. We can infer the same information at // runtime, but could also add an overload that has all of these. // NB: Conversion of the collection should be inserted as a Convert node by the compiler. // // TODO: Do we need to add a means to perform an enumerator conversion? Cf. ForEachEnumeratorInfo in Roslyn. return(ForEachCSharpStatement.Make(variable, collection, body, @break, @continue, conversion)); }
protected internal virtual Expression VisitForEach(ForEachCSharpStatement node) { return node.Update(VisitLabelTarget(node.BreakLabel), VisitLabelTarget(node.ContinueLabel), VisitAndConvert(node.Variable, nameof(VisitForEach)), Visit(node.Collection), VisitAndConvert(node.Conversion, nameof(VisitForEach)), Visit(node.Body)); }
public ForEachCSharpStatementProxy(ForEachCSharpStatement node) { _node = node; }
protected internal virtual Expression VisitForEach(ForEachCSharpStatement node) { return(node.Update(VisitLabelTarget(node.BreakLabel), VisitLabelTarget(node.ContinueLabel), VisitAndConvert(node.Variable, nameof(VisitForEach)), Visit(node.Collection), VisitAndConvert(node.Conversion, nameof(VisitForEach)), Visit(node.Body))); }