private static void CheckForEachArgs (ParameterExpression variable, Expression enumerable, Expression body, LabelTarget?continueTarget) { if (variable is null) { throw new ArgumentNullException(nameof(variable)); } if (enumerable is null) { throw new ArgumentNullException(nameof(enumerable)); } if (body is null) { throw new ArgumentNullException(nameof(body)); } if (continueTarget is not null && continueTarget.Type != typeof(void)) { throw new ArgumentException("Continue label target must be void", nameof(continueTarget)); } }
// for synchronous collection internal ForEachExpression(Expression collection, LabelTarget?continueLabel, LabelTarget?breakLabel) { collection.Type.GetItemType(out var enumerable); const string GetEnumeratorMethod = nameof(IEnumerable.GetEnumerator); MethodCallExpression getEnumerator; if (enumerable is null) { getEnumerator = collection.Call(collection.Type.GetMethod(GetEnumeratorMethod, Array.Empty <Type>()) ?? throw new ArgumentException(ExceptionMessages.EnumerablePatternExpected)); enumeratorVar = Variable(getEnumerator.Method.ReturnType, EnumeratorVarName); moveNextCall = Call(enumeratorVar, nameof(IEnumerator.MoveNext), Array.Empty <Type>()); } else { getEnumerator = collection.Call(enumerable, GetEnumeratorMethod); enumeratorVar = Variable(getEnumerator.Method.ReturnType, EnumeratorVarName); // enumerator.MoveNext() moveNextCall = enumeratorVar.Call(typeof(IEnumerator), nameof(IEnumerator.MoveNext)); } // enumerator = enumerable.GetEnumerator(); enumeratorAssignment = Assign(enumeratorVar, getEnumerator); Element = Property(enumeratorVar, nameof(IEnumerator.Current)); BreakLabel = breakLabel ?? Label(typeof(void), BreakLabelName); ContinueLabel = continueLabel ?? Label(typeof(void), ContinueLabelName); }
public override void Dispose() { lambdaResult = null; returnLabel = null; recursion = null; base.Dispose(); }
/// <summary> /// 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. /// </summary> /// <param name="breakLabel">The <see cref="BreakLabel"/> property of the result.</param> /// <param name="continueLabel">The <see cref="ContinueLabel"/> property of the result.</param> /// <param name="body">The <see cref="Body"/> property of the result.</param> /// <returns>This expression if no children changed, or an expression with the updated children.</returns> public LoopExpression Update(LabelTarget?breakLabel, LabelTarget?continueLabel, Expression body) { if (breakLabel == BreakLabel && continueLabel == ContinueLabel && body == Body) { return(this); } return(Expression.Loop(body, breakLabel, continueLabel)); }
public static WhileExpression WhileUnchecked( Expression test, Expression body, LabelTarget?breakTarget, LabelTarget?continueTarget) { return(new WhileExpression(test, body, breakTarget, continueTarget)); }
private void AttachLabel(LabelTarget?target) { if (target is not null) { ExpressionAttributes.Get(CurrentStatement)?.Labels.Add(target); target.GetUserData().GetOrSet(StateIdPlaceholder).StateId = stateId; } }
/// <summary> /// 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. /// </summary> /// <param name="target">The <see cref="Target" /> property of the result.</param> /// <param name="value">The <see cref="Value" /> property of the result.</param> /// <returns>This expression if no children changed, or an expression with the updated children.</returns> public GotoExpression Update(LabelTarget?target, Expression?value) { if (target == Target && value == Value) { return(this); } return(MakeGoto(Kind, target, value, Type)); }
protected override LabelTarget?VisitLabelTarget(LabelTarget?node) { if (node != null) { Combine(node.Name); Combine(node.Type); } return(base.VisitLabelTarget(node)); }
/// <summary> /// Creates a <see cref="LoopExpression"/> with the given body. /// </summary> /// <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="LoopExpression"/>.</returns> public static LoopExpression Loop(Expression body, LabelTarget? @break, LabelTarget? @continue) { ExpressionUtils.RequiresCanRead(body, nameof(body)); if (@continue != null && @continue.Type != typeof(void)) { throw Error.LabelTypeMustBeVoid(nameof(@continue)); } return(new LoopExpression(body, @break, @continue)); }
/// <summary> /// 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. /// </summary> /// <param name="target">The <see cref="Target" /> property of the result.</param> /// <param name="defaultValue">The <see cref="DefaultValue" /> property of the result.</param> /// <returns>This expression if no children changed, or an expression with the updated children.</returns> public LabelExpression Update(LabelTarget?target, Expression?defaultValue) { if (target == Target && defaultValue == DefaultValue) { return(this); } return(Label(target, defaultValue)); }
public static ForEachExpression ForEach( ParameterExpression variable, Expression enumerable, Expression body, LabelTarget?breakTarget) { CheckForEachArgs(variable, enumerable, body, continueTarget: null); return(ForEachUnchecked(variable, enumerable, body, breakTarget, continueTarget: null)); }
public static ForEachExpression ForEachUnchecked( ParameterExpression variable, Expression enumerable, Expression body, LabelTarget?breakTarget, LabelTarget?continueTarget) { return(new ForEachExpression(variable, enumerable, body, breakTarget, continueTarget)); }
public static WhileExpression While( Expression test, Expression body, LabelTarget?breakTarget, LabelTarget?continueTarget) { CheckWhileArgs(test, body, continueTarget); return(WhileUnchecked(test, body, breakTarget, continueTarget)); }
internal StateTransition(LabelTarget?successful, LabelTarget?failed) { if (successful is null && failed is null) { throw new ArgumentNullException(nameof(successful)); } Successful = successful; Failure = failed; }
/// <summary> /// Creates a <see cref="LabelExpression" /> representing a label with the given default value. /// </summary> /// <param name="target">The <see cref="LabelTarget" /> which this <see cref="LabelExpression" /> will be associated with.</param> /// <param name="defaultValue"> /// The value of this <see cref="LabelExpression" /> when the label is reached through normal /// control flow. /// </param> /// <returns>A <see cref="LabelExpression" /> with the given default value.</returns> public static LabelExpression Label(LabelTarget?target, Expression?defaultValue) { if (target == null) { throw new ArgumentNullException(nameof(target)); } ValidateGoto(target, ref defaultValue, nameof(defaultValue), null); return(new LabelExpression(target, defaultValue)); }
/// <summary>Gets the hash code for the specified LabelTarget.</summary> /// <param name="labelTarget">The LabelTarget for which to get a hash code.</param> /// <returns>A hash code for the specified LabelTarget.</returns> protected virtual int GetHashCodeLabelTarget([AllowNull] LabelTarget?labelTarget) { if (labelTarget == null) { return(0); } return(GetHashCode( GetDefaultHashCode(labelTarget.Type), GetDefaultHashCode(labelTarget.Name))); }
public static ForExpression ForUnchecked( ParameterExpression variable, Expression initializer, Expression test, Expression step, Expression body, LabelTarget?breakTarget, LabelTarget?continueTarget) { return(new ForExpression(variable, initializer, test, step, body, breakTarget, continueTarget)); }
private LabelInfo DefineLabel(LabelTarget?node) { if (node == null) { return(new LabelInfo(_ilg, null, false)); } LabelInfo result = EnsureLabel(node); result.Define(_labelBlock); return(result); }
internal WhileExpression( Expression test, Expression body, LabelTarget?breakTarget, LabelTarget?continueTarget) { Test = test; Body = body; BreakTarget = breakTarget ?? Expression.Label("BREAK"); ContinueTarget = continueTarget ?? Expression.Label("CONTINUE"); }
/// <summary> /// Creates a <see cref="LoopExpression" /> with the given body. /// </summary> /// <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="LoopExpression" />.</returns> public static LoopExpression Loop(Expression body, LabelTarget? @break, LabelTarget? @continue) { ContractUtils.RequiresNotNull(body, nameof(body)); ExpressionUtils.RequiresCanRead(body, nameof(body)); if (@continue != null && @continue.Type != typeof(void)) { throw new ArgumentException("Type must be System.Void for this label argument", nameof(@continue)); } return(new LoopExpression(body, @break, @continue)); }
public static GotoExpression MakeGoto(GotoExpressionKind kind, LabelTarget?target, Expression?value, Type type) { if (target == null) { throw new ArgumentNullException(nameof(target)); } ValidateGoto(target, ref value, nameof(value), type); return(new GotoExpression(kind, target, value, type)); }
internal TryCatchFinallyStatement(TryExpression expression, IDictionary <uint, StateTransition> transitionTable, uint previousState, ref uint stateId) : base(expression, Label("fault_" + (++stateId))) { prologue.AddFirst(new EnterGuardedCodeExpression(stateId)); this.previousState = previousState; transitionTable[stateId] = new StateTransition(null, FaultLabel); if (expression.Handlers.Count > 0) { recoveryStateId = ++stateId; finallyLabel = Label("finally_" + stateId); transitionTable[recoveryStateId] = new StateTransition(null, finallyLabel); } }
internal override Expression Return(Expression?result) { if (returnLabel is null) { returnLabel = Expression.Label("leave"); } if (result is null) { result = Expression.Default(returnType); } result = returnType == typeof(void) ? Expression.Return(returnLabel) : Expression.Block(Expression.Assign(Result !, result), Expression.Return(returnLabel)); return(result); }
private static void CheckForArgs( ParameterExpression variable, Expression initializer, Expression test, Expression step, Expression body, LabelTarget?continueTarget) { if (variable is null) { throw new ArgumentNullException(nameof(variable)); } if (initializer is null) { throw new ArgumentNullException(nameof(initializer)); } if (test is null) { throw new ArgumentNullException(nameof(test)); } if (step is null) { throw new ArgumentNullException(nameof(step)); } if (body is null) { throw new ArgumentNullException(nameof(body)); } if (!variable.Type.IsAssignableFrom(initializer.Type)) { throw new ArgumentException("Initializer must be assignable to variable", nameof(initializer)); } if (test.Type != typeof(bool)) { throw new ArgumentException("Test must be a boolean expression", nameof(test)); } if (continueTarget is not null && continueTarget.Type != typeof(void)) { throw new ArgumentException("Continue label target must be void", nameof(continueTarget)); } }
protected override LabelTarget?VisitLabelTarget(LabelTarget?node) { LabelTarget?targetCopy; if (node is null) { targetCopy = null; } else if (!labelReplacement.TryGetValue(node, out targetCopy)) { targetCopy = Expression.Label(node.Type, node.Name); labelReplacement.Add(node, targetCopy); } return(targetCopy); }
internal WhileExpression(Expression test, LabelTarget?continueLabel, LabelTarget?breakLabel, bool checkConditionFirst) { if (test is null) { throw new ArgumentNullException(nameof(test)); } else if (test.Type != typeof(bool)) { throw new ArgumentException(ExceptionMessages.TypeExpected <bool>(), nameof(test)); } Test = test; conditionFirst = checkConditionFirst; ContinueLabel = continueLabel ?? Label(typeof(void), "continue"); BreakLabel = breakLabel ?? Label(typeof(void), "break"); }
internal ForExpression( ParameterExpression variable, Expression initializer, Expression test, Expression step, Expression body, LabelTarget?breakTarget, LabelTarget?continueTarget) { Variable = variable; Initializer = initializer; Test = test; Step = step; Body = body; BreakTarget = breakTarget ?? Expression.Label("break"); ContinueTarget = continueTarget ?? Expression.Label("continue"); }
/// <summary>Determines whether the children of the two LabelTarget are equal.</summary> /// <param name="x">The first LabelTarget to compare.</param> /// <param name="y">The second LabelTarget to compare.</param> /// <param name="context"></param> /// <returns>true if the specified LabelTarget are equal; otherwise, false.</returns> protected virtual bool EqualsLabelTarget([AllowNull] LabelTarget?x, [AllowNull] LabelTarget?y, [DisallowNull] ComparisonContext context) { if (ReferenceEquals(x, y)) { return(true); } if (x == null || y == null) { return(false); } return(x.Type == y.Type && Equals(x.Name, y.Name) && context.VerifyLabelTarget(x, y)); ; }
internal ForEachExpression( ParameterExpression variable, Expression enumerable, Expression body, LabelTarget?breakTarget, LabelTarget?continueTarget) { _enumerableTypeDescriptor = EnumerableTypeDescriptor.GetTypeDescriptor(enumerable.Type); if (!_enumerableTypeDescriptor.IsEnumerable) { throw new ArgumentException("The specified argument is not enumerable.", nameof(enumerable)); } Variable = variable; Enumerable = enumerable; Body = body; BreakTarget = breakTarget ?? Expression.Label("break"); ContinueTarget = continueTarget ?? Expression.Label("continue"); }
private static void CheckWhileArgs(Expression test, Expression body, LabelTarget?continueTarget) { if (test is null) { throw new ArgumentNullException(nameof(test)); } if (body is null) { throw new ArgumentNullException(nameof(body)); } if (test.Type != typeof(bool)) { throw new ArgumentException("Test must be a boolean expression", nameof(test)); } if (continueTarget is not null && continueTarget.Type != typeof(void)) { throw new ArgumentException("Continue label target must be void", nameof(continueTarget)); } }