af0ad89c17327d7862d5761e87fcb80f84c1f0fe
[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                 public ModuleHandle ModuleHandle {
94                         get {
95                                 return new ModuleHandle (_impl);
96                         }
97                 }
98
99                 public extern int MetadataToken {
100                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
101                         get;
102                 }               
103 #endif
104         
105                 public virtual Type[] FindTypes(TypeFilter filter, object filterCriteria) 
106                 {
107                         System.Collections.ArrayList filtered = new System.Collections.ArrayList ();
108                         Type[] types = GetTypes ();
109                         foreach (Type t in types)
110                                 if (filter (t, filterCriteria))
111                                         filtered.Add (t);
112                         return (Type[])filtered.ToArray (typeof(Type));
113                 }
114         
115                 public virtual object[] GetCustomAttributes(bool inherit) 
116                 {
117                         return MonoCustomAttrs.GetCustomAttributes (this, inherit);
118                 }
119         
120                 public virtual object[] GetCustomAttributes(Type attributeType, bool inherit) 
121                 {
122                         return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
123                 }
124         
125                 public FieldInfo GetField (string name) 
126                 {
127                         if (IsResource ())
128                                 return null;
129
130                         return GetGlobalType ().GetField (name, BindingFlags.Public | BindingFlags.Static);
131                 }
132         
133                 public FieldInfo GetField (string name, BindingFlags flags) 
134                 {
135                         if (IsResource ())
136                                 return null;
137
138                         return GetGlobalType ().GetField (name, flags);
139                 }
140         
141                 public FieldInfo[] GetFields () 
142                 {
143                         if (IsResource ())
144                                 return new FieldInfo [0];
145
146                         return GetGlobalType ().GetFields (BindingFlags.Public | BindingFlags.Static);
147                 }
148         
149                 public MethodInfo GetMethod (string name) 
150                 {
151                         return GetMethodImpl (name, defaultBindingFlags, null, CallingConventions.Any, Type.EmptyTypes, null);
152                 }
153         
154                 public MethodInfo GetMethod (string name, Type[] types) 
155                 {
156                         return GetMethodImpl (name, defaultBindingFlags, null, CallingConventions.Any, types, null);
157                 }
158         
159                 public MethodInfo GetMethod (string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) 
160                 {
161                         return GetMethodImpl (name, bindingAttr, binder, callConvention, types, modifiers);
162                 }
163         
164                 protected virtual MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) 
165                 {
166                         if (IsResource ())
167                                 return null;
168
169                         return GetGlobalType ().GetMethod (name, bindingAttr, binder, callConvention, types, modifiers);
170                 }
171         
172                 public MethodInfo[] GetMethods () 
173                 {
174                         if (IsResource ())
175                                 return new MethodInfo [0];
176
177                         return GetGlobalType ().GetMethods ();
178                 }
179         
180                 public virtual void GetObjectData (SerializationInfo info, StreamingContext context) 
181                 {
182                         UnitySerializationHolder.GetModuleData (this, info, context);
183                 }
184         
185                 public X509Certificate GetSignerCertificate ()
186                 {
187                         try {
188                                 return X509Certificate.CreateFromSignedFile (assembly.Location);
189                         }
190                         catch {
191                                 return null;
192                         }
193                 }
194         
195                 public virtual Type GetType(string className) 
196                 {
197                         return GetType (className, false, false);
198                 }
199         
200                 public virtual Type GetType(string className, bool ignoreCase) 
201                 {
202                         return GetType (className, false, ignoreCase);
203                 }
204         
205                 public virtual Type GetType(string className, bool throwOnError, bool ignoreCase) 
206                 {
207                         if (className == null)
208                                 throw new ArgumentNullException ("className");
209                         if (className == String.Empty)
210                                 throw new ArgumentException ("Type name can't be empty");
211                         return assembly.InternalGetType (this, className, throwOnError, ignoreCase);
212                 }
213
214                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
215                 private extern Type[] InternalGetTypes ();
216         
217                 public virtual Type[] GetTypes() 
218                 {
219                         return InternalGetTypes ();
220                 }
221         
222                 public virtual bool IsDefined (Type attributeType, bool inherit) 
223                 {
224                         return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
225                 }
226         
227                 public bool IsResource()
228                 {
229                         return is_resource;
230                 }
231         
232                 public override string ToString () 
233                 {
234                         return name;
235                 }
236
237 #if NET_2_0 || BOOTSTRAP_NET_2_0
238                 public
239 #else
240                 internal
241 #endif
242                 Guid Mvid {
243                         get {
244                                 return Mono_GetGuid (this);
245                         }
246                 }
247
248 #if NET_2_0
249                 private Exception resolve_token_exception (int metadataToken, ResolveTokenError error, string tokenType) {
250                         if (error == ResolveTokenError.OutOfRange)
251                                 return new ArgumentOutOfRangeException ("metadataToken", String.Format ("Token 0x{0:x} is not valid in the scope of module {1}", metadataToken, name));
252                         else
253                                 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");
254                 }
255
256                 public FieldInfo ResolveField (int metadataToken) {
257                         ResolveTokenError error;
258
259                         IntPtr handle = ResolveFieldToken (_impl, metadataToken, out error);
260                         if (handle == IntPtr.Zero)
261                                 throw resolve_token_exception (metadataToken, error, "Field");
262                         else
263                                 return FieldInfo.GetFieldFromHandle (new RuntimeFieldHandle (handle));
264                 }
265
266                 [MonoTODO]
267                 public MemberInfo ResolveMember (int metadataToken) {
268                         ResolveTokenError error;
269
270                         MemberInfo m = ResolveMemberToken (_impl, metadataToken, out error);
271                         if (m == null)
272                                 throw resolve_token_exception (metadataToken, error, "MemberInfo");
273                         else
274                                 return m;
275                 }
276
277                 public MethodBase ResolveMethod (int metadataToken) {
278                         ResolveTokenError error;
279
280                         IntPtr handle = ResolveMethodToken (_impl, metadataToken, out error);
281                         if (handle == IntPtr.Zero)
282                                 throw resolve_token_exception (metadataToken, error, "MethodBase");
283                         else
284                                 return MethodBase.GetMethodFromHandle (new RuntimeMethodHandle (handle));
285                 }
286
287                 public string ResolveString (int metadataToken) {
288                         ResolveTokenError error;
289
290                         string s = ResolveStringToken (_impl, metadataToken, out error);
291                         if (s == null)
292                                 throw resolve_token_exception (metadataToken, error, "string");
293                         else
294                                 return s;
295                 }
296
297                 public Type ResolveType (int metadataToken) {
298                         ResolveTokenError error;
299
300                         IntPtr handle = ResolveTypeToken (_impl, metadataToken, out error);
301                         if (handle == IntPtr.Zero)
302                                 throw resolve_token_exception (metadataToken, error, "Type");
303                         else
304                                 return Type.GetTypeFromHandle (new RuntimeTypeHandle (handle));
305                 }
306 #endif
307
308                 // Mono Extension: returns the GUID of this module
309                 internal static Guid Mono_GetGuid (Module module)
310                 {
311                         return new Guid (module.GetGuidInternal ());
312                 }
313
314                 private static bool filter_by_type_name (Type m, object filterCriteria) {
315                         string s = (string)filterCriteria;
316                         if (s.EndsWith ("*"))
317                                 return m.Name.StartsWith (s.Substring (0, s.Length - 1));
318                         else
319                                 return m.Name == s;
320                 }
321
322                 private static bool filter_by_type_name_ignore_case (Type m, object filterCriteria) {
323                         string s = (string)filterCriteria;
324                         if (s.EndsWith ("*"))
325                                 return m.Name.ToLower ().StartsWith (s.Substring (0, s.Length - 1).ToLower ());
326                         else
327                                 return String.Compare (m.Name, s, true) == 0;
328                 }
329
330                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
331                 private extern string GetGuidInternal ();
332
333                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
334                 private extern Type GetGlobalType ();
335
336                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
337                 private extern void Close ();
338
339                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
340                 internal static extern IntPtr ResolveTypeToken (IntPtr module, int token, out ResolveTokenError error);
341
342                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
343                 internal static extern IntPtr ResolveMethodToken (IntPtr module, int token, out ResolveTokenError error);
344
345                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
346                 internal static extern IntPtr ResolveFieldToken (IntPtr module, int token, out ResolveTokenError error);
347
348                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
349                 internal static extern string ResolveStringToken (IntPtr module, int token, out ResolveTokenError error);
350
351                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
352                 internal static extern MemberInfo ResolveMemberToken (IntPtr module, int token, out ResolveTokenError error);
353
354                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
355                 internal static extern void GetPEKind (IntPtr module, out PortableExecutableKind peKind, out ImageFileMachine machine);
356         }
357 }