Пример #1
0
        protected override Expression DoResolve(ResolveContext ec)
        {
            unwrap = Unwrap.Create(Expr, false);
            if (unwrap == null)
            {
                return(null);
            }

            Expression res = base.ResolveOperator(ec, unwrap);

            if (res == null)
            {
                Error_OperatorCannotBeApplied(ec, loc, OperName(Oper), Expr.Type);
                return(null);
            }

            if (res != this)
            {
                if (user_operator == null)
                {
                    return(res);
                }
            }
            else
            {
                res = Expr = LiftExpression(ec, Expr);
            }

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

            eclass = ExprClass.Value;
            type   = res.Type;
            return(this);
        }
Пример #2
0
        public override Expression DoResolve(ResolveContext ec)
        {
            if (eclass != ExprClass.Invalid)
            {
                return(this);
            }

            unwrap = Unwrap.Create(Expr, false);
            if (unwrap == null)
            {
                return(null);
            }

            Expression res = base.ResolveOperator(ec, unwrap);

            if (res != this)
            {
                if (user_operator == null)
                {
                    return(res);
                }
            }
            else
            {
                res = Expr = LiftExpression(ec, Expr);
            }

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

            eclass = ExprClass.Value;
            type   = res.Type;
            return(this);
        }
Пример #3
0
        Expression ConvertExpression(ResolveContext ec)
        {
            // TODO: ImplicitConversionExists should take care of this
            if (left.eclass == ExprClass.MethodGroup)
            {
                return(null);
            }

            TypeSpec ltype = left.Type;

            //
            // If left is a nullable type and an implicit conversion exists from right to underlying type of left,
            // the result is underlying type of left
            //
            if (ltype.IsNullableType)
            {
                unwrap = Unwrap.Create(left, false);
                if (unwrap == null)
                {
                    return(null);
                }

                //
                // Reduce (left ?? null) to left
                //
                if (right.IsNull)
                {
                    return(ReducedExpression.Create(left, this));
                }

                Expression conv;
                if (right.Type.IsNullableType)
                {
                    conv = right.Type == ltype ? right : Convert.ImplicitNulableConversion(ec, right, ltype);
                    if (conv != null)
                    {
                        right = conv;
                        type  = ltype;
                        return(this);
                    }
                }
                else
                {
                    conv = Convert.ImplicitConversion(ec, right, unwrap.Type, loc);
                    if (conv != null)
                    {
                        left  = unwrap;
                        ltype = left.Type;

                        //
                        // If right is a dynamic expression, the result type is dynamic
                        //
                        if (right.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
                        {
                            type = right.Type;

                            // Need to box underlying value type
                            left = Convert.ImplicitBoxingConversion(left, ltype, type);
                            return(this);
                        }

                        right = conv;
                        type  = ltype;
                        return(this);
                    }
                }
            }
            else if (TypeSpec.IsReferenceType(ltype))
            {
                if (Convert.ImplicitConversionExists(ec, right, ltype))
                {
                    //
                    // If right is a dynamic expression, the result type is dynamic
                    //
                    if (right.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
                    {
                        type = right.Type;
                        return(this);
                    }

                    //
                    // Reduce ("foo" ?? expr) to expression
                    //
                    Constant lc = left as Constant;
                    if (lc != null && !lc.IsDefaultValue)
                    {
                        return(ReducedExpression.Create(lc, this, false));
                    }

                    //
                    // Reduce (left ?? null) to left OR (null-constant ?? right) to right
                    //
                    if (right.IsNull || lc != null)
                    {
                        //
                        // Special case null ?? null
                        //
                        if (right.IsNull && ltype == right.Type)
                        {
                            return(null);
                        }

                        return(ReducedExpression.Create(lc != null ? right : left, this, false));
                    }

                    right = Convert.ImplicitConversion(ec, right, ltype, loc);
                    type  = ltype;
                    return(this);
                }
            }
            else
            {
                return(null);
            }

            TypeSpec rtype = right.Type;

            if (!Convert.ImplicitConversionExists(ec, unwrap ?? left, rtype) || right.eclass == ExprClass.MethodGroup)
            {
                return(null);
            }

            //
            // Reduce (null ?? right) to right
            //
            if (left.IsNull)
            {
                return(ReducedExpression.Create(right, this, false).Resolve(ec));
            }

            left = Convert.ImplicitConversion(ec, unwrap ?? left, rtype, loc);
            user_conversion_left = left is UserCast;
            type = rtype;
            return(this);
        }
Пример #4
0
        Expression ConvertExpression(ResolveContext ec)
        {
            // TODO: ImplicitConversionExists should take care of this
            if (left.eclass == ExprClass.MethodGroup)
            {
                return(null);
            }

            Type ltype = left.Type;

            //
            // If left is a nullable type and an implicit conversion exists from right to underlying type of left,
            // the result is underlying type of left
            //
            if (TypeManager.IsNullableType(ltype))
            {
                unwrap = Unwrap.Create(left, false);
                if (unwrap == null)
                {
                    return(null);
                }

                if (Convert.ImplicitConversionExists(ec, right, unwrap.Type))
                {
                    left  = unwrap;
                    type  = left.Type;
                    right = Convert.ImplicitConversion(ec, right, type, loc);
                    return(this);
                }
            }
            else if (TypeManager.IsReferenceType(ltype))
            {
                if (Convert.ImplicitConversionExists(ec, right, ltype))
                {
                    //
                    // Reduce (constant ?? expr) to constant
                    //
                    Constant lc = left as Constant;
                    if (lc != null && !lc.IsDefaultValue)
                    {
                        return(new SideEffectConstant(lc, right, loc).Resolve(ec));
                    }

                    //
                    // Reduce (left ?? null) to left OR (null-constant ?? right) to right
                    //
                    if (right.IsNull || lc != null)
                    {
                        return(ReducedExpression.Create(lc != null ? right : left, this).Resolve(ec));
                    }

                    right = Convert.ImplicitConversion(ec, right, ltype, loc);
                    type  = left.Type;
                    return(this);
                }
            }
            else
            {
                return(null);
            }

            Type rtype = right.Type;

            if (!Convert.ImplicitConversionExists(ec, unwrap != null ? unwrap : left, rtype) || right.eclass == ExprClass.MethodGroup)
            {
                return(null);
            }

            //
            // Reduce (null ?? right) to right
            //
            if (left.IsNull)
            {
                return(ReducedExpression.Create(right, this).Resolve(ec));
            }

            left = Convert.ImplicitConversion(ec, unwrap != null ? unwrap : left, rtype, loc);
            type = rtype;
            return(this);
        }