Exemplo n.º 1
0
        private void DoTest <T1, T2>(Expression <Func <T1, T2> > exp, T1 data, string expected)
        {
            ParameterExpression[] currentIndexes;
            var body     = new LinqEliminator().Eliminate(exp.Body, out currentIndexes);
            var paths    = ExpressionPathsBuilder.BuildPaths(exp.Body, currentIndexes);
            var resolved = Expression.Block(currentIndexes, new[]
            {
                body,
                paths
            });

            ParameterExpression[] parameters           = resolved.ExtractParameters();
            Expression <Func <T1, string[][]> > lambda = Expression.Lambda <Func <T1, string[][]> >(resolved, parameters);

            Assert.AreEqual(expected, string.Join(".", LambdaCompiler.Compile(lambda, CompilerOptions.All) /*.Compile()*/ (data)[0]));
        }
            public void BuildValidator(IPathFormatter pathFormatter, ModelConfigurationNode root, List <KeyValuePair <Expression, Expression> > aliases, Dictionary <ParameterExpression, ExpressionPathsBuilder.SinglePaths> paths, ParameterExpression result, Type treeRootType, ParameterExpression priority, List <Expression> validationResults)
            {
                foreach (var pair in mutators)
                {
                    BuildNodeValidator(pathFormatter, pair.Key, pair.Value, root, aliases, paths, result, treeRootType, priority, validationResults);
                }
                foreach (var pair in children)
                {
                    var edge  = pair.Key.Expression;
                    var child = pair.Value;

                    var array = ((MethodCallExpression)edge).Arguments[0];
                    LambdaExpression predicate = null;
                    var resolvedArray          = array.ResolveAliases(aliases);
                    var itemType = resolvedArray.Type.GetItemType();
                    var item     = Expression.Call(null, MutatorsHelperFunctions.EachMethod.MakeGenericMethod(itemType), array);
                    var index    = Expression.Call(null, MutatorsHelperFunctions.CurrentIndexMethod.MakeGenericMethod(itemType), item);
                    if (!resolvedArray.Type.IsArray)
                    {
                        // Filtered array
                        if (resolvedArray.NodeType == ExpressionType.Call)
                        {
                            var methodCallExpression = (MethodCallExpression)resolvedArray;
                            if (methodCallExpression.Method.IsWhereMethod())
                            {
                                resolvedArray = methodCallExpression.Arguments[0];
                                predicate     = (LambdaExpression)methodCallExpression.Arguments[1];
                            }
                        }
                    }

                    ParameterExpression[] indexes = null;
                    var parameter             = Expression.Parameter(itemType);
                    var adjustedResolvedArray = Expression.Call(selectMethod.MakeGenericMethod(itemType, itemType), resolvedArray, Expression.Lambda(parameter, parameter));
                    adjustedResolvedArray = Expression.Call(MutatorsHelperFunctions.EachMethod.MakeGenericMethod(itemType), adjustedResolvedArray);

                    var monster = new LinqEliminator().EliminateAndEnumerate(adjustedResolvedArray, (current, currentIndex, currentIndexes) =>
                    {
                        indexes = currentIndexes;
                        aliases.Add(new KeyValuePair <Expression, Expression>(current, item));
                        aliases.Add(new KeyValuePair <Expression, Expression>(currentIndex, index));
                        var currentPaths = ExpressionPathsBuilder.BuildPaths(adjustedResolvedArray, currentIndexes, paths);
                        //currentPaths.Add(currentIndex);
                        paths.Add(current, currentPaths);

                        var childValidationResults = new List <Expression>();
                        child.BuildValidator(pathFormatter, root, aliases, paths, result, treeRootType, priority, childValidationResults);
                        aliases.RemoveAt(aliases.Count - 1);
                        aliases.RemoveAt(aliases.Count - 1);

                        paths.Remove(current);

                        if (predicate != null)
                        {
                            var condition = Expression.Lambda(current, current).Merge(predicate).Body;
                            for (var i = 0; i < childValidationResults.Count; ++i)
                            {
                                childValidationResults[i] = Expression.IfThen(
                                    Expression.Equal(
                                        Expression.Convert(condition, typeof(bool?)),
                                        Expression.Constant(true, typeof(bool?))),
                                    childValidationResults[i]);
                            }
                        }

                        for (var i = 0; i < childValidationResults.Count; ++i)
                        {
                            childValidationResults[i] = childValidationResults[i].ExtractLoopInvariantFatExpressions(aliases.Where(p => p.Key is ParameterExpression).Select(p => (ParameterExpression)p.Key), e => e);
                        }

                        return(Expression.Block(childValidationResults.SplitToBatches()));
                    });

                    if (indexes != null && indexes.Length > 0)
                    {
                        monster = Expression.Block(indexes, monster);
                    }
                    validationResults.Add(monster);
                }
            }