2 // support.cs: Support routines to work around the fact that System.Reflection.Emit
3 // can not introspect types that are being constructed
6 // Miguel de Icaza (miguel@ximian.com)
8 // (C) 2001 Ximian, Inc (http://www.ximian.com)
13 using System.Reflection;
14 using System.Collections;
15 using System.Reflection.Emit;
16 using System.Globalization;
18 namespace Mono.MonoBASIC {
20 public interface ParameterData {
21 Type ParameterType (int pos);
23 string ParameterName (int pos);
24 string ParameterDesc (int pos);
25 Expression DefaultValue (int pos);
26 Parameter.Modifier ParameterModifier (int pos);
29 public class ReflectionParameters : ParameterData {
31 bool last_arg_is_params = false;
33 public ReflectionParameters (ParameterInfo [] pi)
39 int count = pi.Length-1;
42 attrs = pi [count].GetCustomAttributes (TypeManager.param_array_type, true);
47 if (attrs.Length == 0)
50 last_arg_is_params = true;
54 public Type ParameterType (int pos)
56 if (last_arg_is_params && pos >= pi.Length - 1)
57 return pi [pi.Length - 1].ParameterType;
62 Type pt = pi [pos].ParameterType;
64 pt = pt.GetElementType();
69 public Expression DefaultValue (int pos)
71 if (pi [pos].DefaultValue == null)
72 return NullLiteral.Null;
73 Type type = pi [pos].DefaultValue.GetType();
76 // TODO : Enum is not handled here since ParameterInfo
77 // is not returning correct Data type for Enum
79 switch (Type.GetTypeCode(type)){
81 return new ByteConstant ((byte) pi [pos].DefaultValue);
83 return new CharConstant ((char) pi [pos].DefaultValue);
85 return new StringConstant ((string) pi [pos].DefaultValue);
87 return new ShortConstant ((short) pi [pos].DefaultValue);
89 return new UShortConstant ((ushort) pi [pos].DefaultValue);
91 return new IntConstant ((int) pi [pos].DefaultValue);
93 return new UIntConstant ((uint) pi [pos].DefaultValue);
95 return new LongConstant ((long) pi [pos].DefaultValue);
97 return new ULongConstant ((ulong) pi [pos].DefaultValue);
98 case TypeCode.Boolean:
99 return new BoolConstant ((bool) pi [pos].DefaultValue);
100 case TypeCode.DateTime:
101 return new DateConstant ((DateTime) pi [pos].DefaultValue);
102 case TypeCode.Decimal:
103 return new DecimalConstant ((decimal) pi [pos].DefaultValue);
104 case TypeCode.Double:
105 return new DoubleConstant ((double) pi [pos].DefaultValue);
107 return new SByteConstant ((sbyte) pi [pos].DefaultValue);
110 "Internal Error : cannot handle the data type" +
111 "received from ParameterInfo class");
115 if (last_arg_is_params && pos >= pi.Length - 1)
116 return pi [pi.Length - 1].ParameterType;
118 if (pos >= pi.Length)
121 Type pt = pi [pos].ParameterType;
123 pt = pt.GetElementType();
129 public string ParameterName (int pos)
131 if (last_arg_is_params && pos >= pi.Length - 1)
132 return pi [pi.Length - 1].Name;
134 return pi [pos].Name;
137 public string ParameterDesc (int pos)
139 StringBuilder sb = new StringBuilder ();
147 if (pos >= pi.Length - 1 && last_arg_is_params)
148 sb.Append ("params ");
150 sb.Append (TypeManager.MonoBASIC_Name (ParameterType (pos)));
152 return sb.ToString ();
156 public Parameter.Modifier ParameterModifier (int pos)
159 Parameter.Modifier pm = Parameter.Modifier.NONE;
162 if (last_arg_is_params) {
163 pm |= Parameter.Modifier.PARAMS;
167 Type t = pi [pos].ParameterType;
169 pm |= Parameter.Modifier.ISBYREF | Parameter.Modifier.REF;
171 if (pi [pos].IsOptional)
172 pm |= Parameter.Modifier.OPTIONAL;
185 public class InternalParameters : ParameterData {
188 public readonly Parameters Parameters;
190 public InternalParameters (Type [] param_types, Parameters parameters)
192 this.param_types = param_types;
193 this.Parameters = parameters;
196 public InternalParameters (DeclSpace ds, Parameters parameters)
197 : this (parameters.GetParameterInfo (ds), parameters)
203 if (param_types == null)
206 return param_types.Length;
210 public Type ParameterType (int pos)
212 if (param_types == null)
215 Parameter [] fixed_pars = Parameters.FixedParameters;
216 if (fixed_pars != null && pos < fixed_pars.Length)
217 return Parameters.FixedParameters [pos].ParameterType;
219 return Parameters.ArrayParameter.ParameterType;
222 public Expression DefaultValue (int pos)
224 Parameter [] fixed_pars = Parameters.FixedParameters;
225 if (fixed_pars != null && pos < fixed_pars.Length)
226 return Parameters.FixedParameters [pos].ParameterInitializer;
230 public string ParameterName (int pos)
234 if (pos >= Parameters.FixedParameters.Length)
235 p = Parameters.ArrayParameter;
237 p = Parameters.FixedParameters [pos];
242 public string ParameterDesc (int pos)
244 string tmp = String.Empty;
247 if (Parameters.FixedParameters == null || pos >= Parameters.FixedParameters.Length)
248 p = Parameters.ArrayParameter;
250 p = Parameters.FixedParameters [pos];
252 if (p.ModFlags == Parameter.Modifier.REF)
254 else if (p.ModFlags == Parameter.Modifier.PARAMS)
257 Type t = ParameterType (pos);
259 return tmp + TypeManager.MonoBASIC_Name (t);
262 public Parameter.Modifier ParameterModifier (int pos)
264 Parameter.Modifier mod;
266 if (Parameters.FixedParameters == null) {
267 if (Parameters.ArrayParameter != null)
268 mod = Parameters.ArrayParameter.ModFlags;
270 mod = Parameter.Modifier.NONE;
271 } else if (pos >= Parameters.FixedParameters.Length)
272 mod = Parameters.ArrayParameter.ModFlags;
274 mod = Parameters.FixedParameters [pos].ModFlags;
276 if ((mod & (Parameter.Modifier.REF )) != 0)
277 mod |= Parameter.Modifier.ISBYREF;
284 class PtrHashtable : Hashtable {
285 class PtrComparer : IComparer {
286 public int Compare (object x, object y)
295 public PtrHashtable ()
297 comparer = new PtrComparer ();
298 hcp = new CaseInsensitiveHashCodeProvider();
303 public class CaseInsensitiveHashtable : Hashtable {
304 public CaseInsensitiveHashtable() : base()
306 comparer = new CaseInsensitiveComparer();
307 hcp = new CaseInsensitiveHashCodeProvider();
312 // Compares member infos based on their name and
313 // also allows one argument to be a string
315 class MemberInfoCompare : IComparer {
317 public int Compare (object a, object b)
319 if (a == null || b == null){
320 Console.WriteLine ("Invalid information passed");
321 throw new Exception ();
325 return String.Compare ((string) a, ((MemberInfo)b).Name);
328 return String.Compare (((MemberInfo)a).Name, (string) b);
330 return String.Compare (((MemberInfo)a).Name, ((MemberInfo)b).Name);
336 public object Second;
338 public Pair (object f, object s)