Beispiel #1
0
        ConditionalExpression VisitConditionalStatement(ConditionalExpression node)
        {
            Write("if");
            WriteSpace();
            Write("(");

            var test = Expression.Block(VisitWithDebug(node.Test, 0));

            Write(")");
            WriteLine();

            var ifTrue = VisitAsBlock(node.IfTrue);

            if (node.IfFalse != null)
            {
                if (node.IfFalse.NodeType == ExpressionType.Default && node.IfFalse.Type == typeof(void))
                {
                    return(node.Update(test, ifTrue, node.IfFalse));
                }

                Write("else");
                WriteLine();

                var ifFalse = VisitAsBlock(node.IfFalse);

                return(node.Update(test, ifTrue, ifFalse));
            }
            else
            {
                return(node.Update(test, ifTrue, node.IfFalse));
            }
        }
Beispiel #2
0
        protected override Expression VisitConditional(ConditionalExpression node)
        {
            var visitedTest    = Visit(node.Test);
            var visitedIfTrue  = Visit(node.IfTrue);
            var visitedIfFalse = Visit(node.IfFalse);

            if (visitedTest is ConstantExpression && visitedIfTrue is ConstantExpression && visitedIfFalse is ConstantExpression)
            {
                return(TryEvaluateExpression(node.Update(visitedTest, visitedIfTrue, visitedIfFalse)));
            }

            return(node.Update(visitedTest, visitedIfTrue, visitedIfFalse));
        }
        protected override Expression VisitConditional(ConditionalExpression node)
        {
            var visitedTest    = Visit(node.Test);
            var visitedIfTrue  = Visit(node.IfTrue);
            var visitedIfFalse = Visit(node.IfFalse);

            if (visitedTest.NodeType == ExpressionType.Constant &&
                visitedIfTrue.NodeType == ExpressionType.Constant &&
                visitedIfFalse.NodeType == ExpressionType.Constant)
            {
                return(TryEvaluateExpression(node.Update(visitedTest, visitedIfTrue, visitedIfFalse)));
            }

            return(node.Update(visitedTest, visitedIfTrue, visitedIfFalse));
        }
        /// <summary>
        /// Visit conditional
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        protected override Expression VisitConditional(ConditionalExpression expression)
        {
            Check.NotNull(expression, nameof(expression));

            if (expression.IsNullPropagationCandidate(out var testExpression, out var resultExpression))
            // TODO: Null Check removal)
            {
                return(Visit(resultExpression));
            }

            var test = Visit(expression.Test);

            if (test?.IsSimple() == true)
            {
                test = Expression.Equal(
                    test,
                    Expression.Constant(true, typeof(bool))
                    );
            }

            var ifTrue  = Visit(expression.IfTrue);
            var ifFalse = Visit(expression.IfFalse);

            if (!(test is null) && !(ifTrue is null) && !(ifFalse is null))
            {
                // TODO: IfTrue or IfFalse is expression array

                // TODO: Invertion

                return(expression.Update(test, ifTrue, ifFalse));
            }

            return(null);
        }
