updated the demo application
[mono.git] / mcs / mcs / delegate.cs
index 1009199ddf26b3ee53f6cb880232b5b233196b58..4ccfd496c878f5a9ba1e3a696d3f7face8392d2c 100644 (file)
@@ -1,7 +1,9 @@
 //\r
 // delegate.cs: Delegate Handler\r
 //\r
-// Author: Ravi Pratap (ravi@ximian.com)\r
+// Authors:\r
+//     Ravi Pratap (ravi@ximian.com)\r
+//     Miguel de Icaza (miguel@ximian.com)\r
 //\r
 // Licensed under the terms of the GNU GPL\r
 //\r
@@ -65,6 +67,9 @@ namespace Mono.CSharp {
                                return TypeBuilder;\r
                        \r
                        if (IsTopLevel) {\r
+                               if (TypeManager.NamespaceClash (Name))\r
+                                       return null;\r
+                               \r
                                ModuleBuilder builder = CodeGen.ModuleBuilder;\r
                                attr = TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Sealed;\r
 \r
@@ -146,7 +151,7 @@ namespace Mono.CSharp {
                        //\r
 \r
                        // Check accessibility\r
-                       foreach (Type partype in param_types)\r
+                       foreach (Type partype in param_types){\r
                                if (!container.AsAccessible (partype, ModFlags)) {\r
                                        Report.Error (59, Location,\r
                                                      "Inconsistent accessibility: parameter type `" +\r
@@ -154,6 +159,9 @@ namespace Mono.CSharp {
                                                      "accessible than delegate `" + Name + "'");\r
                                        return false;\r
                                }\r
+                               if (partype.IsPointer && !UnsafeOK (container))\r
+                                       return false;\r
+                       }\r
                        \r
                        ReturnType = ResolveTypeExpr (ReturnType, false, Location);\r
                        ret_type = ReturnType.Type;\r
@@ -168,6 +176,9 @@ namespace Mono.CSharp {
                                return false;\r
                        }\r
 \r
+                       if (ret_type.IsPointer && !UnsafeOK (container))\r
+                               return false;\r
+\r
                        //\r
                        // We don't have to check any others because they are all\r
                        // guaranteed to be accessible - they are standard types.\r
@@ -183,6 +194,10 @@ namespace Mono.CSharp {
                                                                  ret_type,                  \r
                                                                  param_types);\r
 \r
+                       //\r
+                       // Define parameters, and count out/ref parameters\r
+                       //\r
+                       int out_params = 0;\r
                        i = 0;\r
                        if (Parameters.FixedParameters != null){\r
                                int top = Parameters.FixedParameters.Length;\r
@@ -190,9 +205,10 @@ namespace Mono.CSharp {
                                \r
                                for (; i < top; i++) {\r
                                        p = Parameters.FixedParameters [i];\r
+                                       InvokeBuilder.DefineParameter (i+1, p.Attributes, p.Name);\r
 \r
-                                       InvokeBuilder.DefineParameter (\r
-                                               i+1, p.Attributes, p.Name);\r
+                                       if ((p.ModFlags & Parameter.Modifier.ISBYREF) != 0)\r
+                                               out_params++;\r
                                }\r
                        }\r
                        if (Parameters.ArrayParameter != null){\r
@@ -236,15 +252,13 @@ namespace Mono.CSharp {
                                for (i = 0 ; i < top; i++) {\r
                                        p = Parameters.FixedParameters [i];\r
 \r
-                                       BeginInvokeBuilder.DefineParameter (\r
-                                               i+1, p.Attributes, p.Name);\r
+                                       BeginInvokeBuilder.DefineParameter (i+1, p.Attributes, p.Name);\r
                                }\r
                        }\r
                        if (Parameters.ArrayParameter != null){\r
                                Parameter p = Parameters.ArrayParameter;\r
                                \r
-                               BeginInvokeBuilder.DefineParameter (\r
-                                       i+1, p.Attributes, p.Name);\r
+                               BeginInvokeBuilder.DefineParameter (i+1, p.Attributes, p.Name);\r
                                i++;\r
                        }\r
 \r
@@ -270,6 +284,7 @@ namespace Mono.CSharp {
                                                                   Parameter.Modifier.NONE, null);\r
 \r
                        Parameters async_parameters = new Parameters (async_params, null, Location);\r
+                       async_parameters.ComputeAndDefineParameterTypes (this);\r
                        \r
                        async_parameters.ComputeAndDefineParameterTypes (this);\r
                        TypeManager.RegisterMethod (BeginInvokeBuilder,\r
@@ -277,31 +292,49 @@ namespace Mono.CSharp {
                                                    async_param_types);\r
 \r
                        //\r
-                       // EndInvoke\r
+                       // EndInvoke is a bit more interesting, all the parameters labeled as\r
+                       // out or ref have to be duplicated here.\r
                        //\r
-                       Type [] end_param_types = new Type [1];\r
-                       end_param_types [0] = TypeManager.iasyncresult_type;\r
-                       \r
-                       EndInvokeBuilder = TypeBuilder.DefineMethod ("EndInvoke",\r
-                                                                    mattr,\r
-                                                                    cc,\r
-                                                                    ret_type,\r
-                                                                    end_param_types);\r
-                       EndInvokeBuilder.DefineParameter (1, ParameterAttributes.None, "result");\r
                        \r
+                       Type [] end_param_types = new Type [out_params + 1];\r
+                       Parameter [] end_params = new Parameter [out_params + 1];\r
+                       int param = 0; \r
+                       if (out_params > 0){\r
+                               int top = Parameters.FixedParameters.Length;\r
+                               for (i = 0; i < top; i++){\r
+                                       Parameter p = Parameters.FixedParameters [i];\r
+                                       if ((p.ModFlags & Parameter.Modifier.ISBYREF) == 0)\r
+                                               continue;\r
+\r
+                                       end_param_types [param] = param_types [i];\r
+                                       end_params [param] = p;\r
+                                       param++;\r
+                               }\r
+                       }\r
+                       end_param_types [out_params] = TypeManager.iasyncresult_type;\r
+                       end_params [out_params] = new Parameter (TypeManager.system_iasyncresult_expr, "result", Parameter.Modifier.NONE, null);\r
+\r
+                       //\r
+                       // Create method, define parameters, register parameters with type system\r
+                       //\r
+                       EndInvokeBuilder = TypeBuilder.DefineMethod ("EndInvoke", mattr, cc, ret_type, end_param_types);\r
                        EndInvokeBuilder.SetImplementationFlags (MethodImplAttributes.Runtime);\r
 \r
-                       Parameter [] end_params = new Parameter [1];\r
-                       end_params [0] = new Parameter (\r
-                               TypeManager.system_iasyncresult_expr, "result",\r
-                                                       Parameter.Modifier.NONE, null);\r
+                       //\r
+                       // EndInvoke: Label the parameters\r
+                       //\r
+                       EndInvokeBuilder.DefineParameter (out_params + 1, ParameterAttributes.None, "result");\r
+                       for (i = 0; i < end_params.Length-1; i++){\r
+                               EndInvokeBuilder.DefineParameter (i + 1, end_params [i].Attributes, end_params [i].Name);\r
+                       }\r
+\r
+                       Parameters end_parameters = new Parameters (end_params, null, Location);\r
+                       end_parameters.ComputeAndDefineParameterTypes (this);\r
 \r
                        TypeManager.RegisterMethod (\r
-                               EndInvokeBuilder, new InternalParameters (\r
-                                       container,\r
-                                       new Parameters (\r
-                                               end_params, null, Location)),\r
-                                                   end_param_types);\r
+                               EndInvokeBuilder,\r
+                               new InternalParameters (container, end_parameters),\r
+                               end_param_types);\r
 \r
                        return true;\r
                }\r
@@ -338,8 +371,9 @@ namespace Mono.CSharp {
                                if (invoke_pd.ParameterType (i) == pd.ParameterType (i) &&\r
                                    invoke_pd.ParameterModifier (i) == pd.ParameterModifier (i))\r
                                        continue;\r
-                               else\r
+                               else {\r
                                        return null;\r
+                               }\r
                        }\r
 \r
                        if (((MethodInfo) invoke_mb).ReturnType == ((MethodInfo) mb).ReturnType)\r
@@ -447,8 +481,8 @@ namespace Mono.CSharp {
                        \r
                        for (int i = length; i > 0; ) {\r
                                i--;\r
-                               \r
-                               sb.Append (TypeManager.CSharpName (pd.ParameterType (length - i - 1)));\r
+\r
+                               sb.Append (pd.ParameterDesc (length - i - 1));\r
                                if (i != 0)\r
                                        sb.Append (", ");\r
                        }\r
@@ -540,15 +574,9 @@ namespace Mono.CSharp {
 \r
                public override Expression DoResolve (EmitContext ec)\r
                {\r
-                       if (Arguments == null) {\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, loc,\r
-                                             "Delegate creation expression takes only one argument");\r
+                       if (Arguments == null || Arguments.Count != 1) {\r
+                               Report.Error (149, loc,\r
+                                             "Method name expected");\r
                                return null;\r
                        }\r
 \r
@@ -622,10 +650,16 @@ namespace Mono.CSharp {
                                if (mg.InstanceExpression != null)\r
                                        delegate_instance_expr = mg.InstanceExpression.Resolve (ec);\r
                                else {\r
-                                       if (!ec.IsStatic)\r
-                                               delegate_instance_expr = ec.This;\r
-                                       else\r
+                                       if (ec.IsStatic){\r
+                                               if (!delegate_method.IsStatic){\r
+                                                       Report.Error (120, loc,\r
+                                                                     "An object reference is required for the non-static method " +\r
+                                                                     delegate_method.Name);\r
+                                                       return null;\r
+                                               }\r
                                                delegate_instance_expr = null;\r
+                                       } else\r
+                                               delegate_instance_expr = ec.This;\r
                                }\r
 \r
                                if (delegate_instance_expr != null)\r
@@ -639,8 +673,7 @@ namespace Mono.CSharp {
                        Type e_type = e.Type;\r
 \r
                        if (!TypeManager.IsDelegateType (e_type)) {\r
-                               Report.Error (-12, loc, "Cannot create a delegate from something " +\r
-                                             "not a delegate or a method.");\r
+                               e.Error_UnexpectedKind ("method");\r
                                return null;\r
                        }\r
 \r