2002-09-03 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[mono.git] / mcs / mbas / support.cs
index e0a1c69dacda459d8db41630cde25320f619a110..3db32ac9da6489dabdf8413799d523126a93821f 100644 (file)
-//\r
-// support.cs: Support routines to work around the fact that System.Reflection.Emit\r
-// can not introspect types that are being constructed\r
-//\r
-// Author:\r
-//   Miguel de Icaza (miguel@ximian.com)\r
-//\r
-// (C) 2001 Ximian, Inc (http://www.ximian.com)\r
-//\r
-\r
-using System;\r
-using System.Text;\r
-using System.Reflection;\r
-using System.Collections;\r
-using System.Reflection.Emit;\r
-\r
-namespace Mono.CSharp {\r
-\r
-       public interface ParameterData {\r
-               Type ParameterType (int pos);\r
-               int  Count { get; }\r
-               string ParameterDesc (int pos);\r
-               Parameter.Modifier ParameterModifier (int pos);\r
-       }\r
-\r
-       public class ReflectionParameters : ParameterData {\r
-               ParameterInfo [] pi;\r
-               bool last_arg_is_params;\r
-               \r
-               public ReflectionParameters (ParameterInfo [] pi)\r
-               {\r
-                       object [] a;\r
-                       \r
-                       this.pi = pi;\r
-\r
-                       int count = pi.Length-1;\r
-\r
-                       if (count > 0) {\r
-                               a = pi [count].GetCustomAttributes (TypeManager.param_array_type, false);\r
-\r
-                               if (a != null)\r
-                                       if (a.Length != 0)\r
-                                               last_arg_is_params = true;\r
-                       } \r
-               }\r
-                      \r
-               public Type ParameterType (int pos)\r
-               {\r
-                       if (last_arg_is_params && pos >= pi.Length - 1)\r
-                               return pi [pi.Length -1].ParameterType;\r
-                       else \r
-                               return pi [pos].ParameterType;\r
-               }\r
-\r
-               public string ParameterDesc (int pos)\r
-               {\r
-                       StringBuilder sb = new StringBuilder ();\r
-\r
-                       if (pi [pos].IsOut)\r
-                               sb.Append ("out ");\r
-\r
-                       if (pi [pos].IsIn)\r
-                               sb.Append ("in ");\r
-\r
-                       if (pos >= pi.Length - 1 && last_arg_is_params)\r
-                               sb.Append ("params ");\r
-                       \r
-                       sb.Append (TypeManager.CSharpName (ParameterType (pos)));\r
-\r
-                       return sb.ToString ();\r
-                       \r
-               }\r
-\r
-               public Parameter.Modifier ParameterModifier (int pos)\r
-               {\r
-                       if (pos >= pi.Length - 1) \r
-                               if (last_arg_is_params)\r
-                                       return Parameter.Modifier.PARAMS;\r
-\r
-                       Type t = pi [pos].ParameterType;\r
-                       if (t.IsByRef)\r
-                               return Parameter.Modifier.OUT;\r
-                       \r
-                       return Parameter.Modifier.NONE;\r
-               }\r
-\r
-               public int Count {\r
-                       get {\r
-                               return pi.Length;\r
-                       }\r
-               }\r
-               \r
-       }\r
-\r
-       public class InternalParameters : ParameterData {\r
-               Type [] param_types;\r
-\r
-               Parameters parameters;\r
-               \r
-               public InternalParameters (Type [] param_types, Parameters parameters)\r
-               {\r
-                       this.param_types = param_types;\r
-                       this.parameters = parameters;\r
-               }\r
-\r
-               public InternalParameters (TypeContainer tc, Parameters parameters)\r
-                       : this (parameters.GetParameterInfo (tc), parameters)\r
-               {\r
-               }\r
-\r
-               public int Count {\r
-                       get {\r
-                               if (param_types == null)\r
-                                       return 0;\r
-\r
-                               return param_types.Length;\r
-                       }\r
-               }\r
-\r
-               public Type ParameterType (int pos)\r
-               {\r
-                       if (param_types == null)\r
-                               return null;\r
-\r
-                       Parameter [] fixed_pars = parameters.FixedParameters;\r
-                       if (fixed_pars != null){\r
-                               int len = fixed_pars.Length;\r
-                               if (pos < len)\r
-                                       return parameters.FixedParameters [pos].ParameterType;\r
-                               else \r
-                                       return parameters.ArrayParameter.ParameterType;\r
-                       } else\r
-                               return parameters.ArrayParameter.ParameterType;\r
-               }\r
-\r
-               public string ParameterDesc (int pos)\r
-               {\r
-                       string tmp = null;\r
-                       Parameter p;\r
-\r
-                       if (pos >= parameters.FixedParameters.Length)\r
-                               p = parameters.ArrayParameter;\r
-                       else\r
-                               p = parameters.FixedParameters [pos];\r
-                       \r
-                       if (p.ModFlags == Parameter.Modifier.REF)\r
-                               tmp = "ref ";\r
-                       else if (p.ModFlags == Parameter.Modifier.OUT)\r
-                               tmp = "out ";\r
-                       else if (p.ModFlags == Parameter.Modifier.PARAMS)\r
-                               tmp = "params ";\r
-\r
-                       Type t = ParameterType (pos);\r
-\r
-                       return tmp + TypeManager.CSharpName (t);\r
-               }\r
-\r
-               public Parameter.Modifier ParameterModifier (int pos)\r
-               {\r
-                       if (parameters.FixedParameters == null)\r
-                               return parameters.ArrayParameter.ModFlags;\r
-                       \r
-                       if (pos >= parameters.FixedParameters.Length)\r
-                               return parameters.ArrayParameter.ModFlags;\r
-                       else {\r
-                               Parameter.Modifier m = parameters.FixedParameters [pos].ModFlags;\r
-\r
-                               //\r
-                               // We use a return value of "OUT" for "reference" parameters.\r
-                               // both out and ref flags in the source map to reference parameters.\r
-                               //\r
-                               if (m == Parameter.Modifier.OUT || m == Parameter.Modifier.REF)\r
-                                       return Parameter.Modifier.OUT;\r
-                               \r
-                               return Parameter.Modifier.NONE;\r
-                       }\r
-               }\r
-               \r
-       }\r
-\r
-       class PtrHashtable : Hashtable {\r
-               class PtrComparer : IComparer {\r
-                       public int Compare (object x, object y)\r
-                       {\r
-                               if (x == y)\r
-                                       return 0;\r
-                               else\r
-                                       return 1;\r
-                       }\r
-               }\r
-               \r
-               public PtrHashtable ()\r
-               {\r
-                       comparer = new PtrComparer ();\r
-               }\r
-       }\r
-\r
-       //\r
-       // Compares member infos based on their name and\r
-       // also allows one argument to be a string\r
-       //\r
-       class MemberInfoCompare : IComparer {\r
-\r
-               public int Compare (object a, object b)\r
-               {\r
-                       if (a == null || b == null){\r
-                               Console.WriteLine ("Invalid information passed");\r
-                               throw new Exception ();\r
-                       }\r
-                       \r
-                       if (a is string)\r
-                               return String.Compare ((string) a, ((MemberInfo)b).Name);\r
-\r
-                       if (b is string)\r
-                               return String.Compare (((MemberInfo)a).Name, (string) b);\r
-\r
-                       return String.Compare (((MemberInfo)a).Name, ((MemberInfo)b).Name);\r
-               }\r
-       }\r
-\r
-       struct Pair {\r
-               public object First;\r
-               public object Second;\r
-               \r
-               public Pair (object f, object s)\r
-               {\r
-                       First = f;\r
-                       Second = s;\r
-               }\r
-       }\r
-}\r
+//
+// support.cs: Support routines to work around the fact that System.Reflection.Emit
+// can not introspect types that are being constructed
+//
+// Author:
+//   Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc (http://www.ximian.com)
+//
+
+using System;
+using System.Text;
+using System.Reflection;
+using System.Collections;
+using System.Reflection.Emit;
+using System.Globalization;
+
+namespace Mono.CSharp {
+
+       public interface ParameterData {
+               Type ParameterType (int pos);
+               int  Count { get; }
+               string ParameterName (int pos);
+               string ParameterDesc (int pos);
+               Parameter.Modifier ParameterModifier (int pos);
+       }
+
+       public class ReflectionParameters : ParameterData {
+               ParameterInfo [] pi;
+               bool last_arg_is_params = false;
+               
+               public ReflectionParameters (ParameterInfo [] pi)
+               {
+                       object [] attrs;
+                       
+                       this.pi = pi;
+
+                       int count = pi.Length-1;
+
+                       if (count >= 0) {
+                               attrs = pi [count].GetCustomAttributes (TypeManager.param_array_type, true);
+
+                               if (attrs == null)
+                                       return;
+                               
+                               if (attrs.Length == 0)
+                                       return;
+
+                               last_arg_is_params = true;
+                       }
+               }
+                      
+               public Type ParameterType (int pos)
+               {
+                       if (last_arg_is_params && pos >= pi.Length - 1)
+                               return pi [pi.Length - 1].ParameterType;
+                       else 
+                               return pi [pos].ParameterType;
+               }
+
+               public string ParameterName (int pos)
+               {
+                       if (last_arg_is_params && pos >= pi.Length - 1)
+                               return pi [pi.Length - 1].Name;
+                       else 
+                               return pi [pos].Name;
+               }
+
+               public string ParameterDesc (int pos)
+               {
+                       StringBuilder sb = new StringBuilder ();
+
+                       if (pi [pos].IsOut)
+                               sb.Append ("out ");
+
+                       if (pi [pos].IsIn)
+                               sb.Append ("in ");
+
+                       if (pos >= pi.Length - 1 && last_arg_is_params)
+                               sb.Append ("params ");
+                       
+                       sb.Append (TypeManager.CSharpName (ParameterType (pos)));
+
+                       return sb.ToString ();
+                       
+               }
+
+               public Parameter.Modifier ParameterModifier (int pos)
+               {
+                       int len = pi.Length;
+                       
+                       if (pos >= len - 1)
+                               if (last_arg_is_params)
+                                       return Parameter.Modifier.PARAMS;
+                       
+                       Type t = pi [pos].ParameterType;
+                       if (t.IsByRef)
+                               return Parameter.Modifier.ISBYREF;
+                       
+                       return Parameter.Modifier.NONE;
+               }
+
+               public int Count {
+                       get {
+                               return pi.Length;
+                       }
+               }
+               
+       }
+
+       public class InternalParameters : ParameterData {
+               Type [] param_types;
+
+               public readonly Parameters Parameters;
+               
+               public InternalParameters (Type [] param_types, Parameters parameters)
+               {
+                       this.param_types = param_types;
+                       this.Parameters = parameters;
+               }
+
+               public InternalParameters (DeclSpace ds, Parameters parameters)
+                       : this (parameters.GetParameterInfo (ds), parameters)
+               {
+               }
+
+               public int Count {
+                       get {
+                               if (param_types == null)
+                                       return 0;
+
+                               return param_types.Length;
+                       }
+               }
+
+               public Type ParameterType (int pos)
+               {
+                       if (param_types == null)
+                               return null;
+
+                       Parameter [] fixed_pars = Parameters.FixedParameters;
+                       if (fixed_pars != null){
+                               int len = fixed_pars.Length;
+                               if (pos < len)
+                                       return Parameters.FixedParameters [pos].ParameterType;
+                               else 
+                                       return Parameters.ArrayParameter.ParameterType;
+                       } else
+                               return Parameters.ArrayParameter.ParameterType;
+               }
+
+               public string ParameterName (int pos)
+               {
+                       Parameter p;
+
+                       if (pos >= Parameters.FixedParameters.Length)
+                               p = Parameters.ArrayParameter;
+                       else
+                               p = Parameters.FixedParameters [pos];
+
+                       return p.Name;
+               }
+
+               public string ParameterDesc (int pos)
+               {
+                       string tmp = String.Empty;
+                       Parameter p;
+
+                       if (pos >= Parameters.FixedParameters.Length)
+                               p = Parameters.ArrayParameter;
+                       else
+                               p = Parameters.FixedParameters [pos];
+                       
+                       if (p.ModFlags == Parameter.Modifier.REF)
+                               tmp = "ref ";
+                       else if (p.ModFlags == Parameter.Modifier.OUT)
+                               tmp = "out ";
+                       else if (p.ModFlags == Parameter.Modifier.PARAMS)
+                               tmp = "params ";
+
+                       Type t = ParameterType (pos);
+
+                       return tmp + TypeManager.CSharpName (t);
+               }
+
+               public Parameter.Modifier ParameterModifier (int pos)
+               {
+                       Parameter.Modifier mod;
+
+                       if (Parameters.FixedParameters == null) {
+                               if (Parameters.ArrayParameter != null) 
+                                       mod = Parameters.ArrayParameter.ModFlags;
+                               else
+                                       mod = Parameter.Modifier.NONE;
+                       } else if (pos >= Parameters.FixedParameters.Length)
+                               mod = Parameters.ArrayParameter.ModFlags;
+                       else
+                               mod = Parameters.FixedParameters [pos].ModFlags;
+
+                       if ((mod & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) != 0)
+                               mod |= Parameter.Modifier.ISBYREF;
+
+                       return mod;
+               }
+               
+       }
+
+       class PtrHashtable : Hashtable {
+               class PtrComparer : IComparer {
+                       public int Compare (object x, object y)
+                       {
+                               if (x == y)
+                                       return 0;
+                               else
+                                       return 1;
+                       }
+               }
+               
+               public PtrHashtable ()
+               {
+                       comparer = new PtrComparer ();
+               }
+       }
+
+       //
+       // Compares member infos based on their name and
+       // also allows one argument to be a string
+       //
+       class MemberInfoCompare : IComparer {
+
+               public int Compare (object a, object b)
+               {
+                       if (a == null || b == null){
+                               Console.WriteLine ("Invalid information passed");
+                               throw new Exception ();
+                       }
+                       
+                       if (a is string)
+                               return String.Compare ((string) a, ((MemberInfo)b).Name);
+
+                       if (b is string)
+                               return String.Compare (((MemberInfo)a).Name, (string) b);
+
+                       return String.Compare (((MemberInfo)a).Name, ((MemberInfo)b).Name);
+               }
+       }
+
+       struct Pair {
+               public object First;
+               public object Second;
+               
+               public Pair (object f, object s)
+               {
+                       First = f;
+                       Second = s;
+               }
+       }
+}