예제 #1
0
        protected virtual Expression ResolveEnumOperator(ParseContext ec, Expression expr)
        {
            var underlyingType = Enum.GetUnderlyingType(expr.Type);

            var bestExpr = ResolvePrimitivePredefinedType(ec, EmptyCastExpression.Create(expr, underlyingType));

            if (bestExpr == null)
            {
                return(null);
            }

            Operand = bestExpr;
            Type    = expr.Type;

            return(EmptyCastExpression.Create(this, Type));
        }
예제 #2
0
        Expression LiftResult(ParseContext ec, Expression res_expr)
        {
            TypeExpression lifted_type;

            //
            // Avoid double conversion
            //
            if (left_unwrap == null || left_null_lifted || !TypeManager.IsEqual(left_unwrap.Type, Left.Type) || (left_unwrap != null && right_null_lifted))
            {
                lifted_type = new NullableTypeExpression(Left.Type, Span);
                lifted_type = lifted_type.ResolveAsTypeTerminal(ec, false);
                if (lifted_type == null)
                {
                    return(null);
                }

                if (Left is CastExpression)
                {
                    ((CastExpression)Left).DestinationType = new TypeExpression(lifted_type.Type);
                }
                else
                {
                    Left = EmptyCastExpression.Create(Left, lifted_type.Type);
                }
            }

            if (right_unwrap == null || right_null_lifted || !TypeManager.IsEqual(right_unwrap.Type, Right.Type) || (right_unwrap != null && left_null_lifted))
            {
                lifted_type = new NullableTypeExpression(Right.Type, Span);
                lifted_type = lifted_type.ResolveAsTypeTerminal(ec, false);

                if (lifted_type == null)
                {
                    return(null);
                }

                if (Right is CastExpression)
                {
                    ((CastExpression)Right).DestinationType = new TypeExpression(lifted_type.Type);
                }
                else
                {
                    Right = EmptyCastExpression.Create(Right, lifted_type.Type);
                }
            }

            if (!Operator.IsComparison())
            {
                lifted_type = new NullableTypeExpression(res_expr.Type, Span);
                lifted_type = lifted_type.ResolveAsTypeTerminal(ec, false);

                if (lifted_type == null)
                {
                    return(null);
                }

                wrap_ctor  = new NullableInfo(lifted_type.Type).Constructor;
                ResultType = res_expr.Type = lifted_type.Type;
            }

            if (left_null_lifted)
            {
                Left = LiftedNullExpression.Create(Right.Type, Left.Span);

                if (Operator.IsArithmetic() || Operator.IsShift() || Operator.IsBitwise())
                {
                    return(LiftedNullExpression.CreateFromExpression(ec, res_expr));
                }

                //
                // Value types and null comparison
                //
                if (right_unwrap == null || Operator.IsRelational())
                {
                    return(CreateNullConstant(ec, right_orig).Resolve(ec));
                }
            }

            if (right_null_lifted)
            {
                Right = LiftedNullExpression.Create(Left.Type, Right.Span);

                if (Operator.IsArithmetic() || Operator.IsShift() || Operator.IsBitwise())
                {
                    return(LiftedNullExpression.CreateFromExpression(ec, res_expr));
                }

                //
                // Value types and null comparison
                //
                if (left_unwrap == null || Operator.IsRelational())
                {
                    return(CreateNullConstant(ec, left_orig).Resolve(ec));
                }
            }

            return(res_expr);
        }