MarshalByRefObject.cs: Implemented GetLifetimeService() and
[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 using System.Globalization;
17
18 namespace Mono.CSharp {
19
20         public interface ParameterData {
21                 Type ParameterType (int pos);
22                 int  Count { get; }
23                 string ParameterName (int pos);
24                 string ParameterDesc (int pos);
25                 Parameter.Modifier ParameterModifier (int pos);
26         }
27
28         public class ReflectionParameters : ParameterData {
29                 ParameterInfo [] pi;
30                 bool last_arg_is_params = false;
31                 
32                 public ReflectionParameters (ParameterInfo [] pi)
33                 {
34                         object [] attrs;
35                         
36                         this.pi = pi;
37                         int count = pi.Length-1;
38
39                         if (count >= 0) {
40                                 attrs = pi [count].GetCustomAttributes (TypeManager.param_array_type, true);
41
42                                 if (attrs == null)
43                                         return;
44                                 
45                                 if (attrs.Length == 0)
46                                         return;
47
48                                 last_arg_is_params = true;
49                         }
50                 }
51                        
52                 public Type ParameterType (int pos)
53                 {
54                         if (last_arg_is_params && pos >= pi.Length - 1)
55                                 return pi [pi.Length - 1].ParameterType;
56                         else {
57                                 Type t = pi [pos].ParameterType;
58
59                                 if (t.IsByRef)
60                                         return t.GetElementType ();
61                                 else
62                                         return t;
63                         }
64                 }
65
66                 public string ParameterName (int pos)
67                 {
68                         if (last_arg_is_params && pos >= pi.Length - 1)
69                                 return pi [pi.Length - 1].Name;
70                         else 
71                                 return pi [pos].Name;
72                 }
73
74                 public string ParameterDesc (int pos)
75                 {
76                         StringBuilder sb = new StringBuilder ();
77
78                         if (pi [pos].IsOut)
79                                 sb.Append ("out ");
80
81                         if (pi [pos].IsIn)
82                                 sb.Append ("in ");
83
84                         if (pos >= pi.Length - 1 && last_arg_is_params)
85                                 sb.Append ("params ");
86                         
87                         sb.Append (TypeManager.CSharpName (ParameterType (pos)));
88
89                         return sb.ToString ();
90                         
91                 }
92
93                 public Parameter.Modifier ParameterModifier (int pos)
94                 {
95                         int len = pi.Length;
96
97                         if (pos >= len - 1)
98                                 if (last_arg_is_params)
99                                         return Parameter.Modifier.PARAMS;
100                         
101                         Type t = pi [pos].ParameterType;
102                         if (t.IsByRef){
103                                 if ((pi [pos].Attributes & ParameterAttributes.Out) != 0)
104                                         return Parameter.Modifier.ISBYREF | Parameter.Modifier.OUT;
105                                 else
106                                         return Parameter.Modifier.ISBYREF | Parameter.Modifier.REF;
107                         }
108                         
109                         return Parameter.Modifier.NONE;
110                 }
111
112                 public int Count {
113                         get {
114                                 return pi.Length;
115                         }
116                 }
117                 
118         }
119
120         public class InternalParameters : ParameterData {
121                 Type [] param_types;
122
123                 public readonly Parameters Parameters;
124                 
125                 public InternalParameters (Type [] param_types, Parameters parameters)
126                 {
127                         this.param_types = param_types;
128                         this.Parameters = parameters;
129                 }
130
131                 public InternalParameters (DeclSpace ds, Parameters parameters)
132                         : this (parameters.GetParameterInfo (ds), parameters)
133                 {
134                 }
135
136                 public int Count {
137                         get {
138                                 if (param_types == null)
139                                         return 0;
140
141                                 return param_types.Length;
142                         }
143                 }
144
145                 Parameter GetParameter (int pos)
146                 {
147                         Parameter [] fixed_pars = Parameters.FixedParameters;
148                         if (fixed_pars != null){
149                                 int len = fixed_pars.Length;
150                                 if (pos < len)
151                                         return Parameters.FixedParameters [pos];
152                         }
153
154                         return Parameters.ArrayParameter;
155                 }
156
157                 public Type ParameterType (int pos)
158                 {
159                         if (param_types == null)
160                                 return null;
161
162                         return GetParameter (pos).ParameterType;
163                 }
164
165
166                 public string ParameterName (int pos)
167                 {
168                         return GetParameter (pos).Name;
169                 }
170
171                 public string ParameterDesc (int pos)
172                 {
173                         string tmp = String.Empty;
174                         Parameter p = GetParameter (pos);
175
176                         //
177                         // We need to and for REF/OUT, because if either is set the
178                         // extra flag ISBYREF will be set as well
179                         //
180                         if ((p.ModFlags & Parameter.Modifier.REF) != 0)
181                                 tmp = "ref ";
182                         else if ((p.ModFlags & Parameter.Modifier.OUT) != 0)
183                                 tmp = "out ";
184                         else if (p.ModFlags == Parameter.Modifier.PARAMS)
185                                 tmp = "params ";
186
187                         Type t = ParameterType (pos);
188
189                         return tmp + TypeManager.CSharpName (t);
190                 }
191
192                 public Parameter.Modifier ParameterModifier (int pos)
193                 {
194                         Parameter.Modifier mod = GetParameter (pos).ModFlags;
195
196                         if ((mod & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) != 0)
197                                 mod |= Parameter.Modifier.ISBYREF;
198
199                         return mod;
200                 }
201                 
202         }
203
204         class PtrHashtable : Hashtable {
205                 class PtrComparer : IComparer {
206                         public int Compare (object x, object y)
207                         {
208                                 if (x == y)
209                                         return 0;
210                                 else
211                                         return 1;
212                         }
213                 }
214                 
215                 public PtrHashtable ()
216                 {
217                         comparer = new PtrComparer ();
218                 }
219         }
220
221         //
222         // Compares member infos based on their name and
223         // also allows one argument to be a string
224         //
225         class MemberInfoCompare : IComparer {
226
227                 public int Compare (object a, object b)
228                 {
229                         if (a == null || b == null){
230                                 Console.WriteLine ("Invalid information passed");
231                                 throw new Exception ();
232                         }
233                         
234                         if (a is string)
235                                 return String.Compare ((string) a, ((MemberInfo)b).Name);
236
237                         if (b is string)
238                                 return String.Compare (((MemberInfo)a).Name, (string) b);
239
240                         return String.Compare (((MemberInfo)a).Name, ((MemberInfo)b).Name);
241                 }
242         }
243
244         struct Pair {
245                 public object First;
246                 public object Second;
247                 
248                 public Pair (object f, object s)
249                 {
250                         First = f;
251                         Second = s;
252                 }
253         }
254
255 }