Пример #1
0
        private bool BoolAgainstBool(Expression node, out Expression reduced)
        {
            var binary = node as BinaryExpression;

            if (binary != null)
            {
                if (ExpressionHelpers.IsBool(binary.Left) && ExpressionHelpers.IsBool(binary.Right))
                {
                    //We have some kind of boolean expression like true != false.
                    //Evaluate it and replace it with its resulting value

                    var l = SubstituteExpression.Strip(binary.Left);
                    var r = SubstituteExpression.Strip(binary.Right);
                    var b = Expression.MakeBinary(node.NodeType, l, r);

                    var lambda = Expression.Lambda(b);
                    var result = lambda.Compile().DynamicInvoke();

                    reduced = Expression.Constant(result);
                    return(true);
                }
            }

            reduced = null;
            return(false);
        }
Пример #2
0
        private bool DifferentEnumTypesInternal(Expression node, Expression first, Expression second, out Expression outExpr)
        {
            var firstUnwrapped  = SubstituteExpression.Strip(ExpressionHelpers.UnwrapCast(first));
            var secondUnwrapped = SubstituteExpression.Strip(ExpressionHelpers.UnwrapCast(second));

            if (IsEnum(firstUnwrapped) && IsEnum(secondUnwrapped))
            {
                var property = ExpressionSearcher.Search(firstUnwrapped, p => p is PropertyExpression).FirstOrDefault();

                if (property != null)
                {
                    var comparison = ExpressionSearcher.Search(secondUnwrapped, e => IsEnum(e) && e.NodeType != ExpressionType.Convert && e.NodeType != ExpressionType.ConvertChecked);

                    var firstComparison = comparison.FirstOrDefault();

                    if (firstComparison != null)
                    {
                        if (firstComparison.Type.IsEnum && firstComparison.Type != property.Type)
                        {
                            if (strict)
                            {
                                throw Error.InvalidEnumComparison(node, firstUnwrapped, secondUnwrapped);
                            }

                            Logger.Log($"Condition {node} compares enums of different types. Reducing to 'True'", Indentation.Six);

                            outExpr = Expression.Constant(true);
                            return(true);
                        }
                        else
                        {
                            var constant = firstComparison as ConstantExpression;

                            if (constant != null)
                            {
                                if (property.Type != constant.Value.GetType())
                                {
                                    Logger.Log($"Condition {node} compares enums of different types. Reducing to 'True'", Indentation.Six);

                                    if (strict)
                                    {
                                        throw Error.InvalidEnumComparison(node, firstUnwrapped, secondUnwrapped);
                                    }

                                    outExpr = Expression.Constant(true);
                                    return(true);
                                }
                            }
                        }
                    }
                }
            }

            outExpr = null;
            return(false);
        }
Пример #3
0
        protected override Expression VisitLambda <TNode>(Expression <TNode> lambda)
        {
            var body = Visit(lambda.Body);

            if (body != lambda.Body)
            {
                var substituteBody = new SubstituteExpression(lambda.Body, body);

                return(Expression.Lambda(lambda.Type, substituteBody, lambda.Parameters));
            }

            return(lambda);
        }
Пример #4
0
        private BinaryExpression ReduceDoubleFalseInternal(BinaryExpression original, BinaryExpression binaryInternal)
        {
            var innerLeft  = SubstituteExpression.Strip(binaryInternal.Left);
            var innerRight = SubstituteExpression.Strip(binaryInternal.Right);

            if (IsFalse(innerLeft, binaryInternal.NodeType))
            {
                return(ReduceDoubleFalseInternalInternal(innerRight));
            }

            if (IsFalse(innerRight, binaryInternal.NodeType))
            {
                return(ReduceDoubleFalseInternalInternal(innerLeft));
            }

            return(original);
        }
Пример #5
0
        public BinaryExpression ReduceDoubleFalse(BinaryExpression expr)
        {
            var left  = SubstituteExpression.Strip(expr.Left);
            var right = SubstituteExpression.Strip(expr.Right);

            if (IsFalse(left, expr.NodeType) && right is BinaryExpression)
            {
                return(ReduceDoubleFalseInternal(expr, (BinaryExpression)right));
            }

            if (IsFalse(right, expr.NodeType) && left is BinaryExpression)
            {
                return(ReduceDoubleFalseInternal(expr, (BinaryExpression)left));
            }

            return(expr);
        }
Пример #6
0
        protected override Expression VisitExtension(Expression node)
        {
            var substitute = node as SubstituteExpression;

            if (substitute != null)
            {
                var original    = Visit(substitute.Original);
                var replacement = Visit(substitute.Replacement);

                if (original != substitute.Original || replacement != substitute.Replacement)
                {
                    node = new SubstituteExpression(original, replacement);
                }

                return(node);
            }

            return(base.VisitExtension(node));
        }