public static Expression ForEach(ParameterExpression item, Expression source, Expression body)
        {
            if (!typeof(IEnumerable).IsAssignableFrom(source.Type))
            {
                throw new InvalidOperationException($"{source.Type} does not implement IEnumerable and cannot be iterated using foreach");
            }

            ParameterExpression enumerator = Expression.Parameter(typeof(IEnumerator), "enumerator");
            LabelTarget         forEachEnd = Expression.Label();

            return(Expression.Block(
                       new[] { item, enumerator },

                       Expression.Assign(
                           enumerator,
                           Expression.Call(source, EnumerableMembers.GetEnumerator())
                           ),

                       Expression.Loop(
                           Expression.IfThenElse(
                               Expression.Call(enumerator, EnumerableMembers.MoveNext()),

                               Expression.Block(
                                   Expression.Assign(item, Expression.Convert(Expression.Property(enumerator, EnumerableMembers.Current()), item.Type)),
                                   body
                                   ),

                               Expression.Break(forEachEnd)
                               ),
                           forEachEnd
                           )
                       ));
        }
Beispiel #2
0
 public static bool IsWhiteSpace(string a)
 {
     return(ToOption(a)
            .Map(EnumerableMembers.Cast <char>)
            .Map(EnumerableMembers.All <char>(char.IsWhiteSpace))
            .GetOrElse(false));
 }
Beispiel #3
0
 private Expression MoveEnumerator(ParameterExpression enumerator, ParameterExpression someLeft)
 {
     return(Expression.Assign(
                someLeft,
                Expression.Call(
                    enumerator,
                    EnumerableMembers.MoveNext(typeof(IDiffItem))
                    )
                ));
 }
Beispiel #4
0
        private Expression <Func <IDiff <TType>, IDiff <TType>, IConflictContainer, List <IDiffItem> > > Compile()
        {
            ParameterExpression left            = Expression.Parameter(typeof(IDiff <TType>), "left");
            ParameterExpression right           = Expression.Parameter(typeof(IDiff <TType>), "right");
            ParameterExpression conflicts       = Expression.Parameter(typeof(IConflictContainer), "ret");
            ParameterExpression ret             = Expression.Parameter(typeof(List <IDiffItem>), "ret");
            ParameterExpression leftEnumerator  = Expression.Parameter(typeof(IEnumerator <IDiffItem>), "leftEnumerator");
            ParameterExpression leftSomeLeft    = Expression.Parameter(typeof(bool), "leftSomeLeft");
            ParameterExpression rightEnumerator = Expression.Parameter(typeof(IEnumerator <IDiffItem>), "rightEnumerator");
            ParameterExpression rightSomeLeft   = Expression.Parameter(typeof(bool), "rightSomeLeft");

            return(Expression.Lambda <Func <IDiff <TType>, IDiff <TType>, IConflictContainer, List <IDiffItem> > >(
                       Expression.Block(
                           new[] { ret, leftEnumerator, leftSomeLeft, rightEnumerator, rightSomeLeft },
                           Expression.Assign(
                               ret,
                               Expression.New(
                                   ListMembers.NewWithCount(typeof(IDiffItem)),
                                   Expression.Add(
                                       Expression.Property(left, DiffMembers.Count()),
                                       Expression.Property(right, DiffMembers.Count())
                                       )
                                   )
                               ),
                           Expression.Assign(
                               leftEnumerator,
                               Expression.Call(left, EnumerableMembers.GetEnumerator(typeof(IDiffItem)))
                               ),
                           Expression.Assign(
                               rightEnumerator,
                               Expression.Call(right, EnumerableMembers.GetEnumerator(typeof(IDiffItem)))
                               ),
                           this.MoveEnumerator(leftEnumerator, leftSomeLeft),
                           this.MoveEnumerator(rightEnumerator, rightSomeLeft),
                           Expression.Block(Class <TType> .Properties.Select(x => this.EvaluateProperty(leftEnumerator, leftSomeLeft, rightEnumerator, rightSomeLeft, conflicts, ret, x))),
                           ret
                           ),
                       left, right, conflicts
                       ));
        }
