예제 #1
0
        public static void UpdateDifferentReturnsDifferent()
        {
            Expression         bound0             = Expression.Constant(2);
            Expression         bound1             = Expression.Constant(3);
            NewArrayExpression newArrayExpression = Expression.NewArrayBounds(typeof(string), bound0, bound1);

            Assert.NotSame(newArrayExpression, newArrayExpression.Update(new[] { bound0 }));
            Assert.NotSame(newArrayExpression, newArrayExpression.Update(new[] { bound0, bound1, bound0, bound1 }));
            Assert.NotSame(newArrayExpression, newArrayExpression.Update(newArrayExpression.Expressions.Reverse()));
        }
예제 #2
0
        public static Expression Replace(ParameterExpression parameter,
                                         Expression expr, IDictionary <string, int> variables)
        {
            if (expr == null)
            {
                return(null);
            }

            BinaryExpression     eb = expr as BinaryExpression;
            MemberExpression     em = expr as MemberExpression;
            UnaryExpression      eu = expr as UnaryExpression;
            MethodCallExpression ec = expr as MethodCallExpression;
            NewArrayExpression   ea = expr as NewArrayExpression;

            if (em != null) // member expression
            {
                string             varName         = em.Member.Name;
                int                index           = variables[varName];
                ConstantExpression indexExpression = Expression.Constant(index);
                return(Expression.ArrayAccess(parameter, indexExpression));
            }
            else if (eb != null) // binary expression
            {
                var left  = Replace(parameter, eb.Left, variables);
                var right = Replace(parameter, eb.Right, variables);
                return(eb.Update(left, eb.Conversion, right));
            }
            else if (eu != null) // unary expression
            {
                var op = Replace(parameter, eu.Operand, variables);
                return(eu.Update(op));
            }
            else if (ec != null) // call expression
            {
                List <Expression> args = new List <Expression>();

                foreach (var a in ec.Arguments)
                {
                    args.Add(Replace(parameter, a, variables));
                }

                return(ec.Update(ec.Object, args));
            }
            else if (ea != null) // new array expression
            {
                List <Expression> values = new List <Expression>();

                foreach (var v in ea.Expressions)
                {
                    values.Add(Replace(parameter, v, variables));
                }

                return(ea.Update(values));
            }
            else
            {
                return(expr);
            }
        }
예제 #3
0
        public static void UpdateNullThrows()
        {
            Expression         bound0             = Expression.Constant(2);
            Expression         bound1             = Expression.Constant(3);
            NewArrayExpression newArrayExpression = Expression.NewArrayBounds(typeof(string), bound0, bound1);

            AssertExtensions.Throws <ArgumentNullException>("expressions", () => newArrayExpression.Update(null));
        }
예제 #4
0
        public static void UpdateDoesntRepeatEnumeration()
        {
            Expression         bound0             = Expression.Constant(2);
            Expression         bound1             = Expression.Constant(3);
            NewArrayExpression newArrayExpression = Expression.NewArrayBounds(typeof(string), bound0, bound1);

            Assert.NotSame(newArrayExpression, newArrayExpression.Update(new RunOnceEnumerable <Expression>(new[] { bound0 })));
        }
예제 #5
0
        public static void UpdateSameReturnsSame()
        {
            Expression         bound0             = Expression.Constant(2);
            Expression         bound1             = Expression.Constant(3);
            NewArrayExpression newArrayExpression = Expression.NewArrayBounds(typeof(string), bound0, bound1);

            Assert.Same(newArrayExpression, newArrayExpression.Update(new [] { bound0, bound1 }));
        }
예제 #6
0
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        protected override Expression VisitNewArray(NewArrayExpression newArrayExpression)
        {
            var expressions = new Expression[newArrayExpression.Expressions.Count];

            for (var i = 0; i < expressions.Length; i++)
            {
                expressions[i] = MatchExpressionType(
                    Visit(newArrayExpression.Expressions[i]),
                    newArrayExpression.Expressions[i].Type);
            }

            return(newArrayExpression.Update(expressions));
        }
예제 #7
0
        protected override Expression VisitNewArray(NewArrayExpression node)
        {
            var changed   = false;
            var arguments = new Expression[node.Expressions.Count];
            var i         = 0;

            foreach (var arg in node.Expressions)
            {
                var argument = Visit(arg);
                arguments[i] = argument;
                changed     |= argument != arg;
            }
            if (changed)
            {
                return(node.Update(arguments));
            }
            return(node);
        }
