2004-02-17 Martin Baulig <martin@ximian.com>
[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.Reflection.Emit;
13 using System.Collections;
14 using System.Runtime.CompilerServices;
15 using System.Globalization;
16 using System.Runtime.Serialization;
17
18 namespace System.Reflection
19 {
20         internal class MonoGenericInst : MonoType
21         {
22                 protected Type generic_type;
23                 bool initialized;
24
25                 [MonoTODO]
26                 internal MonoGenericInst ()
27                         : base (null)
28                 {
29                         // this should not be used
30                         throw new InvalidOperationException ();
31                 }
32
33                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
34                 protected extern void initialize (MethodInfo[] methods, ConstructorInfo[] ctors, FieldInfo[] fields);
35
36                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
37                 protected extern MethodInfo[] GetMethods_internal (Type reflected_type);
38
39                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
40                 protected extern ConstructorInfo[] GetConstructors_internal (Type reflected_type);
41
42                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
43                 protected extern FieldInfo[] GetFields_internal (Type reflected_type);
44
45                 private const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic |
46                 BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
47
48                 void initialize ()
49                 {
50                         if (initialized)
51                                 return;
52
53                         MonoGenericInst parent = GetParentType ();
54                         if (parent != null)
55                                 parent.initialize ();
56
57                         initialize (generic_type.GetMethods (flags),
58                                     generic_type.GetConstructors (flags),
59                                     generic_type.GetFields (flags));
60
61                         initialized = true;
62                 }
63
64                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
65                 protected extern MonoGenericInst GetParentType ();
66
67                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
68                 protected extern MonoGenericInst[] GetInterfaces_internal ();
69
70                 public override Type BaseType {
71                         get {
72                                 MonoGenericInst parent = GetParentType ();
73                                 return parent != null ? parent : generic_type.BaseType;
74                         }
75                 }
76
77                 public override Type DeclaringType {
78                         get { return generic_type.DeclaringType; }
79                 }
80
81                 public override Type[] GetInterfaces ()
82                 {
83                         return GetInterfaces_internal ();
84                 }
85
86                 protected override bool IsValueTypeImpl ()
87                 {
88                         return generic_type.IsValueType;
89                 }
90
91                 public override MethodInfo[] GetMethods (BindingFlags bf)
92                 {
93                         initialize ();
94                         return GetMethods_impl (bf, this);
95                 }
96
97                 protected MethodInfo[] GetMethods_impl (BindingFlags bf, Type reftype)
98                 {
99                         ArrayList l = new ArrayList ();
100                         bool match;
101                         MethodAttributes mattrs;
102
103                         if ((bf & BindingFlags.DeclaredOnly) == 0) {
104                                 MonoGenericInst parent = GetParentType ();
105                                 if (parent != null)
106                                         l.AddRange (parent.GetMethods_impl (bf, reftype));
107                         }
108
109                         MethodInfo[] methods = GetMethods_internal (reftype);
110
111                         for (int i = 0; i < methods.Length; i++) {
112                                 MethodInfo c = methods [i];
113
114                                 match = false;
115                                 mattrs = c.Attributes;
116                                 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
117                                         if ((bf & BindingFlags.Public) != 0)
118                                                 match = true;
119                                 } else {
120                                         if ((bf & BindingFlags.NonPublic) != 0)
121                                                 match = true;
122                                 }
123                                 if (!match)
124                                         continue;
125                                 match = false;
126                                 if ((mattrs & MethodAttributes.Static) != 0) {
127                                         if ((bf & BindingFlags.Static) != 0)
128                                                 match = true;
129                                 } else {
130                                         if ((bf & BindingFlags.Instance) != 0)
131                                                 match = true;
132                                 }
133                                 if (!match)
134                                         continue;
135                                 l.Add (c);
136                         }
137                         MethodInfo[] result = new MethodInfo [l.Count];
138                         l.CopyTo (result);
139                         return result;
140                 }
141
142                 public override ConstructorInfo[] GetConstructors (BindingFlags bf)
143                 {
144                         initialize ();
145                         return GetConstructors_impl (bf, this);
146                 }
147
148                 protected ConstructorInfo[] GetConstructors_impl (BindingFlags bf, Type reftype)
149                 {
150                         ArrayList l = new ArrayList ();
151                         bool match;
152                         MethodAttributes mattrs;
153
154                         if ((bf & BindingFlags.DeclaredOnly) == 0) {
155                                 MonoGenericInst parent = GetParentType ();
156                                 if (parent != null)
157                                         l.AddRange (parent.GetConstructors_impl (bf, reftype));
158                         }
159
160                         ConstructorInfo[] ctors = GetConstructors_internal (reftype);
161
162                         for (int i = 0; i < ctors.Length; i++) {
163                                 ConstructorInfo c = ctors [i];
164
165                                 match = false;
166                                 mattrs = c.Attributes;
167                                 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
168                                         if ((bf & BindingFlags.Public) != 0)
169                                                 match = true;
170                                 } else {
171                                         if ((bf & BindingFlags.NonPublic) != 0)
172                                                 match = true;
173                                 }
174                                 if (!match)
175                                         continue;
176                                 match = false;
177                                 if ((mattrs & MethodAttributes.Static) != 0) {
178                                         if ((bf & BindingFlags.Static) != 0)
179                                                 match = true;
180                                 } else {
181                                         if ((bf & BindingFlags.Instance) != 0)
182                                                 match = true;
183                                 }
184                                 if (!match)
185                                         continue;
186                                 l.Add (c);
187                         }
188                         ConstructorInfo[] result = new ConstructorInfo [l.Count];
189                         l.CopyTo (result);
190                         return result;
191                 }
192
193                 public override FieldInfo[] GetFields (BindingFlags bf)
194                 {
195                         initialize ();
196                         return GetFields_impl (bf, this);
197                 }
198
199                 protected FieldInfo[] GetFields_impl (BindingFlags bf, Type reftype)
200                 {
201                         ArrayList l = new ArrayList ();
202                         bool match;
203                         FieldAttributes fattrs;
204
205                         if ((bf & BindingFlags.DeclaredOnly) == 0) {
206                                 MonoGenericInst parent = GetParentType ();
207                                 if (parent != null)
208                                         l.AddRange (parent.GetFields_impl (bf, reftype));
209                         }
210
211                         FieldInfo[] fields = GetFields_internal (reftype);
212
213                         for (int i = 0; i < fields.Length; i++) {
214                                 FieldInfo c = fields [i];
215
216                                 match = false;
217                                 fattrs = c.Attributes;
218                                 if ((fattrs & FieldAttributes.FieldAccessMask) == FieldAttributes.Public) {
219                                         if ((bf & BindingFlags.Public) != 0)
220                                                 match = true;
221                                 } else {
222                                         if ((bf & BindingFlags.NonPublic) != 0)
223                                                 match = true;
224                                 }
225                                 if (!match)
226                                         continue;
227                                 match = false;
228                                 if ((fattrs & FieldAttributes.Static) != 0) {
229                                         if ((bf & BindingFlags.Static) != 0)
230                                                 match = true;
231                                 } else {
232                                         if ((bf & BindingFlags.Instance) != 0)
233                                                 match = true;
234                                 }
235                                 if (!match)
236                                         continue;
237                                 l.Add (c);
238                         }
239                         FieldInfo[] result = new FieldInfo [l.Count];
240                         l.CopyTo (result);
241                         return result;
242                 }
243         }
244
245         internal class MonoGenericParam : MonoType
246         {
247                 private object refobj;
248                 private int index;
249                 private string name;
250                 private int flags;
251                 private Type[] constraints;
252                 bool initialized;
253
254                 [MonoTODO]
255                 internal MonoGenericParam ()
256                         : base (null)
257                 {
258                         // this should not be used
259                         throw new InvalidOperationException ();
260                 }
261
262                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
263                 private extern void initialize ();
264
265                 public void SetConstraints (Type[] constraints)
266                 {
267                         this.constraints = constraints;
268                         initialize ();
269                 }
270
271                 public override Type BaseType {
272                         get {
273                                 if (!initialized)
274                                         throw new InvalidOperationException ();
275                                 if ((constraints.Length == 0) || constraints [0].IsInterface)
276                                         return null;
277                                 else
278                                         return constraints [0];
279                         }
280                 }
281
282                 public override Type[] GetInterfaces ()
283                 {
284                         if (!initialized)
285                                 throw new InvalidOperationException ();
286
287                         if ((constraints.Length == 0) || constraints [0].IsInterface)
288                                 return constraints;
289                         else {
290                                 Type[] ret = new Type [constraints.Length-1];
291                                 Array.Copy (constraints, 1, ret, 0, constraints.Length-1);
292                                 return ret;
293                         }
294                 }
295         }
296 }