Beispiel #5
0
        private Expression EvaluateProperty(ParameterExpression leftEnumerator, ParameterExpression leftSomeLeft, ParameterExpression rightEnumerator, ParameterExpression rightSomeLeft, Expression conflicts, Expression ret, Property property)
        {
            Expression leftCurrent  = Expression.Property(leftEnumerator, EnumerableMembers.Current(typeof(IDiffItem)));
            Expression rightCurrent = Expression.Property(rightEnumerator, EnumerableMembers.Current(typeof(IDiffItem)));

            /* PSEUDO CODE FOR THIS:
             * if (leftSomeLeft && leftCurrent.UniqueID == ID)
             * {
             *     if (rightSomeLeft && rightCurrent.UniqueID == ID)
             *     {
             *         CheckConflicts(leftCurrent, rightCurrent)
             *         rightSomeLeft = next(rightCurrent)
             *     }
             *     else
             *         add(leftCurrent)
             *     leftSomeLeft = next(leftCurrent)
             * }
             * else if (rightSomeLeft && rightCurrent.UniqueID == ID)
             * {
             *     add(rightCurrent)
             *     rightSomeLeft = next(rightCurrent)
             * }
             */

            Expression leftShouldBeProcessed = Expression.AndAlso(
                leftSomeLeft,
                Expression.Equal(
                    Expression.Property(
                        Expression.Property(
                            Expression.Convert(
                                leftCurrent,
                                typeof(IDiffClassItem)
                                ),
                            DiffItemsMembers.ClassProperty()
                            ),
                        FastPropertyMembers.UniqueID()
                        ),
                    Expression.Constant(property.UniqueID)
                    )
                );

            Expression rightShouldBeProcessed = Expression.AndAlso(
                rightSomeLeft,
                Expression.Equal(
                    Expression.Property(
                        Expression.Property(
                            Expression.Convert(
                                rightCurrent,
                                typeof(IDiffClassItem)
                                ),
                            DiffItemsMembers.ClassProperty()
                            ),
                        FastPropertyMembers.UniqueID()
                        ),
                    Expression.Constant(property.UniqueID)
                    )
                );

            return(Expression.IfThenElse(
                       leftShouldBeProcessed,
                       Expression.Block(
                           Expression.IfThenElse(
                               rightShouldBeProcessed,
                               Expression.Block(
                                   this.CompileCheckConflicts(property, leftCurrent, rightCurrent, conflicts, ret),
                                   this.MoveEnumerator(rightEnumerator, rightSomeLeft)
                                   ),
                               Expression.Call(
                                   ret,
                                   ListMembers.Add(typeof(IDiffItem)),
                                   leftCurrent
                                   )
                               ),
                           this.MoveEnumerator(leftEnumerator, leftSomeLeft)
                           ),
                       Expression.IfThen(
                           rightShouldBeProcessed,
                           Expression.Block(
                               Expression.Call(
                                   ret,
                                   ListMembers.Add(typeof(IDiffItem)),
                                   rightCurrent
                                   ),
                               this.MoveEnumerator(rightEnumerator, rightSomeLeft)
                               )
                           )
                       ));
        }
Beispiel #6
0
 public static IEnumerable <TA> Flatten <TA>(this IEnumerable <Option <TA> > @as)
 {
     return(EnumerableMembers.Flatten(@as));
 }
 public static IEnumerable <TA> PrependRange <TA>(this IEnumerable <TA> @as, IEnumerable <TA> range)
 {
     return(EnumerableMembers.PrependRange(range)(@as));
 }
 public static IEnumerable <TA> Prepend <TA>(this IEnumerable <TA> @as, Option <TA> a)
 {
     return(EnumerableMembers.Prepend(a)(@as));
 }
 public static IEnumerable <TB> FlatMap <TA, TB>(this IEnumerable <TA> @as, Func <TA, IEnumerable <TB> > f)
 {
     return(EnumerableMembers.FlatMap(f)(@as));
 }
Beispiel #10
0
 public static Func <TValue, IEnumerable <KeyValuePair <TKey, TValue> > > Append <TKey, TValue>(this IEnumerable <KeyValuePair <TKey, TValue> > kvps, TKey key)
 {
     return(Functions.RotateRight2(EnumerableMembers.Append <TKey, TValue>(key))(kvps));
 }
Beispiel #11
0
 public static IEnumerable <KeyValuePair <TKey, TValue> > Prepend <TKey, TValue>(this IEnumerable <KeyValuePair <TKey, TValue> > kvps, TKey key, TValue value)
 {
     return(EnumerableMembers.Prepend(key, value)(kvps));
 }