예제 #8
0
        protected override Expression VisitNewArray(NewArrayExpression node)
        {
            var visitedExpressions = Visit(node.Expressions);

            if (visitedExpressions.All(e => e is ConstantExpression))
            {
                switch (node.NodeType)
                {
                case ExpressionType.NewArrayBounds:
                {
                    return(Expression.Constant(
                               Array.CreateInstance(
                                   node.Type.GetElementType(),
                                   visitedExpressions
                                   .Cast <ConstantExpression>()
                                   .Select(c => c.Value)
                                   .Cast <int>()
                                   .ToArray())));
                }

                case ExpressionType.NewArrayInit:
                {
                    var array = Array.CreateInstance(
                        node.Type.GetElementType(),
                        visitedExpressions.Count);

                    var values = visitedExpressions
                                 .Cast <ConstantExpression>()
                                 .Select((c, i) => (c.Value, i));

                    foreach (var(value, index) in values)
                    {
                        array.SetValue(value, index);
                    }

                    return(Expression.Constant(array));
                }
                }
            }

            return(node.Update(visitedExpressions));
        }
        public T?Simplify <T>(T?expression) where T : Expression
        {
            if (expression is null)
            {
                return(null);
            }
            Expression expr = expression.Reduce() switch
            {
                UnaryExpression unaryExpr => unaryExpr.Update(Simplify(unaryExpr.Operand)),
                BinaryExpression binaryExpr => binaryExpr.Update(Simplify(binaryExpr.Left), binaryExpr.Conversion, Simplify(binaryExpr.Right)),
                LambdaExpression lambdaExpr => Expression.Lambda(Simplify(lambdaExpr.Body), lambdaExpr.Name, lambdaExpr.TailCall, Simplify(lambdaExpr.Parameters)),
                TryExpression tryExpr => tryExpr.Update(Simplify(tryExpr.Body), Simplify(tryExpr.Handlers), Simplify(tryExpr.Finally), Simplify(tryExpr.Fault)),
                NewExpression newExpr => newExpr.Update(Simplify(newExpr.Arguments)),
                GotoExpression gotoExpr => gotoExpr.Update(gotoExpr.Target, Simplify(gotoExpr.Value)),
                LoopExpression loopExpr => loopExpr.Update(loopExpr.BreakLabel, loopExpr.ContinueLabel, Simplify(loopExpr.Body)),
                BlockExpression blockExpr => blockExpr.Update(Simplify(blockExpr.Variables), Simplify(blockExpr.Expressions)),
                IndexExpression indexExpr => indexExpr.Update(Simplify(indexExpr.Object) !, Simplify(indexExpr.Arguments)),
                LabelExpression labelExpr => labelExpr.Update(labelExpr.Target, Simplify(labelExpr.DefaultValue)),
                MemberExpression memberExpr => memberExpr.Update(Simplify(memberExpr.Expression)),
                SwitchExpression switchExpr => switchExpr.Update(Simplify(switchExpr.SwitchValue), Simplify(switchExpr.Cases), Simplify(switchExpr.DefaultBody)),
                DynamicExpression dynamicExpr => dynamicExpr.Update(Simplify(dynamicExpr.Arguments)),
                ListInitExpression listInitExpr => listInitExpr.Update(Simplify(listInitExpr.NewExpression), Simplify(listInitExpr.Initializers)),
                NewArrayExpression newArrayExpr => newArrayExpr.Update(Simplify(newArrayExpr.Expressions)),
                InvocationExpression invokeExpr => invokeExpr.Update(Simplify(invokeExpr.Expression), Simplify(invokeExpr.Arguments)),
                MemberInitExpression memberInitExpr => memberInitExpr.Update(Simplify(memberInitExpr.NewExpression), memberInitExpr.Bindings),
                MethodCallExpression methodCallExpr => methodCallExpr.Update(Simplify(methodCallExpr.Object), Simplify(methodCallExpr.Arguments)),
                TypeBinaryExpression typeBinaryExpr => typeBinaryExpr.Update(Simplify(typeBinaryExpr.Expression)),
                ConditionalExpression condExpr => condExpr.Update(Simplify(condExpr.Test), Simplify(condExpr.IfTrue), Simplify(condExpr.IfFalse)),
                RuntimeVariablesExpression runtimeVarExpr => runtimeVarExpr.Update(Simplify(runtimeVarExpr.Variables)),
                _ => expression
            };

            foreach (var transform in transformers)
            {
                expr = transform.Transform(expr, this);
            }

            return((T)expr);
        }
            protected override Expression VisitNewArray(NewArrayExpression node)
            {
                var e = Visit(node.Expressions);

                var args = (IList <Expression>)e;

                var n = node.Expressions.Count;


                if (Pop(n, out var ess) && _parent.CanEvaluate(node.Type))
                {
                    _tilingState.Push(true);
                }
                else
                {
                    _tilingState.Push(false);

                    EvaluateIf(ess, ref args);
                }

                return(node.Update(args));
            }