Beispiel #5
0
        protected override Expression VisitConditional(ConditionalExpression node)
        {
            var testReference = CreateConditionalNode(node);

            _conditionalReferences.Add(testReference);

            DependencyNode dependencyNode = null;

            if (InpcType.IsAssignableFrom(node.Type) && _context.DownstreamNode != null)
            {
                // Create virtual node
                dependencyNode = GetOrCreateNode(node, () => new DependencyNode(node));
            }

            var context = _context.Clone(item =>
            {
                item.DownstreamNode      = dependencyNode;
                item.ConditionalNode     = testReference;
                item.ConditionalNodeType = ConditionalNodeType.Test;
            });

            var testExpression = VisitInContext(() => Visit(node.Test), context);

            context.ConditionalNodeType = ConditionalNodeType.IfTrue;
            var ifTrueExpression = VisitInContext(() => Visit(node.IfTrue), context);

            context.ConditionalNodeType = ConditionalNodeType.IfFalse;
            var ifFalseExpression = VisitInContext(() => Visit(node.IfFalse), context);

            return(node.Update(testExpression, ifTrueExpression, ifFalseExpression));
        }
            protected override Expression VisitConditional(ConditionalExpression node)
            {
                var c = Visit(node.Test);
                var t = Visit(node.IfTrue);
                var f = Visit(node.IfFalse);

                var fs = _tilingState.Pop();
                var ts = _tilingState.Pop();
                var cs = _tilingState.Pop();

                if (All(cs, ts, fs))
                {
                    _tilingState.Push(true);
                }
                else
                {
                    _tilingState.Push(false);

                    EvaluateIf(cs, ref c);
                    EvaluateIf(ts, ref t);
                    EvaluateIf(fs, ref f);
                }

                return(node.Update(c, t, f));
            }
Beispiel #7
0
        /// <summary>
        /// 访问 <see cref="ConditionalExpression"/>。
        /// </summary>
        /// <param name="conditionExp">要访问的表达式。</param>
        /// <returns></returns>
        protected virtual Expression VisitConditional(ConditionalExpression conditionExp)
        {
            var test    = Visit(conditionExp.Test);
            var ifTrue  = Visit(conditionExp.IfTrue);
            var ifFalse = Visit(conditionExp.IfFalse);

            return(conditionExp.Update(test, ifTrue, ifFalse));
        }
Beispiel #8
0
 protected override Expression VisitConditional(ConditionalExpression node)
 {
     if (node.IfFalse == null || node.IfFalse.NodeType == ExpressionType.Default)
     {
         return(node.Update(this.Visit(node.Test), this.Visit(node.IfTrue), this.Visit(_ifFalse)));
     }
     return(base.VisitConditional(node));
 }
Beispiel #9
0
        protected override Expression VisitConditional(ConditionalExpression node)
        {
            var children = new[] { node.Test, node.IfTrue, node.IfFalse };

            VisitChildren(children);

            return(node.Update(children[0], children[1], children[2]));
        }
Beispiel #10
0
        protected override Expression VisitConditional(ConditionalExpression conditionalExpression)
        {
            var newIfTrue  = Visit(conditionalExpression.IfTrue);
            var newIfFalse = Visit(conditionalExpression.IfFalse);

            return(newIfTrue != conditionalExpression.IfTrue || newIfFalse != conditionalExpression.IfFalse
                ? conditionalExpression.Update(conditionalExpression.Test, newIfTrue, newIfFalse)
                : conditionalExpression);
        }
Beispiel #11
0
        protected override Expression VisitConditional(ConditionalExpression c)
        {
            var test = Visit(c.Test);

            if (test.NodeType == ExpressionType.Constant)
            {
                return((bool)((ConstantExpression)test).Value ? Visit(c.IfTrue) : Visit(c.IfFalse));
            }
            return(c.Update(test, Visit(c.IfTrue), Visit(c.IfFalse)));
        }
Beispiel #12
0
        protected override Expression VisitConditionalExpression(ConditionalExpression expression)
        {
            var test    = VisitExpression(expression.Test);
            var ifTrue  = VisitExpression(expression.IfTrue);
            var ifFalse = VisitExpression(expression.IfFalse);

            Equals(ifTrue.Type, ifFalse.Type);

            return(expression.Update(test, ifTrue, ifFalse));
        }
        protected override Expression VisitConditionalExpression(ConditionalExpression expression)
        {
#if WINDOWS_PHONE || PORTABLE
            return(Expression.Condition(VisitExpression(expression.Test),
                                        VisitExpression(expression.IfTrue),
                                        VisitExpression(expression.IfFalse)));
#else
            return(expression.Update(VisitExpression(expression.Test), VisitExpression(expression.IfTrue),
                                     VisitExpression(expression.IfFalse)));
#endif
        }
            protected override Expression VisitConditional(ConditionalExpression node)
            {
                var test = base.Visit(node.Test);

                if (test is ConstantExpression constantTestExpression)
                {
                    var value = (bool)constantTestExpression.Value;
                    return(value ? Visit(node.IfTrue) : Visit(node.IfFalse));
                }

                return(node.Update(test, Visit(node.IfTrue), Visit(node.IfFalse)));
            }
