protected override bool DoDefineMembers()
        {
            var builtin_types = Compiler.BuiltinTypes;

            var ctor_parameters = ParametersCompiled.CreateFullyResolved(
                new [] {
                new Parameter(new TypeExpression(builtin_types.Object, Location), "object", Parameter.Modifier.NONE, null, Location),
                new Parameter(new TypeExpression(builtin_types.IntPtr, Location), "method", Parameter.Modifier.NONE, null, Location)
            },
                new [] {
                builtin_types.Object,
                builtin_types.IntPtr
            }
                );

            Constructor = new Constructor(this, Constructor.ConstructorName,
                                          Modifiers.PUBLIC, null, ctor_parameters, Location);
            Constructor.Define();

            //
            // Here the various methods like Invoke, BeginInvoke etc are defined
            //
            // First, call the `out of band' special method for
            // defining recursively any types we need:
            //
            var p = parameters;

            if (!p.Resolve(this))
            {
                return(false);
            }

            //
            // Invoke method
            //

            // Check accessibility
            foreach (var partype in p.Types)
            {
                if (!IsAccessibleAs(partype))
                {
                    Report.SymbolRelatedToPreviousError(partype);
                    Report.Error(59, Location,
                                 "Inconsistent accessibility: parameter type `{0}' is less accessible than delegate `{1}'",
                                 TypeManager.CSharpName(partype), GetSignatureForError());
                }
            }

            var ret_type = ReturnType.ResolveAsType(this);

            if (ret_type == null)
            {
                return(false);
            }

            //
            // We don't have to check any others because they are all
            // guaranteed to be accessible - they are standard types.
            //
            if (!IsAccessibleAs(ret_type))
            {
                Report.SymbolRelatedToPreviousError(ret_type);
                Report.Error(58, Location,
                             "Inconsistent accessibility: return type `" +
                             TypeManager.CSharpName(ret_type) + "' is less " +
                             "accessible than delegate `" + GetSignatureForError() + "'");
                return(false);
            }

            CheckProtectedModifier();

            if (Compiler.Settings.StdLib && ret_type.IsSpecialRuntimeType)
            {
                Method.Error1599(Location, ret_type, Report);
                return(false);
            }

            TypeManager.CheckTypeVariance(ret_type, Variance.Covariant, this);

            var resolved_rt = new TypeExpression(ret_type, Location);

            InvokeBuilder = new Method(this, resolved_rt, MethodModifiers, new MemberName(InvokeMethodName), p, null);
            InvokeBuilder.Define();

            //
            // Don't emit async method for compiler generated delegates (e.g. dynamic site containers)
            //
            if (!IsCompilerGenerated)
            {
                DefineAsyncMethods(Parameters.CallingConvention, resolved_rt);
            }

            return(true);
        }
Beispiel #2
0
        public virtual Type Resolve(ParseContext rc)
        {
            if (ParameterType != null)
            {
                return(ParameterType);
            }

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

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

            ParameterType = texpr.Type;

            // Ignore all checks for dummy members
            if (DefaultValue != null)
            {
                DefaultValue = DefaultValue.Resolve(rc);
                if (DefaultValue != null)
                {
                    var value = DefaultValue as ConstantExpression;
                    if (value == null)
                    {
                        if (DefaultValue != null)
                        {
                            bool isValid;
                            if (DefaultValue is DefaultValueExpression)
                            {
                                isValid = true;
                            }
                            else if (DefaultValue is NewExpression && ((NewExpression)DefaultValue).IsDefaultValueType)
                            {
                                isValid = TypeManager.IsEqual(ParameterType, DefaultValue.Type) ||
                                          (TypeManager.IsNullableType(ParameterType) &&
                                           ConvertExpression.ImplicitNullableConversion(
                                               rc, DefaultValue, ParameterType) != EmptyExpression.Null);
                            }
                            else
                            {
                                rc.ReportError(
                                    1736,
                                    string.Format(
                                        "The expression being assigned to optional parameter '{0}' must be a constant or default value.",
                                        Name),
                                    DefaultValue.Span);
                                isValid = true;
                            }

                            if (!isValid)
                            {
                                DefaultValue = null;
                                rc.ReportError(
                                    1763,
                                    string.Format(
                                        "Optional parameter '{0}' of type `{1}' can only be initialized with 'null'.",
                                        Name,
                                        GetSignatureForError()),
                                    Span);
                            }
                        }
                    }
                    else
                    {
                        var c = value.ConvertImplicitly(ParameterType);
                        if (c == null)
                        {
                            if (ParameterType == TypeManager.CoreTypes.Object)
                            {
                                rc.ReportError(
                                    1763,
                                    string.Format(
                                        "Optional parameter '{0}' of type '{1}' can only be initialized with 'null'.",
                                        Name,
                                        GetSignatureForError()),
                                    Span);
                            }
                            else
                            {
                                rc.ReportError(
                                    1750,
                                    string.Format(
                                        "Optional parameter value '{0}' cannot be converted to parameter type '{1}'.",
                                        value.Value,
                                        GetSignatureForError()),
                                    Span);
                            }
                            DefaultValue = null;
                        }
                    }
                }
            }

            if ((_modifierFlags & Modifier.IsByRef) != 0 &&
                TypeManager.IsSpecialType(ParameterType))
            {
                rc.ReportError(
                    1601,
                    string.Format(
                        "Method or delegate parameter cannot be of type '{0}'.",
                        GetSignatureForError()),
                    Span);
                return(null);
            }

            TypeManager.CheckTypeVariance(
                ParameterType,
                (_modifierFlags & Modifier.IsByRef) != 0 ? Variance.None : Variance.Contravariant,
                rc);

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

            if ((_modifierFlags & Modifier.This) != 0 &&
                (ParameterType.IsPointer || TypeManager.IsDynamicType(ParameterType)))
            {
                rc.ReportError(
                    1103,
                    string.Format(
                        "The extension method cannot be of type '{0}'.",
                        TypeManager.GetCSharpName(ParameterType)),
                    Span);
            }

            return(ParameterType);
        }