2003-12-17 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / corlib / System.Reflection / MonoGenericInst.cs
1 //
2 // System.MonoType
3 //
4 // Sean MacIsaac (macisaac@ximian.com)
5 // Paolo Molaro (lupus@ximian.com)
6 // Patrik Torstensson (patrik.torstensson@labs2.com)
7 //
8 // (C) 2001 Ximian, Inc.
9 //
10
11 using System.Reflection;
12 using System.Collections;
13 using System.Runtime.CompilerServices;
14 using System.Globalization;
15 using System.Runtime.Serialization;
16
17 namespace System.Reflection
18 {
19         internal class MonoGenericInst : MonoType
20         {
21                 private IntPtr klass;
22                 protected MonoGenericInst parent;
23                 protected Type generic_type;
24                 private MonoGenericInst[] interfaces;
25                 private MethodInfo[] methods;
26                 private ConstructorInfo[] ctors;
27                 private FieldInfo[] fields;
28
29                 [MonoTODO]
30                 internal MonoGenericInst ()
31                         : base (null)
32                 {
33                         // this should not be used
34                         throw new InvalidOperationException ();
35                 }
36
37                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
38                 private static extern MethodInfo inflate_method (MonoGenericInst declaring, MonoGenericInst reflected, MethodInfo method);
39         
40                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
41                 private static extern ConstructorInfo inflate_ctor (MonoGenericInst declaring, MonoGenericInst reflected, ConstructorInfo ctor);
42
43                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
44                 private static extern FieldInfo inflate_field (MonoGenericInst declaring, MonoGenericInst reflected, FieldInfo field);
45
46                 private const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic |
47                 BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
48
49                 protected void inflate (MonoGenericInst reflected,
50                                         ArrayList mlist, ArrayList clist, ArrayList flist)
51                 {
52                         if (parent != null)
53                                 parent.inflate (parent, mlist, clist, flist);
54                         else if (BaseType != null) {
55                                 mlist.AddRange (generic_type.BaseType.GetMethods (flags));
56                                 clist.AddRange (generic_type.BaseType.GetConstructors (flags));
57                                 flist.AddRange (generic_type.BaseType.GetFields (flags));
58                         } else if (interfaces != null) {
59                                 foreach (MonoGenericInst iface in interfaces)
60                                         iface.inflate (iface, mlist, clist, flist);
61                         }
62
63                         foreach (MethodInfo m in generic_type.GetMethods (flags))
64                                 mlist.Add (inflate_method (this, reflected, m));
65                         foreach (ConstructorInfo c in generic_type.GetConstructors (flags))
66                                 clist.Add (inflate_ctor (this, reflected, c));
67                         foreach (FieldInfo f in generic_type.GetFields (flags))
68                                 flist.Add (inflate_field (this, reflected, f));
69                 }
70
71                 void initialize ()
72                 {
73                         ArrayList mlist = new ArrayList ();
74                         ArrayList clist = new ArrayList ();
75                         ArrayList flist = new ArrayList ();
76
77                         inflate (this, mlist, clist, flist);
78
79                         methods = new MethodInfo [mlist.Count];
80                         mlist.CopyTo (methods, 0);
81
82                         ctors = new ConstructorInfo [clist.Count];
83                         clist.CopyTo (ctors, 0);
84
85                         fields = new FieldInfo [flist.Count];
86                         flist.CopyTo (fields, 0);
87                 }
88
89                 public override Type BaseType {
90                         get { return parent != null ? parent : generic_type.BaseType; }
91                 }
92
93                 protected override bool IsValueTypeImpl ()
94                 {
95                         if (BaseType == null)
96                                 return false;
97                         if (BaseType == typeof (Enum) || BaseType == typeof (ValueType))
98                                 return true;
99
100                         return BaseType.IsSubclassOf (typeof (ValueType));
101                 }
102
103                 public override MethodInfo[] GetMethods (BindingFlags bindingAttr)
104                 {
105                         if (methods == null)
106                                 initialize ();
107
108                         return GetMethods_impl (bindingAttr);
109                 }
110
111                 protected MethodInfo[] GetMethods_impl (BindingFlags bindingAttr)
112                 {
113                         ArrayList l = new ArrayList ();
114                         bool match;
115                         MethodAttributes mattrs;
116
117                         foreach (MethodInfo c in methods) {
118                                 match = false;
119                                 mattrs = c.Attributes;
120                                 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
121                                         if ((bindingAttr & BindingFlags.Public) != 0)
122                                                 match = true;
123                                 } else {
124                                         if ((bindingAttr & BindingFlags.NonPublic) != 0)
125                                                 match = true;
126                                 }
127                                 if (!match)
128                                         continue;
129                                 match = false;
130                                 if ((mattrs & MethodAttributes.Static) != 0) {
131                                         if ((bindingAttr & BindingFlags.Static) != 0)
132                                                 match = true;
133                                 } else {
134                                         if ((bindingAttr & BindingFlags.Instance) != 0)
135                                                 match = true;
136                                 }
137                                 if (!match)
138                                         continue;
139                                 l.Add (c);
140                         }
141                         MethodInfo[] result = new MethodInfo [l.Count];
142                         l.CopyTo (result);
143                         return result;
144                 }
145
146                 public override ConstructorInfo[] GetConstructors (BindingFlags bindingAttr)
147                 {
148                         if (ctors == null)
149                                 initialize ();
150
151                         return GetConstructors_impl (bindingAttr);
152                 }
153
154                 protected ConstructorInfo[] GetConstructors_impl (BindingFlags bindingAttr)
155                 {
156                         ArrayList l = new ArrayList ();
157                         bool match;
158                         MethodAttributes mattrs;
159
160                         foreach (ConstructorInfo c in ctors) {
161                                 match = false;
162                                 mattrs = c.Attributes;
163                                 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
164                                         if ((bindingAttr & BindingFlags.Public) != 0)
165                                                 match = true;
166                                 } else {
167                                         if ((bindingAttr & BindingFlags.NonPublic) != 0)
168                                                 match = true;
169                                 }
170                                 if (!match)
171                                         continue;
172                                 match = false;
173                                 if ((mattrs & MethodAttributes.Static) != 0) {
174                                         if ((bindingAttr & BindingFlags.Static) != 0)
175                                                 match = true;
176                                 } else {
177                                         if ((bindingAttr & BindingFlags.Instance) != 0)
178                                                 match = true;
179                                 }
180                                 if (!match)
181                                         continue;
182                                 l.Add (c);
183                         }
184                         ConstructorInfo[] result = new ConstructorInfo [l.Count];
185                         l.CopyTo (result);
186                         return result;
187                 }
188
189                 public override FieldInfo[] GetFields (BindingFlags bindingAttr)
190                 {
191                         if (fields == null)
192                                 initialize ();
193
194                         return GetFields_impl (bindingAttr);
195                 }
196
197                 protected FieldInfo[] GetFields_impl (BindingFlags bindingAttr)
198                 {
199                         ArrayList l = new ArrayList ();
200                         bool match;
201                         FieldAttributes fattrs;
202
203                         foreach (FieldInfo c in fields) {
204                                 match = false;
205                                 fattrs = c.Attributes;
206                                 if ((fattrs & FieldAttributes.FieldAccessMask) == FieldAttributes.Public) {
207                                         if ((bindingAttr & BindingFlags.Public) != 0)
208                                                 match = true;
209                                 } else {
210                                         if ((bindingAttr & BindingFlags.NonPublic) != 0)
211                                                 match = true;
212                                 }
213                                 if (!match)
214                                         continue;
215                                 match = false;
216                                 if ((fattrs & FieldAttributes.Static) != 0) {
217                                         if ((bindingAttr & BindingFlags.Static) != 0)
218                                                 match = true;
219                                 } else {
220                                         if ((bindingAttr & BindingFlags.Instance) != 0)
221                                                 match = true;
222                                 }
223                                 if (!match)
224                                         continue;
225                                 l.Add (c);
226                         }
227                         FieldInfo[] result = new FieldInfo [l.Count];
228                         l.CopyTo (result);
229                         return result;
230                 }
231         }
232
233         internal class MonoInflatedMethod : MonoMethod
234         {
235                 private readonly MethodInfo declaring;
236                 private readonly MonoGenericInst declaring_type;
237                 private readonly MonoGenericInst reflected_type;
238                 private readonly IntPtr ginst;
239
240                 public override Type DeclaringType {
241                         get {
242                                 return declaring_type != null ? declaring_type : base.DeclaringType;
243                         }
244                 }
245
246                 public override Type ReflectedType {
247                         get {
248                                 return reflected_type != null ? reflected_type : base.ReflectedType;
249                         }
250                 }
251
252                 public override bool IsDefined (Type attributeType, bool inherit)
253                 {
254                         // FIXME
255                         return false;
256                 }
257                 public override object[] GetCustomAttributes (bool inherit)
258                 {
259                         // FIXME
260                         return new object [0];
261                 }
262                 public override object[] GetCustomAttributes (Type attributeType, bool inherit)
263                 {
264                         // FIXME
265                         return new object [0];
266                 }
267         }
268
269         internal class MonoInflatedCtor : MonoCMethod
270         {
271                 private readonly ConstructorInfo declaring;
272                 private readonly MonoGenericInst declaring_type;
273                 private readonly MonoGenericInst reflected_type;
274                 private readonly IntPtr ginst;
275
276                 public override Type DeclaringType {
277                         get {
278                                 return declaring_type != null ? declaring_type : base.DeclaringType;
279                         }
280                 }
281
282                 public override Type ReflectedType {
283                         get {
284                                 return reflected_type != null ? reflected_type : base.ReflectedType;
285                         }
286                 }
287
288                 public override bool IsDefined (Type attributeType, bool inherit)
289                 {
290                         // FIXME
291                         return false;
292                 }
293                 public override object[] GetCustomAttributes (bool inherit)
294                 {
295                         // FIXME
296                         return new object [0];
297                 }
298                 public override object[] GetCustomAttributes (Type attributeType, bool inherit)
299                 {
300                         // FIXME
301                         return new object [0];
302                 }
303         }
304
305         internal class MonoInflatedField : MonoField
306         {
307                 private readonly IntPtr dhandle;
308                 private readonly MonoGenericInst declaring_type;
309                 private readonly MonoGenericInst reflected_type;
310
311                 public override Type DeclaringType {
312                         get {
313                                 return declaring_type != null ? declaring_type : base.DeclaringType;
314                         }
315                 }
316
317                 public override Type ReflectedType {
318                         get {
319                                 return reflected_type != null ? reflected_type : base.ReflectedType;
320                         }
321                 }
322         }
323
324         internal class MonoGenericParam : MonoType
325         {
326                 private object refobj;
327                 private int index;
328                 private string name;
329                 private int flags;
330                 private Type[] constraints;
331                 bool initialized;
332
333                 [MonoTODO]
334                 internal MonoGenericParam ()
335                         : base (null)
336                 {
337                         // this should not be used
338                         throw new InvalidOperationException ();
339                 }
340
341                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
342                 private extern void initialize ();
343
344                 public void SetConstraints (Type[] constraints)
345                 {
346                         this.constraints = constraints;
347                         initialize ();
348                 }
349
350                 public override Type BaseType {
351                         get {
352                                 if (!initialized)
353                                         throw new InvalidOperationException ();
354                                 if ((constraints.Length == 0) || constraints [0].IsInterface)
355                                         return null;
356                                 else
357                                         return constraints [0];
358                         }
359                 }
360
361                 public override Type[] GetInterfaces ()
362                 {
363                         if (!initialized)
364                                 throw new InvalidOperationException ();
365
366                         if ((constraints.Length == 0) || constraints [0].IsInterface)
367                                 return constraints;
368                         else {
369                                 Type[] ret = new Type [constraints.Length-1];
370                                 Array.Copy (constraints, 1, ret, 0, constraints.Length-1);
371                                 return ret;
372                         }
373                 }
374         }
375 }