Exemple #1
0
        Expression LiftExpression(ResolveContext ec, Expression expr)
        {
            TypeExpr lifted_type = new NullableType(expr.Type, expr.Location);

            lifted_type = lifted_type.ResolveAsTypeTerminal(ec, false);
            if (lifted_type == null)
            {
                return(null);
            }

            expr.Type = lifted_type.Type;
            return(expr);
        }
Exemple #2
0
		Expression LiftResult (ResolveContext ec, Expression res_expr)
		{
			TypeExpr lifted_type;

			//
			// Avoid double conversion
			//
			if (left_unwrap == null || IsLeftNullLifted || left_unwrap.Type != left.Type || (left_unwrap != null && IsRightNullLifted)) {
				lifted_type = new NullableType (left.Type, loc);
				lifted_type = lifted_type.ResolveAsTypeTerminal (ec, false);
				if (lifted_type == null)
					return null;

				if (left is UserCast || left is TypeCast)
					left.Type = lifted_type.Type;
				else
					left = EmptyCast.Create (left, lifted_type.Type);
			}

			if (left != right && (right_unwrap == null || IsRightNullLifted || right_unwrap.Type != right.Type || (right_unwrap != null && IsLeftNullLifted))) {
				lifted_type = new NullableType (right.Type, loc);
				lifted_type = lifted_type.ResolveAsTypeTerminal (ec, false);
				if (lifted_type == null)
					return null;

				var r = right;
				if (r is ReducedExpression)
					r = ((ReducedExpression) r).OriginalExpression;

				if (r is UserCast || r is TypeCast)
					r.Type = lifted_type.Type;
				else
					right = EmptyCast.Create (right, lifted_type.Type);
			}

			if ((Oper & Operator.ComparisonMask) == 0) {
				lifted_type = new NullableType (res_expr.Type, loc);
				lifted_type = lifted_type.ResolveAsTypeTerminal (ec, false);
				if (lifted_type == null)
					return null;

				wrap_ctor = NullableInfo.GetConstructor (lifted_type.Type);
				type = res_expr.Type = lifted_type.Type;
			}

			if (IsLeftNullLifted) {
				left = LiftedNull.Create (right.Type, left.Location);

				//
				// Special case for bool?, the result depends on both null right side and left side value
				//
				if ((Oper == Operator.BitwiseAnd || Oper == Operator.BitwiseOr) && NullableInfo.GetUnderlyingType (type).BuiltinType == BuiltinTypeSpec.Type.Bool) {
					return res_expr;
				}

				if ((Oper & (Operator.ArithmeticMask | Operator.ShiftMask | Operator.BitwiseMask)) != 0)
					return LiftedNull.CreateFromExpression (ec, res_expr);

				//
				// Value types and null comparison
				//
				if (right_unwrap == null || (Oper & Operator.RelationalMask) != 0)
					return CreateNullConstant (ec, right_orig);
			}

			if (IsRightNullLifted) {
				right = LiftedNull.Create (left.Type, right.Location);

				//
				// Special case for bool?, the result depends on both null right side and left side value
				//
				if ((Oper == Operator.BitwiseAnd || Oper == Operator.BitwiseOr) && NullableInfo.GetUnderlyingType (type).BuiltinType == BuiltinTypeSpec.Type.Bool) {
					return res_expr;
				}

				if ((Oper & (Operator.ArithmeticMask | Operator.ShiftMask | Operator.BitwiseMask)) != 0)
					return LiftedNull.CreateFromExpression (ec, res_expr);

				//
				// Value types and null comparison
				//
				if (left_unwrap == null || (Oper & Operator.RelationalMask) != 0)
					return CreateNullConstant (ec, left_orig);
			}

			return res_expr;
		}
Exemple #3
0
		Expression LiftExpression (ResolveContext ec, Expression expr)
		{
			TypeExpr lifted_type = new NullableType (expr.Type, expr.Location);
			lifted_type = lifted_type.ResolveAsTypeTerminal (ec, false);
			if (lifted_type == null)
				return null;

			expr.Type = lifted_type.Type;
			return expr;
		}
