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) ) ) )); }
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 ) )); }