2002-08-06 Martin Baulig <martin@gnome.org>
[mono.git] / mcs / mcs / delegate.cs
index f2d45696f8effc7bbcdd68f446133da5598951cd..11d9cfad90dfac6f5d34d885204777f9ace70b10 100644 (file)
@@ -50,7 +50,9 @@ namespace Mono.CSharp {
                        : base (parent, name, l)\r
                {\r
                        this.ReturnType = type;\r
-                       ModFlags        = Modifiers.Check (AllowedModifiers, mod_flags, Modifiers.PUBLIC, l);\r
+                       ModFlags        = Modifiers.Check (AllowedModifiers, mod_flags,\r
+                                                          IsTopLevel ? Modifiers.INTERNAL :\r
+                                                          Modifiers.PRIVATE, l);\r
                        Parameters      = param_list;\r
                        OptAttributes   = attrs;\r
                }\r
@@ -137,19 +139,29 @@ namespace Mono.CSharp {
                        //\r
                        // Invoke method\r
                        //\r
-                       \r
+\r
                        // Check accessibility\r
                        foreach (Type partype in param_types)\r
-                               if (!TypeContainer.AsAccessible (partype, ModFlags))\r
+                               if (!container.AsAccessible (partype, ModFlags)) {\r
+                                       Report.Error (59, Location,\r
+                                                     "Inconsistent accessibility: parameter type `" +\r
+                                                     TypeManager.CSharpName (partype) + "` is less " +\r
+                                                     "accessible than delegate `" + Name + "'");\r
                                        return false;\r
+                               }\r
                        \r
                        ReturnType = ResolveTypeExpr (ReturnType, false, Location);\r
                        ret_type = ReturnType.Type;\r
                        if (ret_type == null)\r
                                return false;\r
 \r
-                       if (!TypeContainer.AsAccessible (ret_type, ModFlags))\r
+                       if (!container.AsAccessible (ret_type, ModFlags)) {\r
+                               Report.Error (58, Location,\r
+                                             "Inconsistent accessibility: return type `" +\r
+                                             TypeManager.CSharpName (ret_type) + "` is less " +\r
+                                             "accessible than delegate `" + Name + "'");\r
                                return false;\r
+                       }\r
 \r
                        //\r
                        // We don't have to check any others because they are all\r
@@ -315,45 +327,19 @@ namespace Mono.CSharp {
                        if (invoke_pd.Count != pd_count)\r
                                return null;\r
 \r
-                       bool mismatch = false;\r
                        for (int i = pd_count; i > 0; ) {\r
                                i--;\r
 \r
                                if (invoke_pd.ParameterType (i) == pd.ParameterType (i))\r
                                        continue;\r
-                               else {\r
-                                       mismatch = true;\r
-                                       break;\r
-                               }\r
-                       }\r
-\r
-                       if (mismatch) {\r
-                               //\r
-                               // FIXME: This error message is not very useful!\r
-                               //\r
-                               Report.Error (\r
-                                       123, loc, "Method '" + Invocation.FullMethodDesc (mb) +\r
-                                       "' does not match delegate '" +\r
-                                       FullDelegateDesc (delegate_type, invoke_mb, invoke_pd) + "'");\r
-                               return null;\r
+                               else\r
+                                       return null;\r
                        }\r
 \r
                        if (((MethodInfo) invoke_mb).ReturnType == ((MethodInfo) mb).ReturnType)\r
                                return mb;\r
                        else\r
-                               mismatch = true;\r
-\r
-                       if (mismatch) {\r
-                               //\r
-                               // FIXME: This error message is not very useful!\r
-                               //\r
-                               Report.Error (123, loc, "Method '" + Invocation.FullMethodDesc (mb) +\r
-                                             "' does not match delegate '" +\r
-                                             FullDelegateDesc (delegate_type, invoke_mb, invoke_pd) + "'");\r
                                return null;\r
-                       }\r
-\r
-                       return null;\r
                }\r
 \r
                // <summary>\r
@@ -544,57 +530,76 @@ namespace Mono.CSharp {
                MethodBase delegate_method;\r
                Expression delegate_instance_expr;\r
 \r
-               Location Location;\r
-               \r
                public NewDelegate (Type type, ArrayList Arguments, Location loc)\r
                {\r
                        this.type = type;\r
                        this.Arguments = Arguments;\r
-                       this.Location  = loc; \r
+                       this.loc  = loc; \r
                }\r
 \r
                public override Expression DoResolve (EmitContext ec)\r
                {\r
                        if (Arguments == null) {\r
-                               Report.Error (-11, Location,\r
+                               Report.Error (-11, loc,\r
                                              "Delegate creation expression takes only one argument");\r
                                return null;\r
                        }\r
 \r
                        if (Arguments.Count != 1) {\r
-                               Report.Error (-11, Location,\r
+                               Report.Error (-11, loc,\r
                                              "Delegate creation expression takes only one argument");\r
                                return null;\r
                        }\r
 \r
                        Expression ml = Expression.MemberLookup (\r
-                               ec, type, ".ctor", Location);\r
+                               ec, type, ".ctor", loc);\r
 \r
                        if (!(ml is MethodGroupExpr)) {\r
-                               Report.Error (-100, Location, "Internal error : Could not find delegate constructor!");\r
+                               Report.Error (-100, loc, "Internal error : Could not find delegate constructor!");\r
                                return null;\r
                        }\r
 \r
                        constructor_method = ((MethodGroupExpr) ml).Methods [0];\r
                        Argument a = (Argument) Arguments [0];\r
                        \r
-                       if (!a.Resolve (ec, Location))\r
+                       if (!a.ResolveMethodGroup (ec, Location))\r
                                return null;\r
                        \r
                        Expression e = a.Expr;\r
 \r
+                       Expression invoke_method = Expression.MemberLookup (\r
+                               ec, type, "Invoke", MemberTypes.Method,\r
+                               Expression.AllBindingFlags, loc);\r
+\r
+                       if (invoke_method == null) {\r
+                               Report.Error (-200, loc, "Internal error ! COuld not find Invoke method!");\r
+                               return null;\r
+                       }\r
+\r
                        if (e is MethodGroupExpr) {\r
                                MethodGroupExpr mg = (MethodGroupExpr) e;\r
 \r
                                foreach (MethodInfo mi in mg.Methods){\r
-                                       delegate_method  = Delegate.VerifyMethod (ec, type, mi, Location);\r
+                                       delegate_method  = Delegate.VerifyMethod (ec, type, mi, loc);\r
 \r
                                        if (delegate_method != null)\r
                                                break;\r
                                }\r
                                        \r
                                if (delegate_method == null) {\r
-                                       Report.Error (-14, Location, "Ambiguous method reference in delegate creation");\r
+                                       string method_desc;\r
+                                       if (mg.Methods.Length > 1)\r
+                                               method_desc = mg.Methods [0].Name;\r
+                                       else\r
+                                               method_desc = Invocation.FullMethodDesc (mg.Methods [0]);\r
+\r
+                                       MethodBase dm = ((MethodGroupExpr) invoke_method).Methods [0];\r
+                                       ParameterData param = Invocation.GetParameterData (dm);\r
+                                       string delegate_desc = Delegate.FullDelegateDesc (type, dm, param);\r
+\r
+                                       Report.Error (123, loc, "Method '" + method_desc + "' does not " +\r
+                                                     "match delegate '" + delegate_desc + "'");\r
+\r
                                        return null;\r
                                }\r
                                                \r
@@ -618,7 +623,7 @@ namespace Mono.CSharp {
                        Type e_type = e.Type;\r
 \r
                        if (!TypeManager.IsDelegateType (e_type)) {\r
-                               Report.Error (-12, Location, "Cannot create a delegate from something " +\r
+                               Report.Error (-12, loc, "Cannot create a delegate from something " +\r
                                              "not a delegate or a method.");\r
                                return null;\r
                        }\r
@@ -626,20 +631,11 @@ namespace Mono.CSharp {
                        // This is what MS' compiler reports. We could always choose\r
                        // to be more verbose and actually give delegate-level specifics\r
                        \r
-                       if (!Delegate.VerifyDelegate (ec, type, e_type, Location)) {\r
-                               Report.Error (29, Location, "Cannot implicitly convert type '" + e_type + "' " +\r
+                       if (!Delegate.VerifyDelegate (ec, type, e_type, loc)) {\r
+                               Report.Error (29, loc, "Cannot implicitly convert type '" + e_type + "' " +\r
                                              "to type '" + type + "'");\r
                                return null;\r
                        }\r
-\r
-                       Expression invoke_method = Expression.MemberLookup (\r
-                               ec, e_type, "Invoke", MemberTypes.Method,\r
-                               Expression.AllBindingFlags, Location);\r
-\r
-                       if (invoke_method == null) {\r
-                               Report.Error (-200, Location, "Internal error ! COuld not find Invoke method!");\r
-                               return null;\r
-                       }\r
                                \r
                        delegate_instance_expr = e;\r
                        delegate_method        = ((MethodGroupExpr) invoke_method).Methods [0];\r
@@ -665,7 +661,6 @@ namespace Mono.CSharp {
 \r
                public Expression InstanceExpr;\r
                public ArrayList  Arguments;\r
-               public Location   Location;\r
 \r
                MethodBase method;\r
                \r
@@ -673,7 +668,7 @@ namespace Mono.CSharp {
                {\r
                        this.InstanceExpr = instance_expr;\r
                        this.Arguments = args;\r
-                       this.Location = loc;\r
+                       this.loc = loc;\r
                }\r
 \r
                public override Expression DoResolve (EmitContext ec)\r
@@ -684,17 +679,17 @@ namespace Mono.CSharp {
                        \r
                        if (Arguments != null){\r
                                foreach (Argument a in Arguments){\r
-                                       if (!a.Resolve (ec, Location))\r
+                                       if (!a.Resolve (ec, loc))\r
                                                return null;\r
                                }\r
                        }\r
                        \r
-                       if (!Delegate.VerifyApplicability (ec, del_type, Arguments, Location))\r
+                       if (!Delegate.VerifyApplicability (ec, del_type, Arguments, loc))\r
                                return null;\r
 \r
-                       Expression ml = Expression.MemberLookup (ec, del_type, "Invoke", Location);\r
+                       Expression ml = Expression.MemberLookup (ec, del_type, "Invoke", loc);\r
                        if (!(ml is MethodGroupExpr)) {\r
-                               Report.Error (-100, Location, "Internal error : could not find Invoke method!");\r
+                               Report.Error (-100, loc, "Internal error : could not find Invoke method!");\r
                                return null;\r
                        }\r
                        \r
@@ -713,7 +708,7 @@ namespace Mono.CSharp {
                        // Invocation on delegates call the virtual Invoke member\r
                        // so we are always `instance' calls\r
                        //\r
-                       Invocation.EmitCall (ec, false, false, InstanceExpr, method, Arguments, Location);\r
+                       Invocation.EmitCall (ec, false, false, InstanceExpr, method, Arguments, loc);\r
                }\r
 \r
                public override void EmitStatement (EmitContext ec)\r