Beispiel #15
0
        protected override Expression VisitConditional(ConditionalExpression node)
        {
            var test    = Visit(node.Test);
            var ifTrue  = Visit(node.IfTrue);
            var ifFalse = Visit(node.IfFalse);

            if (test != node.Test || ifTrue != node.IfTrue || ifFalse != node.IfFalse)
            {
                return(node.Update(test, ifTrue, ifFalse));
            }
            return(node);
        }
Beispiel #16
0
        protected override Expression VisitConditional(ConditionalExpression expression)
        {
            var oldRequiresJoinForNonIdentifier = _requiresJoinForNonIdentifier;

            _requiresJoinForNonIdentifier = !_preventJoinsInConditionalTest && _requiresJoinForNonIdentifier;
            var newTest = Visit(expression.Test);

            _requiresJoinForNonIdentifier = oldRequiresJoinForNonIdentifier;
            var newFalse = Visit(expression.IfFalse);
            var newTrue  = Visit(expression.IfTrue);

            return(expression.Update(newTest, newTrue, newFalse));
        }
        protected override Expression VisitConditional(ConditionalExpression conditionalExpression)
        {
            var test    = Visit(conditionalExpression.Test);
            var ifTrue  = Visit(conditionalExpression.IfTrue);
            var ifFalse = Visit(conditionalExpression.IfFalse);

            if (test.Type == typeof(bool?))
            {
                test = Expression.Equal(test, Expression.Constant(true, typeof(bool?)));
            }

            return(conditionalExpression.Update(test, ifTrue, ifFalse));
        }
        protected override Expression VisitConditional(ConditionalExpression conditionalExpression)
        {
            var newTest    = Visit(conditionalExpression.Test);
            var newIfTrue  = Visit(conditionalExpression.IfTrue);
            var newIfFalse = Visit(conditionalExpression.IfFalse);

            var newConditional = conditionalExpression.Update(newTest, Unwrap(newIfTrue), Unwrap(newIfFalse));

            // TODO: the true and false sides may refer different entity types which happen to have the same
            // CLR type (e.g. shared entities)
            var wrapper = newIfTrue as EntityReferenceExpression ?? newIfFalse as EntityReferenceExpression;

            return(wrapper == null ? (Expression)newConditional : wrapper.Update(newConditional));
        }
            protected override Expression VisitConditional(ConditionalExpression conditionalExpression)
            {
                var test    = Visit(conditionalExpression.Test);
                var ifTrue  = Visit(conditionalExpression.IfTrue);
                var ifFalse = Visit(conditionalExpression.IfFalse);

                if (ifTrue.Type.IsNullableType() &&
                    conditionalExpression.IfTrue.Type == ifTrue.Type.UnwrapNullableType() &&
                    ifFalse is DefaultExpression)
                {
                    ifFalse = Default(ifTrue.Type);
                }

                return(conditionalExpression.Update(test, ifTrue, ifFalse));
            }
        protected override Expression VisitConditional(ConditionalExpression node)
        {
            bool isSearchCondition = _isSearchCondition;

            _isSearchCondition = true;
            Expression test = Visit(node.Test);

            _isSearchCondition = false;
            Expression ifTrue  = Visit(node.IfTrue);
            Expression ifFalse = Visit(node.IfFalse);

            _isSearchCondition = isSearchCondition;
            node = node.Update(test, ifTrue, ifFalse);
            return(ApplyConversion(node));
        }
        protected override Expression VisitConditional(ConditionalExpression expression)
        {
            var test    = Visit(expression.Test);
            var ifTrue  = Visit(expression.IfTrue);
            var ifFalse = Visit(expression.IfFalse);

            if (test != null &&
                ifTrue != null &&
                ifFalse != null)
            {
                return(expression.Update(test, ifTrue, ifFalse));
            }

            return(null);
        }
