Beispiel #1
0
 public static bool Matches(this ExpressionType expressionType, OperatorFlags flags)
 {
     return((((flags & OperatorFlags.Addition) != 0) && expressionType.IsAddition()) ||
            (((flags & OperatorFlags.Arithmetic) != 0) && expressionType.IsArithmetic()) ||
            (((flags & OperatorFlags.Bitwise) != 0) && expressionType.IsBitwise()) ||
            (((flags & OperatorFlags.Comparison) != 0) && expressionType.IsComparison()) ||
            (((flags & OperatorFlags.Equality) != 0) && expressionType.IsEquality()) ||
            (((flags & OperatorFlags.Logical) != 0) && expressionType.IsLogical()) ||
            (((flags & OperatorFlags.Relational) != 0) && expressionType.IsRelational()) ||
            (((flags & OperatorFlags.Shift) != 0) && expressionType.IsShift()) ||
            (((flags & OperatorFlags.Subtraction) != 0) && expressionType.IsSubtraction()));
 }
Beispiel #2
0
        public static void BinaryExpressionArgumentConverter(ref Expression left, ref Expression right, ExpressionType type)
        {
            BinaryExpressionEnumArgumentConverter(ref left, ref right);

            PreparingNullableArguments(ref left, ref right);

            if (type.IsBinary())
            {
                var leftTypeIsNullable  = left.Type.IsNullableType();
                var rightTypeIsNullable = right.Type.IsNullableType();

                var logicalOperation = type.IsBinaryLogical() || type.IsCompare();

                var arifmeticOperation = type.IsArithmetic();

                #region Arifmetic operation

                if (arifmeticOperation)
                {
                    if (left.Type == right.Type && ArifmeticResultTypes.ContainsKey(left.Type))
                    {
                        var commonType = ArifmeticResultTypes[left.Type];

                        left  = ConvertExpression(left, commonType);
                        right = ConvertExpression(right, commonType);
                    }
                    else
                    {
                        var leftType  = Nullable.GetUnderlyingType(left.Type);
                        var rightType = Nullable.GetUnderlyingType(right.Type);

                        if ((leftTypeIsNullable && leftType == right.Type && ArifmeticResultTypes.ContainsKey(right.Type))
                            ||
                            (rightTypeIsNullable && rightType == left.Type && ArifmeticResultTypes.ContainsKey(left.Type)))
                        {
                            if (leftTypeIsNullable)
                            {
                                var commonType = ArifmeticResultTypes[left.Type];

                                if (!rightTypeIsNullable)
                                {
                                    var commonUnderlyingType = commonType.GetGenericArguments().First();
                                    right = ConvertExpression(right, commonUnderlyingType);
                                }

                                right = ConvertExpression(right, commonType);
                                left  = ConvertExpression(left, commonType);
                            }
                            else
                            {
                                var commonType           = ArifmeticResultTypes[right.Type];
                                var commonUnderlyingType = commonType.GetGenericArguments().First();

                                left  = ConvertExpression(left, commonUnderlyingType);
                                left  = ConvertExpression(left, commonType);
                                right = ConvertExpression(right, commonType);
                            }
                        }
                    }
                }

                #endregion

                if (logicalOperation && left.Type == right.Type)
                {
                    return;
                }

                if (logicalOperation && left.Type == right.Type)
                {
                    return;
                }

                if (leftTypeIsNullable || rightTypeIsNullable)
                {
                    var leftType  = Nullable.GetUnderlyingType(left.Type) ?? left.Type;
                    var rightType = Nullable.GetUnderlyingType(right.Type) ?? right.Type;

                    if (leftType == rightType)
                    {
                        var commonType = NullableType.MakeGenericType(leftType);
                        left  = ConvertExpression(left, commonType);
                        right = ConvertExpression(right, commonType);
                    }
                    else
                    {
                        if (ImplicitNumericConversions.ContainsKey(leftType) &&
                            ImplicitNumericConversions.ContainsKey(rightType))
                        {
                            var leftTypes  = ImplicitNumericConversions[leftType];
                            var rightTypes = ImplicitNumericConversions[rightType];

                            var isIntegralTypes = IntegralTypes.Contains(left.Type) &&
                                                  IntegralTypes.Contains(right.Type);

                            var commonType = isIntegralTypes
                                ? leftTypes.Where(t => IntegralTypes.Contains(t))
                                             .Intersect(rightTypes.Where(t => IntegralTypes.Contains(t)))
                                             .FirstOrDefault()
                                : leftTypes.Intersect(rightTypes).FirstOrDefault();

                            if (commonType != null)
                            {
                                commonType = NullableType.MakeGenericType(commonType);

                                left  = ConvertExpression(left, commonType);
                                right = ConvertExpression(right, commonType);
                            }
                        }
                    }
                }
                else
                {
                    if (ImplicitNumericConversions.ContainsKey(left.Type) &&
                        ImplicitNumericConversions.ContainsKey(right.Type))
                    {
                        var leftTypes  = ImplicitNumericConversions[left.Type];
                        var rightTypes = ImplicitNumericConversions[right.Type];

                        var isIntegralTypes = IntegralTypes.Contains(left.Type) && IntegralTypes.Contains(right.Type);

                        var commonType = isIntegralTypes
                            ? leftTypes.Where(t => IntegralTypes.Contains(t))
                                         .Intersect(rightTypes.Where(t => IntegralTypes.Contains(t)))
                                         .FirstOrDefault()
                            : leftTypes.Intersect(rightTypes).FirstOrDefault();

                        if (commonType != null)
                        {
                            left  = ConvertExpression(left, commonType);
                            right = ConvertExpression(right, commonType);
                        }
                    }
                }
            }
        }