예제 #1
0
        // <summary>
        //   Resolve is used in method definitions
        // </summary>
        public virtual Type Resolve(IResolveContext ec)
        {
            // HACK: to resolve attributes correctly
            this.resolve_context = ec;

            if (parameter_type != null)
            {
                return(parameter_type);
            }

            TypeExpr texpr = TypeName.ResolveAsTypeTerminal(ec, false);

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

            parameter_type = texpr.Type;

            if ((modFlags & Parameter.Modifier.ISBYREF) != 0 &&
                TypeManager.IsSpecialType(parameter_type))
            {
                Report.Error(1601, Location, "Method or delegate parameter cannot be of type `{0}'",
                             GetSignatureForError());
                return(null);
            }

#if GMCS_SOURCE
            TypeParameterExpr tparam = texpr as TypeParameterExpr;
            if (tparam != null)
            {
                return(parameter_type);
            }
#endif

            if ((parameter_type.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute)
            {
                Report.Error(721, Location, "`{0}': static types cannot be used as parameters",
                             texpr.GetSignatureForError());
                return(parameter_type);
            }

            if ((modFlags & Modifier.This) != 0 && parameter_type.IsPointer)
            {
                Report.Error(1103, Location, "The type of extension method cannot be `{0}'",
                             TypeManager.CSharpName(parameter_type));
            }

            return(parameter_type);
        }
예제 #2
0
        // <summary>
        //   Resolve is used in method definitions
        // </summary>
        public virtual Type Resolve(IMemberContext rc)
        {
            if (parameter_type != null)
            {
                return(parameter_type);
            }

            if (attributes != null)
            {
                attributes.AttachTo(this, rc);
            }

            TypeExpr texpr = TypeName.ResolveAsTypeTerminal(rc, false);

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

            parameter_type = texpr.Type;

            // Ignore all checks for dummy members
            AbstractPropertyEventMethod pem = rc as AbstractPropertyEventMethod;

            if (pem != null && pem.IsDummy)
            {
                return(parameter_type);
            }

            if (default_expr != null)
            {
                ResolveContext ec = new ResolveContext(rc);
                default_expr = default_expr.Resolve(ec);
                if (default_expr != null)
                {
                    Constant value = default_expr as Constant;
                    if (value == null)
                    {
                        if (default_expr != null)
                        {
                            bool is_valid = false;
                            if (default_expr is DefaultValueExpression)
                            {
                                is_valid = true;
                            }
                            else if (default_expr is New && ((New)default_expr).IsDefaultValueType)
                            {
                                is_valid = TypeManager.IsEqual(parameter_type, default_expr.Type) ||
                                           (TypeManager.IsNullableType(parameter_type) &&
                                            Convert.ImplicitNulableConversion(ec, default_expr, parameter_type) != EmptyExpression.Null);
                            }
                            else
                            {
                                rc.Compiler.Report.Error(1736, default_expr.Location,
                                                         "The expression being assigned to optional parameter `{0}' must be a constant or default value",
                                                         Name);
                                is_valid = true;
                            }

                            if (!is_valid)
                            {
                                default_expr = null;
                                ec.Compiler.Report.Error(1763, Location,
                                                         "Optional parameter `{0}' of type `{1}' can only be initialized with `null'",
                                                         Name, GetSignatureForError());
                            }
                        }
                    }
                    else
                    {
                        Constant c = value.ConvertImplicitly(parameter_type);
                        if (c == null)
                        {
                            if (parameter_type == TypeManager.object_type)
                            {
                                rc.Compiler.Report.Error(1763, Location,
                                                         "Optional parameter `{0}' of type `{1}' can only be initialized with `null'",
                                                         Name, GetSignatureForError());
                            }
                            else
                            {
                                rc.Compiler.Report.Error(1750, Location,
                                                         "Optional parameter value `{0}' cannot be converted to parameter type `{1}'",
                                                         value.GetValue(), GetSignatureForError());
                            }
                            default_expr = null;
                        }
                    }
                }
            }

            if ((modFlags & Parameter.Modifier.ISBYREF) != 0 &&
                TypeManager.IsSpecialType(parameter_type))
            {
                rc.Compiler.Report.Error(1601, Location, "Method or delegate parameter cannot be of type `{0}'",
                                         GetSignatureForError());
                return(null);
            }

            TypeManager.CheckTypeVariance(parameter_type,
                                          (modFlags & Parameter.Modifier.ISBYREF) != 0 ? Variance.None : Variance.Contravariant,
                                          rc);

            if (TypeManager.IsGenericParameter(parameter_type))
            {
                return(parameter_type);
            }

            if ((parameter_type.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute)
            {
                rc.Compiler.Report.Error(721, Location, "`{0}': static types cannot be used as parameters",
                                         texpr.GetSignatureForError());
                return(parameter_type);
            }

            if ((modFlags & Modifier.This) != 0 && (parameter_type.IsPointer || TypeManager.IsDynamicType(parameter_type)))
            {
                rc.Compiler.Report.Error(1103, Location, "The extension method cannot be of type `{0}'",
                                         TypeManager.CSharpName(parameter_type));
            }

            return(parameter_type);
        }