2004-09-28 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / corlib / System.Reflection / Module.cs
1 //
2 // System.Reflection/Module.cs
3 //
4 // Author:
5 //   Paolo Molaro (lupus@ximian.com)
6 //
7 // (C) 2001 Ximian, Inc.  http://www.ximian.com
8 //
9
10 //
11 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32
33 using System;
34 using System.Reflection;
35 using System.Runtime.Serialization;
36 using System.Security.Cryptography.X509Certificates;
37 using System.Runtime.InteropServices;
38 using System.Runtime.CompilerServices;
39
40 namespace System.Reflection {
41
42         internal enum ResolveTokenError {
43                 OutOfRange,
44                 BadTable,
45                 Other
46         };
47
48         [Serializable]
49         public class Module : ISerializable, ICustomAttributeProvider {
50         
51                 public static readonly TypeFilter FilterTypeName;
52                 public static readonly TypeFilter FilterTypeNameIgnoreCase;
53         
54                 private IntPtr _impl; /* a pointer to a MonoImage */
55                 internal Assembly assembly;
56                 internal string fqname;
57                 internal string name;
58                 internal string scopename;
59                 internal bool is_resource;
60                 internal int token;
61         
62                 const BindingFlags defaultBindingFlags = 
63                         BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance;
64                 
65                 static Module () {
66                         FilterTypeName = new TypeFilter (filter_by_type_name);
67                         FilterTypeNameIgnoreCase = new TypeFilter (filter_by_type_name_ignore_case);
68                 }
69
70                 internal Module () { }
71
72                 ~Module () {
73                         Close ();
74                 }
75         
76                 public Assembly Assembly {
77                         get { return assembly; }
78                 }
79         
80                 public virtual string FullyQualifiedName {
81                         get { return fqname; }
82                 }
83         
84                 public string Name {
85                         get { return name; }
86                 }
87         
88                 public string ScopeName {
89                         get { return scopename; }
90                 }
91
92 #if NET_2_0
93                 [CLSCompliant(false)]
94                 public ModuleHandle ModuleHandle {
95                         get {
96                                 return new ModuleHandle (_impl);
97                         }
98                 }
99
100                 public extern int MetadataToken {
101                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
102                         get;
103                 }               
104 #endif
105         
106                 public virtual Type[] FindTypes(TypeFilter filter, object filterCriteria) 
107                 {
108                         System.Collections.ArrayList filtered = new System.Collections.ArrayList ();
109                         Type[] types = GetTypes ();
110                         foreach (Type t in types)
111                                 if (filter (t, filterCriteria))
112                                         filtered.Add (t);
113                         return (Type[])filtered.ToArray (typeof(Type));
114                 }
115         
116                 public virtual object[] GetCustomAttributes(bool inherit) 
117                 {
118                         return MonoCustomAttrs.GetCustomAttributes (this, inherit);
119                 }
120         
121                 public virtual object[] GetCustomAttributes(Type attributeType, bool inherit) 
122                 {
123                         return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
124                 }
125         
126                 public FieldInfo GetField (string name) 
127                 {
128                         if (IsResource ())
129                                 return null;
130
131                         return GetGlobalType ().GetField (name, BindingFlags.Public | BindingFlags.Static);
132                 }
133         
134                 public FieldInfo GetField (string name, BindingFlags flags) 
135                 {
136                         if (IsResource ())
137                                 return null;
138
139                         return GetGlobalType ().GetField (name, flags);
140                 }
141         
142                 public FieldInfo[] GetFields () 
143                 {
144                         if (IsResource ())
145                                 return new FieldInfo [0];
146
147                         return GetGlobalType ().GetFields (BindingFlags.Public | BindingFlags.Static);
148                 }
149         
150                 public MethodInfo GetMethod (string name) 
151                 {
152                         return GetMethodImpl (name, defaultBindingFlags, null, CallingConventions.Any, Type.EmptyTypes, null);
153                 }
154         
155                 public MethodInfo GetMethod (string name, Type[] types) 
156                 {
157                         return GetMethodImpl (name, defaultBindingFlags, null, CallingConventions.Any, types, null);
158                 }
159         
160                 public MethodInfo GetMethod (string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) 
161                 {
162                         return GetMethodImpl (name, bindingAttr, binder, callConvention, types, modifiers);
163                 }
164         
165                 protected virtual MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) 
166                 {
167                         if (IsResource ())
168                                 return null;
169
170                         return GetGlobalType ().GetMethod (name, bindingAttr, binder, callConvention, types, modifiers);
171                 }
172         
173                 public MethodInfo[] GetMethods () 
174                 {
175                         if (IsResource ())
176                                 return new MethodInfo [0];
177
178                         return GetGlobalType ().GetMethods ();
179                 }
180
181 #if NET_2_0
182                 public MethodInfo[] GetMethods (BindingFlags flags) {
183                         if (IsResource ())
184                                 return new MethodInfo [0];
185
186                         return GetGlobalType ().GetMethods (flags);
187                 }
188
189                 public FieldInfo[] GetFields (BindingFlags flags) 
190                 {
191                         if (IsResource ())
192                                 return new FieldInfo [0];
193
194                         return GetGlobalType ().GetFields (flags);
195                 }
196 #endif
197         
198                 public virtual void GetObjectData (SerializationInfo info, StreamingContext context) 
199                 {
200                         UnitySerializationHolder.GetModuleData (this, info, context);
201                 }
202         
203                 public X509Certificate GetSignerCertificate ()
204                 {
205                         try {
206                                 return X509Certificate.CreateFromSignedFile (assembly.Location);
207                         }
208                         catch {
209                                 return null;
210                         }
211                 }
212         
213                 public virtual Type GetType(string className) 
214                 {
215                         return GetType (className, false, false);
216                 }
217         
218                 public virtual Type GetType(string className, bool ignoreCase) 
219                 {
220                         return GetType (className, false, ignoreCase);
221                 }
222         
223                 public virtual Type GetType(string className, bool throwOnError, bool ignoreCase) 
224                 {
225                         if (className == null)
226                                 throw new ArgumentNullException ("className");
227                         if (className == String.Empty)
228                                 throw new ArgumentException ("Type name can't be empty");
229                         return assembly.InternalGetType (this, className, throwOnError, ignoreCase);
230                 }
231
232                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
233                 private extern Type[] InternalGetTypes ();
234         
235                 public virtual Type[] GetTypes() 
236                 {
237                         return InternalGetTypes ();
238                 }
239         
240                 public virtual bool IsDefined (Type attributeType, bool inherit) 
241                 {
242                         return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
243                 }
244         
245                 public bool IsResource()
246                 {
247                         return is_resource;
248                 }
249         
250                 public override string ToString () 
251                 {
252                         return name;
253                 }
254
255 #if NET_2_0 || BOOTSTRAP_NET_2_0
256                 public
257 #else
258                 internal
259 #endif
260                 Guid Mvid {
261                         get {
262                                 return Mono_GetGuid (this);
263                         }
264                 }
265
266 #if NET_2_0
267                 private Exception resolve_token_exception (int metadataToken, ResolveTokenError error, string tokenType) {
268                         if (error == ResolveTokenError.OutOfRange)
269                                 return new ArgumentOutOfRangeException ("metadataToken", String.Format ("Token 0x{0:x} is not valid in the scope of module {1}", metadataToken, name));
270                         else
271                                 return new ArgumentException (String.Format ("Token 0x{0:x} is not a valid {1} token in the scope of module {2}", metadataToken, tokenType, name), "metadataToken");
272                 }
273
274                 public FieldInfo ResolveField (int metadataToken) {
275                         ResolveTokenError error;
276
277                         IntPtr handle = ResolveFieldToken (_impl, metadataToken, out error);
278                         if (handle == IntPtr.Zero)
279                                 throw resolve_token_exception (metadataToken, error, "Field");
280                         else
281                                 return FieldInfo.GetFieldFromHandle (new RuntimeFieldHandle (handle));
282                 }
283
284                 public MemberInfo ResolveMember (int metadataToken) {
285                         ResolveTokenError error;
286
287                         MemberInfo m = ResolveMemberToken (_impl, metadataToken, out error);
288                         if (m == null)
289                                 throw resolve_token_exception (metadataToken, error, "MemberInfo");
290                         else
291                                 return m;
292                 }
293
294                 public MethodBase ResolveMethod (int metadataToken) {
295                         ResolveTokenError error;
296
297                         IntPtr handle = ResolveMethodToken (_impl, metadataToken, out error);
298                         if (handle == IntPtr.Zero)
299                                 throw resolve_token_exception (metadataToken, error, "MethodBase");
300                         else
301                                 return MethodBase.GetMethodFromHandle (new RuntimeMethodHandle (handle));
302                 }
303
304                 public string ResolveString (int metadataToken) {
305                         ResolveTokenError error;
306
307                         string s = ResolveStringToken (_impl, metadataToken, out error);
308                         if (s == null)
309                                 throw resolve_token_exception (metadataToken, error, "string");
310                         else
311                                 return s;
312                 }
313
314                 public Type ResolveType (int metadataToken) {
315                         ResolveTokenError error;
316
317                         IntPtr handle = ResolveTypeToken (_impl, metadataToken, out error);
318                         if (handle == IntPtr.Zero)
319                                 throw resolve_token_exception (metadataToken, error, "Type");
320                         else
321                                 return Type.GetTypeFromHandle (new RuntimeTypeHandle (handle));
322                 }
323 #endif
324
325                 // Mono Extension: returns the GUID of this module
326                 internal static Guid Mono_GetGuid (Module module)
327                 {
328                         return new Guid (module.GetGuidInternal ());
329                 }
330
331                 private static bool filter_by_type_name (Type m, object filterCriteria) {
332                         string s = (string)filterCriteria;
333                         if (s.EndsWith ("*"))
334                                 return m.Name.StartsWith (s.Substring (0, s.Length - 1));
335                         else
336                                 return m.Name == s;
337                 }
338
339                 private static bool filter_by_type_name_ignore_case (Type m, object filterCriteria) {
340                         string s = (string)filterCriteria;
341                         if (s.EndsWith ("*"))
342                                 return m.Name.ToLower ().StartsWith (s.Substring (0, s.Length - 1).ToLower ());
343                         else
344                                 return String.Compare (m.Name, s, true) == 0;
345                 }
346
347                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
348                 private extern string GetGuidInternal ();
349
350                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
351                 private extern Type GetGlobalType ();
352
353                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
354                 private extern void Close ();
355
356                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
357                 internal static extern IntPtr ResolveTypeToken (IntPtr module, int token, out ResolveTokenError error);
358
359                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
360                 internal static extern IntPtr ResolveMethodToken (IntPtr module, int token, out ResolveTokenError error);
361
362                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
363                 internal static extern IntPtr ResolveFieldToken (IntPtr module, int token, out ResolveTokenError error);
364
365                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
366                 internal static extern string ResolveStringToken (IntPtr module, int token, out ResolveTokenError error);
367
368                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
369                 internal static extern MemberInfo ResolveMemberToken (IntPtr module, int token, out ResolveTokenError error);
370
371                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
372                 internal static extern void GetPEKind (IntPtr module, out PortableExecutableKind peKind, out ImageFileMachine machine);
373         }
374 }