/// <summary> /// Creates a <see cref="ForCSharpStatement"/> that represents a for loop. /// </summary> /// <param name="initializers">The loop initializers.</param> /// <param name="test">The condition of the loop.</param> /// <param name="iterators">The loop iterators.</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> /// <returns>The created <see cref="ForCSharpStatement"/>.</returns> public static ForCSharpStatement For(IEnumerable <BinaryExpression> initializers, Expression test, IEnumerable <Expression> iterators, Expression body, LabelTarget @break, LabelTarget @continue) { ValidateLoop(test, body, @break, @continue, optionalTest: true); // NB: While C# requires all initializers to be of the same type, we don't quite need that restriction here. // This can be revisited. We will check whether all initializers are simple assignments though. var initializerList = initializers.ToReadOnly <Expression>(); var uniqueVariables = new HashSet <ParameterExpression>(); var variables = new List <ParameterExpression>(); foreach (BinaryExpression initializer in initializerList) { if (initializer.NodeType != ExpressionType.Assign || initializer.Left.NodeType != ExpressionType.Parameter) { throw Error.InvalidInitializer(); } var variable = (ParameterExpression)initializer.Left; if (!uniqueVariables.Add(variable)) { throw LinqError.DuplicateVariable(variable); } // NB: We keep them in the order specified and don't rely on the hash set. variables.Add(variable); } var variableList = variables.ToReadOnly(); var iteratorList = iterators.ToReadOnly(); return(ForCSharpStatement.Make(variableList, initializerList, test, iteratorList, body, @break, @continue)); }
/// <summary> /// Creates a <see cref="ForCSharpStatement"/> that represents a for loop. /// </summary> /// <param name="variables">The variables in scope of the loop.</param> /// <param name="initializers">The loop initializers.</param> /// <param name="test">The condition of the loop.</param> /// <param name="iterators">The loop iterators.</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> /// <returns>The created <see cref="ForCSharpStatement"/>.</returns> public static ForCSharpStatement For(IEnumerable <ParameterExpression> variables, IEnumerable <Expression> initializers, Expression test, IEnumerable <Expression> iterators, Expression body, LabelTarget @break, LabelTarget @continue) { ValidateLoop(test, body, @break, @continue, optionalTest: true); // NB: While C# requires all initializers to be of the same type, we don't quite need that restriction here. // This can be revisited. We will check whether all initializers are simple assignments though. var variableList = variables.ToReadOnly(); var initializerList = initializers.ToReadOnly <Expression>(); RequiresNotNullItems(initializerList, nameof(initializers)); var uniqueVariables = new HashSet <ParameterExpression>(); foreach (var variable in variableList) { if (!uniqueVariables.Add(variable)) { throw LinqError.DuplicateVariable(variable); } } var iteratorList = iterators.ToReadOnly(); RequiresNotNullItems(iteratorList, nameof(iterators)); return(ForCSharpStatement.Make(variableList, initializerList, test, iteratorList, body, @break, @continue)); }
protected internal virtual Expression VisitFor(ForCSharpStatement node) => node.Update( VisitLabelTarget(node.BreakLabel), VisitLabelTarget(node.ContinueLabel), VisitAndConvert(node.Variables, nameof(VisitFor)), Visit(node.Initializers), Visit(node.Test), Visit(node.Iterators), Visit(node.Body), VisitAndConvert(node.Locals, nameof(VisitFor)) );
/// <summary> /// Creates a <see cref="ForCSharpStatement"/> that represents a for loop. /// </summary> /// <param name="variables">The variables in scope of the loop.</param> /// <param name="initializers">The loop initializers.</param> /// <param name="test">The condition of the loop.</param> /// <param name="iterators">The loop iterators.</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="locals">The variables that are in scope of the loop.</param> /// <returns>The created <see cref="ForCSharpStatement"/>.</returns> public static ForCSharpStatement For(IEnumerable <ParameterExpression> variables, IEnumerable <Expression> initializers, Expression test, IEnumerable <Expression> iterators, Expression body, LabelTarget @break, LabelTarget @continue, IEnumerable <ParameterExpression> locals) { ValidateLoop(test, body, @break, @continue, optionalTest: true); // NB: While C# requires all initializers to be of the same type, we don't quite need that restriction here. // This can be revisited. We will check whether all initializers are simple assignments though. var variableList = CheckUniqueVariables(variables, nameof(variables)); var initializerList = initializers.ToReadOnly(); RequiresNotNullItems(initializerList, nameof(initializers)); var iteratorList = iterators.ToReadOnly(); RequiresNotNullItems(iteratorList, nameof(iterators)); var localsList = CheckUniqueVariables(locals, nameof(locals)); return(ForCSharpStatement.Make(variableList, initializerList, test, iteratorList, body, @break, @continue, localsList)); }
protected internal override Expression VisitFor(ForCSharpStatement node) { var args = new List <object>(); if (node.Variables.Count > 0) { args.Add(Visit(nameof(node.Variables), node.Variables)); } if (node.Initializers.Count > 0) { args.Add(Visit(nameof(node.Initializers), node.Initializers)); } if (node.Test != null) { args.Add(new XElement(nameof(node.Test), Visit(node.Test))); } if (node.Iterators.Count > 0) { args.Add(Visit(nameof(node.Iterators), node.Iterators)); } 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)); }
protected internal virtual Expression VisitFor(ForCSharpStatement node) { return node.Update(VisitLabelTarget(node.BreakLabel), VisitLabelTarget(node.ContinueLabel), VisitAndConvert(node.Variables, nameof(VisitFor)), Visit(node.Initializers), Visit(node.Test), Visit(node.Iterators), Visit(node.Body)); }
public ForCSharpStatementProxy(ForCSharpStatement node) { _node = node; }
protected internal override Expression VisitFor(ForCSharpStatement node) { Visited = true; return base.VisitFor(node); }