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