Exemple #4
0
        Expression LiftResult(ResolveContext ec, Expression res_expr)
        {
            TypeExpr lifted_type;

            //
            // Avoid double conversion
            //
            if (left_unwrap == null || IsLeftNullLifted || left_unwrap.Type != left.Type || (left_unwrap != null && IsRightNullLifted))
            {
                lifted_type = new NullableType(left.Type, loc);
                lifted_type = lifted_type.ResolveAsTypeTerminal(ec, false);
                if (lifted_type == null)
                {
                    return(null);
                }

                if (left is UserCast || left is TypeCast)
                {
                    left.Type = lifted_type.Type;
                }
                else
                {
                    left = EmptyCast.Create(left, lifted_type.Type);
                }
            }

            if (left != right && (right_unwrap == null || IsRightNullLifted || right_unwrap.Type != right.Type || (right_unwrap != null && IsLeftNullLifted)))
            {
                lifted_type = new NullableType(right.Type, loc);
                lifted_type = lifted_type.ResolveAsTypeTerminal(ec, false);
                if (lifted_type == null)
                {
                    return(null);
                }

                var r = right;
                if (r is ReducedExpression)
                {
                    r = ((ReducedExpression)r).OriginalExpression;
                }

                if (r is UserCast || r is TypeCast)
                {
                    r.Type = lifted_type.Type;
                }
                else
                {
                    right = EmptyCast.Create(right, lifted_type.Type);
                }
            }

            if ((Oper & Operator.ComparisonMask) == 0)
            {
                lifted_type = new NullableType(res_expr.Type, loc);
                lifted_type = lifted_type.ResolveAsTypeTerminal(ec, false);
                if (lifted_type == null)
                {
                    return(null);
                }

                wrap_ctor = NullableInfo.GetConstructor(lifted_type.Type);
                type      = res_expr.Type = lifted_type.Type;
            }

            if (IsLeftNullLifted)
            {
                left = LiftedNull.Create(right.Type, left.Location);

                //
                // Special case for bool?, the result depends on both null right side and left side value
                //
                if ((Oper == Operator.BitwiseAnd || Oper == Operator.BitwiseOr) && NullableInfo.GetUnderlyingType(type).BuiltinType == BuiltinTypeSpec.Type.Bool)
                {
                    return(res_expr);
                }

                if ((Oper & (Operator.ArithmeticMask | Operator.ShiftMask | Operator.BitwiseMask)) != 0)
                {
                    return(LiftedNull.CreateFromExpression(ec, res_expr));
                }

                //
                // Value types and null comparison
                //
                if (right_unwrap == null || (Oper & Operator.RelationalMask) != 0)
                {
                    return(CreateNullConstant(ec, right_orig));
                }
            }

            if (IsRightNullLifted)
            {
                right = LiftedNull.Create(left.Type, right.Location);

                //
                // Special case for bool?, the result depends on both null right side and left side value
                //
                if ((Oper == Operator.BitwiseAnd || Oper == Operator.BitwiseOr) && NullableInfo.GetUnderlyingType(type).BuiltinType == BuiltinTypeSpec.Type.Bool)
                {
                    return(res_expr);
                }

                if ((Oper & (Operator.ArithmeticMask | Operator.ShiftMask | Operator.BitwiseMask)) != 0)
                {
                    return(LiftedNull.CreateFromExpression(ec, res_expr));
                }

                //
                // Value types and null comparison
                //
                if (left_unwrap == null || (Oper & Operator.RelationalMask) != 0)
                {
                    return(CreateNullConstant(ec, left_orig));
                }
            }

            return(res_expr);
        }