예제 #11
0
        /// <summary>
        /// 访问 <see cref="NewArrayExpression"/>。
        /// </summary>
        /// <param name="newArrayExp">要访问的表达式。</param>
        /// <returns></returns>
        protected virtual Expression VisitNewArray(NewArrayExpression newArrayExp)
        {
            var exprs = VisitMemberAndExpressionList(newArrayExp.Expressions);

            return(newArrayExp.Update(newArrayExp.Type, exprs));
        }
예제 #12
0
 NewArrayExpression Convert(NewArrayExpression expr)
 {
     return(expr.Update(Process(expr.Expressions)));
 }
예제 #13
0
 /// <summary>
 /// Visits the children of the <see cref="NewArrayExpression" />.
 /// </summary>
 /// <param name="node">The expression to visit.</param>
 /// <returns>The modified expression, if it or any subexpression was modified;
 /// otherwise, returns the original expression.</returns>
 protected internal virtual Expression VisitNewArray(NewArrayExpression node)
 {
     return(node.Update(Visit(node.Expressions)));
 }
예제 #14
0
 static NewArrayExpression MutateNewArray(NewArrayExpression node, IList <Expression> operands)
 {
     return(node.Update(operands));
 }
예제 #15
0
 protected virtual Expression VisitNewArray(NewArrayExpression expr)
 {
     return(expr.Update(expr.Expressions.Select(a => Visit(a))));
 }
        protected override Expression VisitNewArray(NewArrayExpression node)
        {
            var expressions = new Expression[node.Expressions.Count];
            var shouldApply = true;

            for (var i = 0; i < expressions.Length; i++)
            {
                var expression = Visit(node.Expressions[i]);

                shouldApply &= expression.NodeType == ExpressionType.Constant;

                expressions[i] = expression;
            }

            if (shouldApply)
            {
                try
                {
                    switch (node.NodeType)
                    {
                    case ExpressionType.NewArrayBounds:
                    {
                        var lengths = new int[expressions.Length];

                        for (var i = 0; i < expressions.Length; i++)
                        {
                            lengths[i] = (int)((ConstantExpression)expressions[i]).Value;
                        }

                        return(Expression.Constant(
                                   Array.CreateInstance(
                                       node.Type.GetElementType(),
                                       lengths)));
                    }

                    case ExpressionType.NewArrayInit:
                    {
                        var array
                            = Array.CreateInstance(
                                  node.Type.GetElementType(),
                                  expressions.Length);

                        for (var i = 0; i < expressions.Length; i++)
                        {
                            array.SetValue(((ConstantExpression)expressions[i]).Value, i);
                        }

                        return(Expression.Constant(array));
                    }

                    default:
                    {
                        throw new NotSupportedException();
                    }
                    }
                }
                catch
                {
                    // no-op, proceed to update expressions
                }
            }

            return(node.Update(expressions));
        }
예제 #17
0
 /// <summary>
 /// Visits the children of the <see cref="NewArrayExpression"/>.
 /// </summary>
 /// <param name="node">The expression to visit.</param>
 /// <returns>The modified expression, if it or any subexpression was modified;
 /// otherwise, returns the original expression.</returns>
 protected override Expression VisitNewArray(NewArrayExpression node)
 {
     return(node.Update(Visit(node.Expressions)));
 }
예제 #18
0
        protected override Expression VisitNewArray(NewArrayExpression node)
        {
            var exprs = VisitMemberAndExpressionList(node.Expressions);

            return(node.Update(node.Type, exprs));
        }
예제 #19
0
 private static Expression SetChildren(ReadOnlySpan <Expression> newChildren, NewArrayExpression n)
 => n.Update(newChildren.ToArray());
 /// <summary>
 ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
 ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
 ///     any release. You should only use it directly in your code with extreme caution and knowing that
 ///     doing so can result in application failures when updating to a new Entity Framework Core release.
 /// </summary>
 protected override Expression VisitNewArray(NewArrayExpression newArrayExpression)
 => newArrayExpression.Update(newArrayExpression.Expressions.Select(e => MatchTypes(Visit(e), e.Type)));
 protected virtual Expression VisitNewArray(NewArrayExpression node, Type expectedType)
 => node.Update(node.NodeType == ExpressionType.NewArrayInit
            ? Visit(node.Expressions, node.Type)
            : Visit(node.Expressions, null));