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));
            }
        }
コード例 #2
0
        // 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);
        }
コード例 #3
0
 public override void Dispose()
 {
     lambdaResult = null;
     returnLabel  = null;
     recursion    = null;
     base.Dispose();
 }
コード例 #4
0
 /// <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));
 }
コード例 #6
0
 private void AttachLabel(LabelTarget?target)
 {
     if (target is not null)
     {
         ExpressionAttributes.Get(CurrentStatement)?.Labels.Add(target);
         target.GetUserData().GetOrSet(StateIdPlaceholder).StateId = stateId;
     }
 }
コード例 #7
0
        /// <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));
        }
コード例 #8
0
 protected override LabelTarget?VisitLabelTarget(LabelTarget?node)
 {
     if (node != null)
     {
         Combine(node.Name);
         Combine(node.Type);
     }
     return(base.VisitLabelTarget(node));
 }
コード例 #9
0
 /// <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));
 }
コード例 #10
0
ファイル: LabelExpression.cs プロジェクト: csharpHub/Theraot
        /// <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));
 }
コード例 #14
0
 internal StateTransition(LabelTarget?successful, LabelTarget?failed)
 {
     if (successful is null && failed is null)
     {
         throw new ArgumentNullException(nameof(successful));
     }
     Successful = successful;
     Failure    = failed;
 }
コード例 #15
0
ファイル: LabelExpression.cs プロジェクト: csharpHub/Theraot
        /// <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));
        }
コード例 #16
0
        /// <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)));
        }
コード例 #17
0
 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));
 }
コード例 #18
0
        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");
 }
コード例 #20
0
ファイル: LoopExpression.cs プロジェクト: csharpHub/Theraot
        /// <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));
        }
コード例 #21
0
        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));
        }
コード例 #22
0
 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);
     }
 }
コード例 #23
0
 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);
 }
コード例 #24
0
        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));
            }
        }
コード例 #25
0
        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);
        }
コード例 #26
0
        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");
        }
コード例 #27
0
 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");
 }
コード例 #28
0
        /// <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));
            }
        }