#if NET20 || NET30 || !NET_4_6 // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Diagnostics; namespace System.Linq.Expressions.Reimplement { /// /// Represents an infinite loop. It can be exited with "break". /// [DebuggerTypeProxy(typeof(LoopExpressionProxy))] public sealed class LoopExpression : Expression { private readonly Expression _body; private readonly LabelTarget _break; private readonly LabelTarget _continue; internal LoopExpression(Expression body, LabelTarget @break, LabelTarget @continue) { _body = body; _break = @break; _continue = @continue; } /// /// Gets the static type of the expression that this represents. /// /// The that represents the static type of the expression. public override Type Type { get { return _break == null ? typeof(void) : _break.Type; } } /// /// Returns the node type of this Expression. Extension nodes should return /// ExpressionType.Extension when overriding this method. /// /// The of the expression. public override ExpressionType NodeType { get { return ExpressionType.Loop; } } /// /// Gets the that is the body of the loop. /// public Expression Body { get { return _body; } } /// /// Gets the that is used by the loop body as a break statement target. /// public LabelTarget BreakLabel { get { return _break; } } /// /// Gets the that is used by the loop body as a continue statement target. /// public LabelTarget ContinueLabel { get { return _continue; } } protected internal override Expression Accept(ExpressionVisitor visitor) { return visitor.VisitLoop(this); } /// /// Creates a new expression that is like this one, but using the /// supplied children. If all of the children are the same, it will /// return this expression. /// /// The property of the result. /// The property of the result. /// The property of the result. /// This expression if no children changed, or an expression with the updated children. public LoopExpression Update(LabelTarget breakLabel, LabelTarget continueLabel, Expression body) { if (breakLabel == BreakLabel && continueLabel == ContinueLabel && body == Body) { return this; } return Loop(body, breakLabel, continueLabel); } } public partial class Expression { /// /// Creates a with the given body. /// /// The body of the loop. /// The created . public static LoopExpression Loop(Expression body) { return Loop(body, null); } /// /// Creates a with the given body and break target. /// /// The body of the loop. /// The break target used by the loop body. /// The created . public static LoopExpression Loop(Expression body, LabelTarget @break) { return Loop(body, @break, null); } /// /// Creates a with the given body. /// /// The body of the loop. /// The break target used by the loop body. /// The continue target used by the loop body. /// The created . public static LoopExpression Loop(Expression body, LabelTarget @break, LabelTarget @continue) { RequiresCanRead(body, "body"); if (@continue != null && @continue.Type != typeof(void)) { throw Error.LabelTypeMustBeVoid(); } return new LoopExpression(body, @break, @continue); } } } #endif