Old code
[mono.git] / mcs / mbas / support.cs
1 //\r
2 // support.cs: Support routines to work around the fact that System.Reflection.Emit\r
3 // can not introspect types that are being constructed\r
4 //\r
5 // Author:\r
6 //   Miguel de Icaza (miguel@ximian.com)\r
7 //\r
8 // (C) 2001 Ximian, Inc (http://www.ximian.com)\r
9 //\r
10 \r
11 using System;\r
12 using System.Text;\r
13 using System.Reflection;\r
14 using System.Collections;\r
15 using System.Reflection.Emit;\r
16 \r
17 namespace Mono.CSharp {\r
18 \r
19         public interface ParameterData {\r
20                 Type ParameterType (int pos);\r
21                 int  Count { get; }\r
22                 string ParameterDesc (int pos);\r
23                 Parameter.Modifier ParameterModifier (int pos);\r
24         }\r
25 \r
26         public class ReflectionParameters : ParameterData {\r
27                 ParameterInfo [] pi;\r
28                 bool last_arg_is_params;\r
29                 \r
30                 public ReflectionParameters (ParameterInfo [] pi)\r
31                 {\r
32                         object [] a;\r
33                         \r
34                         this.pi = pi;\r
35 \r
36                         int count = pi.Length-1;\r
37 \r
38                         if (count > 0) {\r
39                                 a = pi [count].GetCustomAttributes (TypeManager.param_array_type, false);\r
40 \r
41                                 if (a != null)\r
42                                         if (a.Length != 0)\r
43                                                 last_arg_is_params = true;\r
44                         } \r
45                 }\r
46                        \r
47                 public Type ParameterType (int pos)\r
48                 {\r
49                         if (last_arg_is_params && pos >= pi.Length - 1)\r
50                                 return pi [pi.Length -1].ParameterType;\r
51                         else \r
52                                 return pi [pos].ParameterType;\r
53                 }\r
54 \r
55                 public string ParameterDesc (int pos)\r
56                 {\r
57                         StringBuilder sb = new StringBuilder ();\r
58 \r
59                         if (pi [pos].IsOut)\r
60                                 sb.Append ("out ");\r
61 \r
62                         if (pi [pos].IsIn)\r
63                                 sb.Append ("in ");\r
64 \r
65                         if (pos >= pi.Length - 1 && last_arg_is_params)\r
66                                 sb.Append ("params ");\r
67                         \r
68                         sb.Append (TypeManager.CSharpName (ParameterType (pos)));\r
69 \r
70                         return sb.ToString ();\r
71                         \r
72                 }\r
73 \r
74                 public Parameter.Modifier ParameterModifier (int pos)\r
75                 {\r
76                         if (pos >= pi.Length - 1) \r
77                                 if (last_arg_is_params)\r
78                                         return Parameter.Modifier.PARAMS;\r
79 \r
80                         Type t = pi [pos].ParameterType;\r
81                         if (t.IsByRef)\r
82                                 return Parameter.Modifier.OUT;\r
83                         \r
84                         return Parameter.Modifier.NONE;\r
85                 }\r
86 \r
87                 public int Count {\r
88                         get {\r
89                                 return pi.Length;\r
90                         }\r
91                 }\r
92                 \r
93         }\r
94 \r
95         public class InternalParameters : ParameterData {\r
96                 Type [] param_types;\r
97 \r
98                 Parameters parameters;\r
99                 \r
100                 public InternalParameters (Type [] param_types, Parameters parameters)\r
101                 {\r
102                         this.param_types = param_types;\r
103                         this.parameters = parameters;\r
104                 }\r
105 \r
106                 public InternalParameters (TypeContainer tc, Parameters parameters)\r
107                         : this (parameters.GetParameterInfo (tc), parameters)\r
108                 {\r
109                 }\r
110 \r
111                 public int Count {\r
112                         get {\r
113                                 if (param_types == null)\r
114                                         return 0;\r
115 \r
116                                 return param_types.Length;\r
117                         }\r
118                 }\r
119 \r
120                 public Type ParameterType (int pos)\r
121                 {\r
122                         if (param_types == null)\r
123                                 return null;\r
124 \r
125                         Parameter [] fixed_pars = parameters.FixedParameters;\r
126                         if (fixed_pars != null){\r
127                                 int len = fixed_pars.Length;\r
128                                 if (pos < len)\r
129                                         return parameters.FixedParameters [pos].ParameterType;\r
130                                 else \r
131                                         return parameters.ArrayParameter.ParameterType;\r
132                         } else\r
133                                 return parameters.ArrayParameter.ParameterType;\r
134                 }\r
135 \r
136                 public string ParameterDesc (int pos)\r
137                 {\r
138                         string tmp = null;\r
139                         Parameter p;\r
140 \r
141                         if (pos >= parameters.FixedParameters.Length)\r
142                                 p = parameters.ArrayParameter;\r
143                         else\r
144                                 p = parameters.FixedParameters [pos];\r
145                         \r
146                         if (p.ModFlags == Parameter.Modifier.REF)\r
147                                 tmp = "ref ";\r
148                         else if (p.ModFlags == Parameter.Modifier.OUT)\r
149                                 tmp = "out ";\r
150                         else if (p.ModFlags == Parameter.Modifier.PARAMS)\r
151                                 tmp = "params ";\r
152 \r
153                         Type t = ParameterType (pos);\r
154 \r
155                         return tmp + TypeManager.CSharpName (t);\r
156                 }\r
157 \r
158                 public Parameter.Modifier ParameterModifier (int pos)\r
159                 {\r
160                         if (parameters.FixedParameters == null)\r
161                                 return parameters.ArrayParameter.ModFlags;\r
162                         \r
163                         if (pos >= parameters.FixedParameters.Length)\r
164                                 return parameters.ArrayParameter.ModFlags;\r
165                         else {\r
166                                 Parameter.Modifier m = parameters.FixedParameters [pos].ModFlags;\r
167 \r
168                                 //\r
169                                 // We use a return value of "OUT" for "reference" parameters.\r
170                                 // both out and ref flags in the source map to reference parameters.\r
171                                 //\r
172                                 if (m == Parameter.Modifier.OUT || m == Parameter.Modifier.REF)\r
173                                         return Parameter.Modifier.OUT;\r
174                                 \r
175                                 return Parameter.Modifier.NONE;\r
176                         }\r
177                 }\r
178                 \r
179         }\r
180 \r
181         class PtrHashtable : Hashtable {\r
182                 class PtrComparer : IComparer {\r
183                         public int Compare (object x, object y)\r
184                         {\r
185                                 if (x == y)\r
186                                         return 0;\r
187                                 else\r
188                                         return 1;\r
189                         }\r
190                 }\r
191                 \r
192                 public PtrHashtable ()\r
193                 {\r
194                         comparer = new PtrComparer ();\r
195                 }\r
196         }\r
197 \r
198         //\r
199         // Compares member infos based on their name and\r
200         // also allows one argument to be a string\r
201         //\r
202         class MemberInfoCompare : IComparer {\r
203 \r
204                 public int Compare (object a, object b)\r
205                 {\r
206                         if (a == null || b == null){\r
207                                 Console.WriteLine ("Invalid information passed");\r
208                                 throw new Exception ();\r
209                         }\r
210                         \r
211                         if (a is string)\r
212                                 return String.Compare ((string) a, ((MemberInfo)b).Name);\r
213 \r
214                         if (b is string)\r
215                                 return String.Compare (((MemberInfo)a).Name, (string) b);\r
216 \r
217                         return String.Compare (((MemberInfo)a).Name, ((MemberInfo)b).Name);\r
218                 }\r
219         }\r
220 \r
221         struct Pair {\r
222                 public object First;\r
223                 public object Second;\r
224                 \r
225                 public Pair (object f, object s)\r
226                 {\r
227                         First = f;\r
228                         Second = s;\r
229                 }\r
230         }\r
231 }\r