Exemple #5
0
		Expression LiftResult (ResolveContext ec, Expression res_expr)
		{
			TypeExpr 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 NullableType (left.Type, loc);
				lifted_type = lifted_type.ResolveAsTypeTerminal (ec, false);
				if (lifted_type == null)
					return null;

				if (left is UserCast || left is TypeCast)
					left.Type = lifted_type.Type;
				else
					left = EmptyCast.Create (left, lifted_type.Type);
			}

			if (left != right && (right_unwrap == null || right_null_lifted || !TypeManager.IsEqual (right_unwrap.Type, right.Type) || (right_unwrap != null && left_null_lifted))) {
				lifted_type = new NullableType (right.Type, loc);
				lifted_type = lifted_type.ResolveAsTypeTerminal (ec, false);
				if (lifted_type == null)
					return null;

				if (right is UserCast || right is TypeCast)
					right.Type = lifted_type.Type;
				else
					right = EmptyCast.Create (right, lifted_type.Type);
			}

			if ((Oper & Operator.ComparisonMask) == 0) {
				lifted_type = new NullableType (res_expr.Type, loc);
				lifted_type = lifted_type.ResolveAsTypeTerminal (ec, false);
				if (lifted_type == null)
					return null;

				wrap_ctor = NullableInfo.GetConstructor (lifted_type.Type);
				type = res_expr.Type = lifted_type.Type;
			}

			if (left_null_lifted) {
				left = LiftedNull.Create (right.Type, left.Location);

				if ((Oper & (Operator.ArithmeticMask | Operator.ShiftMask | Operator.BitwiseMask)) != 0)
					return LiftedNull.CreateFromExpression (ec, res_expr);

				//
				// Value types and null comparison
				//
				if (right_unwrap == null || (Oper & Operator.RelationalMask) != 0)
					return CreateNullConstant (ec, right_orig).Resolve (ec);
			}

			if (right_null_lifted) {
				right = LiftedNull.Create (left.Type, right.Location);

				if ((Oper & (Operator.ArithmeticMask | Operator.ShiftMask | Operator.BitwiseMask)) != 0)
					return LiftedNull.CreateFromExpression (ec, res_expr);

				//
				// Value types and null comparison
				//
				if (left_unwrap == null || (Oper & Operator.RelationalMask) != 0)
					return CreateNullConstant (ec, left_orig);
			}

			return res_expr;
		}
Exemple #6
0
        Expression LiftResult(ResolveContext ec, Expression res_expr)
        {
            TypeExpr 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 NullableType(left.Type, loc);
                lifted_type = lifted_type.ResolveAsTypeTerminal(ec, false);
                if (lifted_type == null)
                {
                    return(null);
                }

                if (left is UserCast || left is TypeCast)
                {
                    left.Type = lifted_type.Type;
                }
                else
                {
                    left = EmptyCast.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 NullableType(right.Type, loc);
                lifted_type = lifted_type.ResolveAsTypeTerminal(ec, false);
                if (lifted_type == null)
                {
                    return(null);
                }

                if (right is UserCast || right is TypeCast)
                {
                    right.Type = lifted_type.Type;
                }
                else
                {
                    right = EmptyCast.Create(right, lifted_type.Type);
                }
            }

            if ((Oper & Operator.ComparisonMask) == 0)
            {
                lifted_type = new NullableType(res_expr.Type, loc);
                lifted_type = lifted_type.ResolveAsTypeTerminal(ec, false);
                if (lifted_type == null)
                {
                    return(null);
                }

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

            if (left_null_lifted)
            {
                left = LiftedNull.Create(right.Type, left.Location);

                if ((Oper & (Operator.ArithmeticMask | Operator.ShiftMask | Operator.BitwiseMask)) != 0)
                {
                    return(LiftedNull.CreateFromExpression(ec, res_expr));
                }

                //
                // Value types and null comparison
                //
                if (right_unwrap == null || (Oper & Operator.RelationalMask) != 0)
                {
                    return(CreateNullConstant(ec, right_orig).Resolve(ec));
                }
            }

            if (right_null_lifted)
            {
                right = LiftedNull.Create(left.Type, right.Location);

                if ((Oper & (Operator.ArithmeticMask | Operator.ShiftMask | Operator.BitwiseMask)) != 0)
                {
                    return(LiftedNull.CreateFromExpression(ec, res_expr));
                }

                //
                // Value types and null comparison
                //
                if (left_unwrap == null || (Oper & Operator.RelationalMask) != 0)
                {
                    return(CreateNullConstant(ec, left_orig).Resolve(ec));
                }
            }

            return(res_expr);
        }