private Expression MakeSelect(CurrentDependencies current, LambdaExpression selector) { var subExtractor = new DependenciesExtractor(selector, parameters.Concat(selector.Parameters)); LambdaExpression[] primarySubDependencies; LambdaExpression[] additionalSubDependencies; subExtractor.Extract(out primarySubDependencies, out additionalSubDependencies); var prefixCurrent = MakeLambda(GotoCurrent(current.Prefix)); current.AddSubDependencies(prefixCurrent, additionalSubDependencies); if (primarySubDependencies.Length > 1) { return(Expression.NewArrayInit(typeof(object), primarySubDependencies.Select(exp => Expression.Convert(prefixCurrent.Merge(exp).Body, typeof(object))))); } var primarySubDependency = primarySubDependencies.SingleOrDefault(); if (primarySubDependency == null) { return(Expression.NewArrayInit(typeof(object))); } if (!selector.ReturnType.IsAssignableFrom(primarySubDependency.ReturnType)) { return(null); } if (!(primarySubDependency.Body is NewExpression)) { return(new AnonymousTypeEliminator().Eliminate(prefixCurrent.Merge(primarySubDependency)).Body); } var newExpression = (NewExpression)primarySubDependency.Body; return(Expression.New(newExpression.Constructor, newExpression.Arguments.Select(arg => prefixCurrent.Merge(Expression.Lambda(arg, primarySubDependency.Parameters)).Body))); }
private void ProcessLinqSelectMany(MethodInfo method, CurrentDependencies current, Expression[] arguments) { var collectionSelector = (LambdaExpression)arguments[0]; var collection = MakeSelect(current, collectionSelector); if (collection == null) { current.Prefix = null; return; } if (arguments.Length == 1) { current.Prefix = collection; return; } var resultSelector = (LambdaExpression)arguments[1]; var subExtractor = new DependenciesExtractor(resultSelector, parameters.Concat(resultSelector.Parameters)); LambdaExpression[] primarySubDependencies; LambdaExpression[] additionalSubDependencies; subExtractor.Extract(out primarySubDependencies, out additionalSubDependencies); var prefixCurrent = MakeLambda(GotoCurrent(current.Prefix)); var collectionCurrent = MakeLambda(GotoCurrent(collection)); current.AddSubDependencies(prefixCurrent, collectionCurrent, additionalSubDependencies); var primarySubDependency = primarySubDependencies.Single(); if (!(primarySubDependency.Body is NewExpression)) { current.Prefix = new AnonymousTypeEliminator().Eliminate(new ExpressionMerger(prefixCurrent, collectionCurrent).Merge(primarySubDependency)).Body; } else { var newExpression = (NewExpression)primarySubDependency.Body; current.Prefix = Expression.New(newExpression.Constructor, newExpression.Arguments.Select(arg => new ExpressionMerger(prefixCurrent, collectionCurrent).Merge(Expression.Lambda(arg, primarySubDependency.Parameters)).Body)); } }