Beispiel #22
0
        /// <summary>
        ///     Visits a conditional expression.
        /// </summary>
        /// <param name="expression"> The expression to visit. </param>
        /// <returns>
        ///     An Expression.
        /// </returns>
        protected override Expression VisitConditional(ConditionalExpression expression)
        {
            Check.NotNull(expression, nameof(expression));

            if (expression.IsNullPropagationCandidate(out var testExpression, out var resultExpression) &&
                _nullCheckRemovalTestingVisitor.CanRemoveNullCheck(testExpression, resultExpression))
            {
                return(Visit(resultExpression));
            }

            var test = Visit(expression.Test);

            if (test?.IsSimpleExpression() == true)
            {
                test = Expression.Equal(test, Expression.Constant(true, typeof(bool)));
            }

            var ifTrue  = Visit(expression.IfTrue);
            var ifFalse = Visit(expression.IfFalse);

            if (test != null &&
                ifTrue != null &&
                ifFalse != null)
            {
                // 'test ? new { ... } : null' case can't be translated
                if (ifTrue.Type == typeof(Expression[]) ||
                    ifFalse.Type == typeof(Expression[]))
                {
                    return(null);
                }

                if (ifTrue.IsComparisonOperation() ||
                    ifFalse.IsComparisonOperation())
                {
                    var invertedTest = Invert(test);
                    if (invertedTest != null)
                    {
                        return(Expression.OrElse(
                                   Expression.AndAlso(test, ifTrue),
                                   Expression.AndAlso(invertedTest, ifFalse)));
                    }
                }

                return(expression.Update(test, ifTrue, ifFalse));
            }

            return(null);
        }
        protected override Expression VisitConditional(ConditionalExpression node)
        {
            if (node.Type == typeof(void))
            {
                node = node.Update(node.Test, Statement.Wrap(node.IfTrue), Statement.Wrap(node.IfFalse));
                return(context.Rewrite(node, base.VisitConditional));
            }
            else if (node.IfTrue is BlockExpression && node.IfFalse is BlockExpression)
            {
                throw new NotSupportedException(ExceptionMessages.UnsupportedConditionalExpr);
            }
            else
            {
                /*
                 *  x = a ? await b() : c();
                 *  --transformed into--
                 *  var temp;
                 *  if(a)
                 *      temp = await b();
                 *  else
                 *      temp = c();
                 *  x = temp;
                 */
                var prologue = context.CurrentStatement.PrologueCodeInserter();
                {
                    var result = context.Rewrite(node, base.VisitConditional);
                    if (result is ConditionalExpression conditional)
                    {
                        node = conditional;
                    }
                    else
                    {
                        return(result);
                    }
                }

                if ((ExpressionAttributes.Get(node.IfTrue)?.ContainsAwait ?? false) || (ExpressionAttributes.Get(node.IfFalse)?.ContainsAwait ?? false))
                {
                    var tempVar = NewStateSlot(node.Type);
                    prologue(Expression.Condition(node.Test, Expression.Assign(tempVar, node.IfTrue), Expression.Assign(tempVar, node.IfFalse), typeof(void)));
                    return(tempVar);
                }
                else
                {
                    return(node);
                }
            }
        }
