Пример #1
0
        private Expression <Func <TType, TType, List <IDiffItem> > > Compile()
        {
            List <Expression>   body    = new List <Expression>();
            ParameterExpression ret     = Expression.Parameter(typeof(List <IDiffItem>), "ret");
            ParameterExpression @base   = Expression.Parameter(typeof(TType), "base");
            ParameterExpression changed = Expression.Parameter(typeof(TType), "changed");

            body.Add(
                Expression.Assign(
                    ret,
                    Expression.New(
                        ListMembers.NewWithCount(typeof(IDiffItem)),
                        Expression.Constant(Class <TType> .Properties.Count)                       // maximum number of different items
                        )
                    )
                );

            foreach (Property property in Class <TType> .Properties)
            {
                if (this.aIgnoreProperties.Contains(property))
                {
                    continue;
                }

                IDiffAlgorithm diff = this.aMergerImplementation.Partial.Algorithms.GetDiffAlgorithm(property.Type);

                if (diff.IsDirect)
                {
                    body.Add(this.MightBeReplaced(ret, property, @base, changed));
                }
                else
                {
                    body.Add(this.MightBeChanged(ret, property, @base, changed));
                }
            }

            body.Add(ret);

            return(Expression.Lambda <Func <TType, TType, List <IDiffItem> > >(
                       Expression.Block(new[] { ret }, body),
                       @base, changed
                       ));
        }
Пример #2
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
                       ));
        }
Пример #3
0
        private Func <TType, TType, List <IDiffItem> > CompileDiff()
        {
            ParameterExpression ret = Expression.Parameter(typeof(List <IDiffItem>), "ret");

            ParameterExpression @base   = Expression.Parameter(typeof(TType), "base");
            ParameterExpression changed = Expression.Parameter(typeof(TType), "changed");

            Expression differ;

            if (this.aIDProperty == null)
            {
                differ = Expression.IfThen(
                    ExpressionExtensions.NotEqual(@base, changed),
                    Expression.Call(
                        ret,
                        ListMembers.Add(typeof(IDiffItem)),
                        Expression.New(
                            DiffItemsMembers.NewValueReplaced(typeof(TType)),
                            @base,
                            changed
                            )
                        )
                    );
            }
            else
            {
                differ = Expression.IfThen(
                    ExpressionExtensions.NotEqual(
                        Expression.Property(@base, this.aIDProperty.ReflectionPropertyInfo),
                        Expression.Property(changed, this.aIDProperty.ReflectionPropertyInfo)
                        ),
                    Expression.Call(
                        ret,
                        ListMembers.Add(typeof(IDiffItem)),
                        Expression.New(
                            DiffItemsMembers.NewValueReplaced(typeof(TType)),
                            @base,
                            changed
                            )
                        )
                    );
            }

            if (!typeof(TType).IsValueType)
            {
                differ = Expression.IfThenElse(
                    Expression.OrElse(
                        Expression.ReferenceEqual(@base, Expression.Constant(null)),
                        Expression.ReferenceEqual(changed, Expression.Constant(null))
                        ),
                    Expression.IfThen(
                        Expression.ReferenceEqual(@base, changed),
                        Expression.New(
                            DiffItemsMembers.NewValueReplaced(typeof(TType)),
                            @base,
                            changed
                            )
                        ),
                    differ
                    );
            }

            Expression <Func <TType, TType, List <IDiffItem> > > comparer = Expression.Lambda <Func <TType, TType, List <IDiffItem> > >(
                Expression.Block(
                    new[] { ret },
                    Expression.Assign(
                        ret,
                        Expression.New(
                            ListMembers.NewWithCount(typeof(IDiffItem)),
                            Expression.Constant(1)                             // maximum number of changes
                            )
                        ),
                    differ,
                    ret
                    ),
                @base,
                changed
                );

            return(comparer.Compile());
        }