public Expression GetGetterExpression(ParameterExpression parameterExpr)
        {
            // TODO does this keep swapping the same parameter?
            var replacer = new ParameterReplacerVisitor(_getterExpr.Parameters[0], parameterExpr);

            return(replacer.Visit(_getterExpr.Body));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Remaps an expression on a type to another type that have the original type as a property.
        /// </summary>
        /// <typeparam name="TTarget"></typeparam>
        /// <typeparam name="TSource"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="source"></param>
        /// <param name="selector"></param>
        /// <returns></returns>
        public static Expression <Func <TTarget, TResult> > RemapTo <TTarget, TSource, TResult>(this Expression <Func <TSource, TResult> > source, Expression <Func <TTarget, TSource> > selector)
        {
            var map = new Dictionary <ParameterExpression, Expression>
            {
                [source.Parameters.Single()] = selector.Body
            };
            var resultBody = new ParameterReplacerVisitor(map).Visit(source.Body);

            return(Expression.Lambda <Func <TTarget, TResult> >(resultBody, selector.Parameters));
        }
Ejemplo n.º 3
0
        /// <summary>Replaced the type of input parameter with the given <paramref name="targetType"/></summary>
        /// <param name="input">Input lambda expression.</param>
        /// <param name="targetType">Type of the new parameter that will be replaced.</param>
        /// <returns>New lambda expression with parameter of new type.</returns>
        private static LambdaExpression ReplaceParameterTypeForLambda(LambdaExpression input, Type targetType)
        {
            Debug.Assert(input.Parameters.Count == 1, "Assuming a single parameter for input lambda expression in this function.");

            ParameterExpression p = Expression.Parameter(targetType, input.Parameters[0].Name);

            return(Expression.Lambda(
                       ParameterReplacerVisitor.Replace(input.Body, input.Parameters[0], p),
                       p));
        }
Ejemplo n.º 4
0
        public static Expression <TFunc> Merge <TFunc>(
            this Expression <TFunc> left,
            Expression <TFunc> right,
            Func <Expression, Expression, Expression> merge)
        {
            var parametersMap = left.Parameters
                                .Select((param, index) => new { r = right.Parameters[index], l = param })
                                .ToDictionary(x => x.r, x => x.l);

            var rightBody = new ParameterReplacerVisitor(parametersMap).Visit(right.Body);

            return(Expression.Lambda <TFunc>(merge(left.Body, rightBody), left.Parameters));
        }
Ejemplo n.º 5
0
    public static Expression <Func <T, bool> > And <T>(this Expression <Func <T, bool> > left, Expression <Func <T, bool> > right)
    {
        var p1 = left.Parameters.First();
        var p2 = right.Parameters.First();

        if (p1.Name != p2.Name)
        {
            var replacer = new ParameterReplacerVisitor <Func <T, bool> >(p1);
            right = replacer.VisitAndConvert(right);
        }
        var newBody = Expression.AndAlso(left.Body, right.Body);

        return(Expression.Lambda <Func <T, bool> >(newBody, left.Parameters));
    }
Ejemplo n.º 6
0
        private static Expression <T> Combine <T>(this Expression <T> first, Expression <T> second, Func <Expression, Expression, BinaryExpression> operatorFunc)
        {
            if (first == null || second == null)
            {
                return(first ?? second);
            }

            var map = second.Parameters
                      .Zip(first.Parameters, (key, value) => new { key, value })
                      .ToDictionary(x => x.key, x => (Expression)x.value);
            var secondBody = new ParameterReplacerVisitor(map).Visit(second.Body);

            return(Expression.Lambda <T>(operatorFunc(first.Body, secondBody), first.Parameters));
        }
Ejemplo n.º 7
0
        /// <summary>Composes all query interceptors into a single expression.</summary>
        /// <param name="serviceInstance">Web service instance.</param>
        /// <param name="container">Container for which interceptors should run.</param>
        /// <returns>An expression the filter for query interceptors, possibly null.</returns>
        internal static Expression ComposeQueryInterceptors(object serviceInstance, ResourceSetWrapper container)
        {
            Debug.Assert(container != null, "container != null");
            MethodInfo[] methods = container.QueryInterceptors;
            if (methods == null || methods.Length == 0)
            {
                return(null);
            }

            LambdaExpression filter = null;

            for (int i = 0; i < methods.Length; i++)
            {
                Expression predicate;
                try
                {
                    predicate = (Expression)methods[i].Invoke(serviceInstance, WebUtil.EmptyObjectArray);
                }
                catch (TargetInvocationException tie)
                {
                    ErrorHandler.HandleTargetInvocationException(tie);
                    throw;
                }

                if (predicate == null)
                {
                    throw new InvalidOperationException(Strings.DataService_AuthorizationReturnedNullQuery(methods[i].Name, methods[i].DeclaringType.FullName));
                }

                // predicate is LambdaExpression -- otherwise signature check missed something and following cast would throw
                LambdaExpression lambdaPredicate = ((LambdaExpression)predicate);

                if (filter == null)
                {
                    filter = lambdaPredicate;
                }
                else
                {
                    ParameterExpression parameter         = filter.Parameters[0];
                    Expression          adjustedPredicate = ParameterReplacerVisitor.Replace(
                        lambdaPredicate.Body,             // expression
                        lambdaPredicate.Parameters[0],    // oldParameter
                        parameter);                       // newParameter
                    filter = Expression.Lambda(Expression.And(filter.Body, adjustedPredicate), parameter);
                }
            }

            return(filter);
        }
        public bool TryParse(PrioritizedString expr, ParameterInfo paramInfo, out Expression parsed)
        {
            var minPriorityInds = expr.Priorities.GetMinIndexes();
            var whereParts      = expr.SplitOnSubset("where", minPriorityInds);

            if (whereParts.Length > 2)
            {
                throw new ParseException("Too many 'where'!");
            }

            if (whereParts.Length == 1)
            {
                parsed = null;
                return(false);
            }

            var mainFunc = whereParts[0];

            if (mainFunc.Input.Last() == ',')
            {
                mainFunc = mainFunc.Substring(0, mainFunc.Input.Length - 1);
            }

            var parameterExpressions = new Dictionary <string, PrioritizedString>();

            foreach (Match match in ParameterRe.Matches(whereParts[1].Input))
            {
                var(paramName, paramExpr) = (match.Groups["paramName"].Value, match.Groups["paramExpr"].Value);
                if (paramInfo.Parameters.ContainsKey(paramName))
                {
                    throw new ParseException($"Parameter {paramName} is defined multiple times");
                }

                paramInfo.Parameters[paramName] = Expression.Parameter(typeof(double), paramName);
                parameterExpressions[paramName] = new PrioritizedString(paramExpr);
            }
            var parameterExprs = parameterExpressions
                                 .ToDictionary(
                nameWithExpr => nameWithExpr.Key,
                nameWithExpr => Combinator.ParseFunctionalExpression(nameWithExpr.Value, paramInfo)
                );
            var mainExpr = Combinator.ParseFunctionalExpression(mainFunc, paramInfo);

            var paramReplacer = new ParameterReplacerVisitor(parameterExprs);

            parsed = paramReplacer.Visit(mainExpr);
            return(true);
        }
Ejemplo n.º 9
0
        IQueryable <T> IQuery <T> .Execute(Expression <Func <T, bool> > predicate)
        {
            var modifiedPredicate = predicate;

            var filterExpression = _context.GetContextFilterExpression <T>();

            if (filterExpression != null)
            {
                var typeParam = predicate.Parameters[0];
                var filter    = new ParameterReplacerVisitor(typeParam).Visit(filterExpression.Body);

                modifiedPredicate = Expression.Lambda <Func <T, bool> >(Expression.AndAlso(predicate.Body, filter), typeParam);
            }

            return(((IQuery <T>)_crud).Execute(modifiedPredicate));
        }
Ejemplo n.º 10
0
        public static Expression <Func <T, TResult> > Chain <T, TIntermediate, TResult>(this Expression <Func <T, TIntermediate> > expression, Expression <Func <TIntermediate, TResult> > otherExpression)
        {
            if (expression == null)
            {
                throw new ArgumentNullException(nameof(expression));
            }

            if (otherExpression == null)
            {
                throw new ArgumentNullException(nameof(otherExpression));
            }

            var paramReplacer = new ParameterReplacerVisitor(expression);

            return((Expression <Func <T, TResult> >)paramReplacer.Visit(otherExpression));
        }
Ejemplo n.º 11
0
        public EquatableExpression(LambdaExpression expression)
        {
            if (expression == null)
            {
                throw new ArgumentNullException("expression");
            }
            if (expression.Parameters.Count != 1)
            {
                throw new ArgumentException("Invalid LambdaExpression. Must only have one parameter.");
            }
            _expression    = expression;
            _parameterType = _expression.Parameters[0].Type;
            var visitor = new ParameterReplacerVisitor();

            _expressionAsString = visitor.Visit(expression).ToString();
        }
Ejemplo n.º 12
0
        public void ParametersReplacer_Test()
        {
            var args = new Dictionary <string, ConstantExpression>
            {
                ["a"] = Expression.Constant(4),
                ["b"] = Expression.Constant(1),
            };
            Expression <Func <int, int, int, int> > source_exp = (a, b, c) => c + (a - 1) * b + (a + 1) * (a + 5) * (a + 1);
            var result_exp = new ParameterReplacerVisitor(args).VisitAndConvert(source_exp, "");

            Console.WriteLine(source_exp + " " + source_exp.Compile().Invoke(3, 3, 2));
            Console.WriteLine(result_exp + " " + result_exp.Compile().Invoke(3, 3, 2));
            Console.WriteLine("Source Expression:");
            new TraceExpressionVisitor().Visit(source_exp);
            Console.WriteLine("Result Expression:");
            new TraceExpressionVisitor().Visit(result_exp);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Composes a property navigation with the appropriate filter lamba, as appropriate.
        /// </summary>
        /// <param name="expression">Member access expression to compose.</param>
        /// <param name="filterLambda">Lambda expression used for the filter.</param>
        /// <param name="propagateNull">Whether null propagation is required on the <paramref name="expression"/>.</param>
        /// <param name="isSingleResult">Whether <paramref name="expression"/> represent a single resource navigation.</param>
        /// <returns>The composed expression.</returns>
        internal static Expression ComposePropertyNavigation(
            Expression expression,
            LambdaExpression filterLambda,
            bool propagateNull,
            bool isSingleResult)
        {
            Debug.Assert(expression != null, "expression != null");
            Debug.Assert(filterLambda != null, "filterLambda != null");

            Expression nullConstant = NullLiteral;

            if (isSingleResult)
            {
                Expression fixedFilter = ParameterReplacerVisitor.Replace(
                    filterLambda.Body,
                    filterLambda.Parameters[0],
                    expression);

                Expression test = propagateNull
                                      ? Expression.AndAlso(Expression.NotEqual(expression, nullConstant), fixedFilter)
                                      : fixedFilter;

                Expression conditionTrue  = expression;
                Expression conditionFalse = Expression.Constant(null, conditionTrue.Type);
                return(Expression.Condition(test, conditionTrue, conditionFalse));
            }

            Type       elementType      = filterLambda.Parameters[0].Type;
            Expression filterExpression = expression.EnumerableWhere(filterLambda);

            if (propagateNull)
            {
                Expression test    = Expression.Equal(expression, nullConstant);
                Expression falseIf = filterExpression;
                Expression trueIf  = EnumerableEmpty(elementType);
                return(Expression.Condition(test, trueIf, falseIf, trueIf.Type));
            }

            return(filterExpression);
        }
Ejemplo n.º 14
0
        /// <summary>Makes the expression that is used as a filter corresponding to skip token.</summary>
        /// <param name="topLevelOrderingInfo">Ordering expression.</param>
        /// <param name="skipToken">The provided skip token.</param>
        /// <param name="parameterType">The parameter type of the lambda.</param>
        /// <returns>LambdaExpression corresponding to the skip token filter.</returns>
        internal LambdaExpression BuildSkipTokenFilter(OrderingInfo topLevelOrderingInfo, IList <object> skipToken, Type parameterType)
        {
            ParameterExpression element       = Expression.Parameter(parameterType, "element");
            Expression          lastCondition = Expression.Constant(true, typeof(bool));
            Expression          lastMatch     = Expression.Constant(false, typeof(bool));

            foreach (var v in WebUtil.Zip(topLevelOrderingInfo.OrderingExpressions, skipToken, (x, y) => new { Order = x, Value = y }))
            {
                BinaryOperatorKind comparisonExp = v.Order.IsAscending ? BinaryOperatorKind.GreaterThan : BinaryOperatorKind.LessThan;

                Expression fixedLambda = ParameterReplacerVisitor.Replace(
                    ((LambdaExpression)v.Order.Expression).Body,
                    ((LambdaExpression)v.Order.Expression).Parameters[0],
                    element);

                // TODO: this will be an EnumNode if $skiptoken contains enum constant.
                ConstantNode node;
                var          lexer   = new ExpressionLexer((string)v.Value);
                bool         success = TokenToQueryNodeTranslator.TryCreateLiteral(lexer.CurrentToken, out node);
                Debug.Assert(success, "Was not a literal");

                node = this.EnsureCorrectTypeAndPrecisionForLFDM(node, fixedLambda.Type);
                Expression right      = this.nodeToExpressionTranslator.TranslateNode(node);
                Expression comparison = ExpressionGenerator.GenerateLogicalAnd(
                    lastCondition,
                    this.GenerateNullAwareComparison(fixedLambda, right, comparisonExp));

                lastMatch = ExpressionGenerator.GenerateLogicalOr(lastMatch, comparison);

                lastCondition = ExpressionGenerator.GenerateLogicalAnd(
                    lastCondition,
                    this.GenerateComparisonExpression(fixedLambda, right, BinaryOperatorKind.Equal));
            }

            lastMatch = ExpressionUtils.EnsurePredicateExpressionIsBoolean(lastMatch);

            Debug.Assert(lastMatch.Type == typeof(bool), "Skip token should generate boolean expression.");

            return(Expression.Lambda(lastMatch, element));
        }
Ejemplo n.º 15
0
        internal static Expression <Func <TItem, bool> > CombinePredicates <TItem>(IEnumerable <Expression <Func <TItem, bool> > > predicates)
        {
            ParameterExpression paramExpr         = null;
            Expression          combinedPredicate = null;

            foreach (Expression <Func <TItem, bool> > predicate in predicates)
            {
                if (predicate == null)
                {
                    continue;
                }

                Expression predicateBody;

                if (paramExpr == null)
                {
                    paramExpr     = predicate.Parameters[0];
                    predicateBody = predicate.Body;
                }
                else
                {
                    var visitor = new ParameterReplacerVisitor(predicate.Parameters[0], paramExpr);
                    predicateBody = visitor.Visit(predicate.Body);
                }

                combinedPredicate = combinedPredicate == null ? predicateBody : Expression.OrElse(combinedPredicate, predicateBody);
            }

            if (combinedPredicate == null)
            {
                return(item => false);
            }

            var combinedLambda = Expression.Lambda <Func <TItem, bool> >(combinedPredicate, paramExpr);

            return(combinedLambda);
        }
Ejemplo n.º 16
0
 private PredicateBuilder(bool value)
 {
     _param         = Expression.Parameter(typeof(T));
     _paramReplacer = new ParameterReplacerVisitor(_param);
     _body          = Expression.Constant(value);
 }
        public Expression GetSelectExpression(ParameterExpression itemPram)
        {
            var replacer = new ParameterReplacerVisitor(_middleExpression.Parameters[0], itemPram);

            return(replacer.Visit(_middleExpression.Body));
        }
        protected override Expression GetGetterExpression(ParameterExpression parameterExpr)
        {
            var replacer = new ParameterReplacerVisitor(_getterExpression.Parameters[0], parameterExpr);

            return(replacer.Visit(_getterExpression.Body));
        }