Beispiel #24
0
        Expression VisitConditionalExpression(ConditionalExpression node)
        {
            var test = Visit(node.Test);

            WriteSpace();
            Write("?");
            WriteSpace();
            var ifTrue = Visit(node.IfTrue);

            WriteSpace();
            Write(":");
            WriteSpace();
            var ifFalse = Visit(node.IfFalse);

            return(node.Update(test, ifTrue, ifFalse));
        }
        /// <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 VisitConditional(ConditionalExpression conditionalExpression)
        {
            var newTestExpression = TryGetConstantValue(conditionalExpression.Test) ?? Visit(conditionalExpression.Test);

            if (newTestExpression is ConstantExpression constantTestExpression &&
                constantTestExpression.Value is bool constantTestValue)
            {
                return(constantTestValue
                    ? Visit(conditionalExpression.IfTrue)
                    : Visit(conditionalExpression.IfFalse));
            }

            return(conditionalExpression.Update(
                       newTestExpression,
                       Visit(conditionalExpression.IfTrue),
                       Visit(conditionalExpression.IfFalse)));
        }
Beispiel #26
0
        protected override Expression VisitConditional(ConditionalExpression conditionalExpression)
        {
            Check.NotNull(conditionalExpression, nameof(conditionalExpression));

            var test    = Visit(conditionalExpression.Test);
            var ifTrue  = Visit(conditionalExpression.IfTrue);
            var ifFalse = Visit(conditionalExpression.IfFalse);

            if (test != null &&
                ifTrue != null &&
                ifFalse != null)
            {
                return(conditionalExpression.Update(test, ifTrue, ifFalse));
            }

            return(null);
        }
Beispiel #27
0
        protected override Expression VisitConditional(ConditionalExpression node)
        {
            var test = Visit(node.Test);

            if (test.UnwrapInnerExpression() is ConstantExpression constant)
            {
                return(true.Equals(constant.Value) ? Visit(node.IfTrue) : Visit(node.IfFalse));
            }

            var ifTrue  = Visit(node.IfTrue);
            var ifFalse = Visit(node.IfFalse);

            if (ifTrue.IsSemanticallyEqualTo(ifFalse))
            {
                return(ifTrue);
            }

            return(node.Update(test, ifTrue, ifFalse));
        }
Beispiel #28
0
        /// <summary>
        /// Flattens nested conditional expressions by using <see cref="ExpressionType.AndAlso"/> nodes
        /// to combine conditions.
        /// </summary>
        /// <param name="node">The node to flatten.</param>
        /// <returns>The result of flattening the conditional expression.</returns>
        private static Expression FlattenConditional(ConditionalExpression node)
        {
            if (node.IfFalse.NodeType == ExpressionType.Default)
            {
                var current = node;

                var test   = current.Test;
                var ifTrue = current.IfTrue;

                while (IsIfThen(ifTrue, out current))
                {
                    test   = Expression.AndAlso(test, current.Test);
                    ifTrue = current.IfTrue;
                }

                return(node.Update(test, ifTrue, node.IfFalse));
            }

            return(node);
        }
        /// <summary>
        ///     Visits a conditional expression.
        /// </summary>
        /// <param name="expression"> The expression to visit. </param>
        /// <returns>
        ///     An Expression.
        /// </returns>
        protected override Expression VisitConditional(ConditionalExpression expression)
        {
            Check.NotNull(expression, nameof(expression));

            var nullCheckRemoved = TryRemoveNullCheck(expression);

            if (nullCheckRemoved != null)
            {
                return(Visit(nullCheckRemoved));
            }

            var test = Visit(expression.Test);

            if (test.IsSimpleExpression())
            {
                test = Expression.Equal(test, Expression.Constant(true, typeof(bool)));
            }

            var ifTrue  = Visit(expression.IfTrue);
            var ifFalse = Visit(expression.IfFalse);

            // ReSharper disable once ConditionIsAlwaysTrueOrFalse
            if (test != null &&
                ifTrue != null &&
                ifFalse != null)
            {
                if (ifTrue.IsComparisonOperation() ||
                    ifFalse.IsComparisonOperation())
                {
                    return(Expression.OrElse(
                               Expression.AndAlso(test, ifTrue),
                               Expression.AndAlso(Invert(test), ifFalse)));
                }

                return(expression.Update(test, ifTrue, ifFalse));
            }

            return(null);
        }
        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);
        }