2008-11-11 Rodrigo Kumpera <rkumpera@novell.com>
[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 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29
30 using System.Runtime.Serialization;
31 using System.Security.Cryptography.X509Certificates;
32 using System.Runtime.InteropServices;
33 using System.Runtime.CompilerServices;
34 using System.Security;
35 using System.Security.Permissions;
36
37 namespace System.Reflection {
38
39         internal enum ResolveTokenError {
40                 OutOfRange,
41                 BadTable,
42                 Other
43         };
44
45 #if NET_2_0
46         [ComVisible (true)]
47         [ComDefaultInterfaceAttribute (typeof (_Module))]
48 #endif
49         [Serializable]
50         [ClassInterfaceAttribute (ClassInterfaceType.None)]
51         public class Module : ISerializable, ICustomAttributeProvider, _Module {
52         
53                 public static readonly TypeFilter FilterTypeName;
54                 public static readonly TypeFilter FilterTypeNameIgnoreCase;
55         
56 #pragma warning disable 649     
57                 private IntPtr _impl; /* a pointer to a MonoImage */
58                 internal Assembly assembly;
59                 internal string fqname;
60                 internal string name;
61                 internal string scopename;
62                 internal bool is_resource;
63                 internal int token;
64 #pragma warning restore 649             
65         
66                 const BindingFlags defaultBindingFlags = 
67                         BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance;
68                 
69                 static Module () {
70                         FilterTypeName = new TypeFilter (filter_by_type_name);
71                         FilterTypeNameIgnoreCase = new TypeFilter (filter_by_type_name_ignore_case);
72                 }
73
74                 internal Module () {
75                 }
76
77                 public Assembly Assembly {
78                         get { return assembly; }
79                 }
80         
81                 public virtual string FullyQualifiedName {
82                         get {
83                                 if (SecurityManager.SecurityEnabled) {
84                                         new FileIOPermission (FileIOPermissionAccess.PathDiscovery, fqname).Demand ();
85                                 }
86                                 return fqname;
87                         }
88                 }
89
90                 // Note: we do not ask for PathDiscovery because no path is returned here.
91                 // However MS Fx requires it (see FDBK23572 for details).
92                 public string Name {
93                         get { return name; }
94                 }
95         
96                 public string ScopeName {
97                         get { return scopename; }
98                 }
99
100 #if NET_2_0
101                 public ModuleHandle ModuleHandle {
102                         get {
103                                 return new ModuleHandle (_impl);
104                         }
105                 }
106
107                 public extern int MetadataToken {
108                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
109                         get;
110                 }
111
112                 public int MDStreamVersion {
113                         get {
114                                 if (_impl == IntPtr.Zero)
115                                         throw new NotSupportedException ();
116                                 return GetMDStreamVersion (_impl);
117                         }
118                 }
119
120                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
121                 internal static extern int GetMDStreamVersion (IntPtr module_handle);
122 #endif
123         
124                 public virtual Type[] FindTypes(TypeFilter filter, object filterCriteria) 
125                 {
126                         System.Collections.ArrayList filtered = new System.Collections.ArrayList ();
127                         Type[] types = GetTypes ();
128                         foreach (Type t in types)
129                                 if (filter (t, filterCriteria))
130                                         filtered.Add (t);
131                         return (Type[])filtered.ToArray (typeof(Type));
132                 }
133         
134                 public virtual object[] GetCustomAttributes(bool inherit) 
135                 {
136                         return MonoCustomAttrs.GetCustomAttributes (this, inherit);
137                 }
138         
139                 public virtual object[] GetCustomAttributes(Type attributeType, bool inherit) 
140                 {
141                         return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
142                 }
143         
144                 public FieldInfo GetField (string name) 
145                 {
146                         if (IsResource ())
147                                 return null;
148
149                         Type globalType = GetGlobalType ();
150                         return (globalType != null) ? globalType.GetField (name, BindingFlags.Public | BindingFlags.Static) : null;
151                 }
152         
153                 public FieldInfo GetField (string name, BindingFlags bindingAttr) 
154                 {
155                         if (IsResource ())
156                                 return null;
157
158                         Type globalType = GetGlobalType ();
159                         return (globalType != null) ? globalType.GetField (name, bindingAttr) : null;
160                 }
161         
162                 public FieldInfo[] GetFields () 
163                 {
164                         if (IsResource ())
165                                 return new FieldInfo [0];
166
167                         Type globalType = GetGlobalType ();
168                         return (globalType != null) ? globalType.GetFields (BindingFlags.Public | BindingFlags.Static) : new FieldInfo [0];
169                 }
170         
171                 public MethodInfo GetMethod (string name) 
172                 {
173                         // Can't call the other overloads since they call Type.GetMethod () which does a null check on the 'types' array
174                         if (IsResource ())
175                                 return null;
176
177                         Type globalType = GetGlobalType ();
178                         return (globalType != null) ? globalType.GetMethod (name) : null;
179                 }
180         
181                 public MethodInfo GetMethod (string name, Type[] types) 
182                 {
183                         return GetMethodImpl (name, defaultBindingFlags, null, CallingConventions.Any, types, null);
184                 }
185         
186                 public MethodInfo GetMethod (string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) 
187                 {
188                         return GetMethodImpl (name, bindingAttr, binder, callConvention, types, modifiers);
189                 }
190         
191                 protected virtual MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) 
192                 {
193                         if (IsResource ())
194                                 return null;
195
196                         Type globalType = GetGlobalType ();
197                         return (globalType != null) ? globalType.GetMethod (name, bindingAttr, binder, callConvention, types, modifiers) : null;
198                 }
199         
200                 public MethodInfo[] GetMethods () 
201                 {
202                         if (IsResource ())
203                                 return new MethodInfo [0];
204
205                         Type globalType = GetGlobalType ();
206                         return (globalType != null) ? globalType.GetMethods () : new MethodInfo [0];
207                 }
208
209 #if NET_2_0
210                 public MethodInfo[] GetMethods (BindingFlags bindingFlags) {
211                         if (IsResource ())
212                                 return new MethodInfo [0];
213
214                         Type globalType = GetGlobalType ();
215                         return (globalType != null) ? globalType.GetMethods (bindingFlags) : new MethodInfo [0];
216                 }
217
218                 public FieldInfo[] GetFields (BindingFlags bindingFlags)
219                 {
220                         if (IsResource ())
221                                 return new FieldInfo [0];
222
223                         Type globalType = GetGlobalType ();
224                         return (globalType != null) ? globalType.GetFields (bindingFlags) : new FieldInfo [0];
225                 }
226 #endif
227         
228                 [SecurityPermission (SecurityAction.LinkDemand, SerializationFormatter = true)]
229                 public virtual void GetObjectData (SerializationInfo info, StreamingContext context) 
230                 {
231                         if (info == null)
232                                 throw new ArgumentNullException ("info");
233
234                         UnitySerializationHolder.GetModuleData (this, info, context);
235                 }
236         
237                 public X509Certificate GetSignerCertificate ()
238                 {
239                         try {
240                                 return X509Certificate.CreateFromSignedFile (assembly.Location);
241                         }
242                         catch {
243                                 return null;
244                         }
245                 }
246
247 #if NET_2_0
248                 [ComVisible (true)]
249 #endif
250                 public virtual Type GetType(string className) 
251                 {
252                         return GetType (className, false, false);
253                 }
254
255 #if NET_2_0
256                 [ComVisible (true)]
257 #endif  
258                 public virtual Type GetType(string className, bool ignoreCase) 
259                 {
260                         return GetType (className, false, ignoreCase);
261                 }
262         
263 #if NET_2_0
264                 [ComVisible (true)]
265 #endif
266                 public virtual Type GetType(string className, bool throwOnError, bool ignoreCase) 
267                 {
268                         if (className == null)
269                                 throw new ArgumentNullException ("className");
270                         if (className == String.Empty)
271                                 throw new ArgumentException ("Type name can't be empty");
272                         return assembly.InternalGetType (this, className, throwOnError, ignoreCase);
273                 }
274
275                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
276                 private extern Type[] InternalGetTypes ();
277         
278                 public virtual Type[] GetTypes() 
279                 {
280                         return InternalGetTypes ();
281                 }
282         
283                 public virtual bool IsDefined (Type attributeType, bool inherit) 
284                 {
285                         return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
286                 }
287         
288                 public bool IsResource()
289                 {
290                         return is_resource;
291                 }
292         
293                 public override string ToString () 
294                 {
295                         return name;
296                 }
297
298                 internal Guid MvId {
299                         get {
300                                 return Mono_GetGuid (this);
301                         }
302                 }
303
304 #if NET_2_0
305                 public Guid ModuleVersionId {
306                         get {
307                                 return Mono_GetGuid (this);
308                         }
309                 }
310
311                 public void GetPEKind (out PortableExecutableKinds peKind, out ImageFileMachine machine) {
312                         ModuleHandle.GetPEKind (out peKind, out machine);
313                 }
314 #endif
315                 
316
317 #if NET_2_0
318                 private Exception resolve_token_exception (int metadataToken, ResolveTokenError error, string tokenType) {
319                         if (error == ResolveTokenError.OutOfRange)
320                                 return new ArgumentOutOfRangeException ("metadataToken", String.Format ("Token 0x{0:x} is not valid in the scope of module {1}", metadataToken, name));
321                         else
322                                 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");
323                 }
324
325                 private IntPtr[] ptrs_from_types (Type[] types) {
326                         if (types == null)
327                                 return null;
328                         else {
329                                 IntPtr[] res = new IntPtr [types.Length];
330                                 for (int i = 0; i < types.Length; ++i) {
331                                         if (types [i] == null)
332                                                 throw new ArgumentException ();
333                                         res [i] = types [i].TypeHandle.Value;
334                                 }
335                                 return res;
336                         }
337                 }
338
339                 public FieldInfo ResolveField (int metadataToken) {
340                         return ResolveField (metadataToken, null, null);
341                 }
342
343                 public FieldInfo ResolveField (int metadataToken, Type [] genericTypeArguments, Type [] genericMethodArguments) {
344                         ResolveTokenError error;
345
346                         IntPtr handle = ResolveFieldToken (_impl, metadataToken, ptrs_from_types (genericTypeArguments), ptrs_from_types (genericMethodArguments), out error);
347                         if (handle == IntPtr.Zero)
348                                 throw resolve_token_exception (metadataToken, error, "Field");
349                         else
350                                 return FieldInfo.GetFieldFromHandle (new RuntimeFieldHandle (handle));
351                 }
352
353                 public MemberInfo ResolveMember (int metadataToken) {
354                         return ResolveMember (metadataToken, null, null);
355                 }
356
357                 public MemberInfo ResolveMember (int metadataToken, Type [] genericTypeArguments, Type [] genericMethodArguments) {
358
359                         ResolveTokenError error;
360
361                         MemberInfo m = ResolveMemberToken (_impl, metadataToken, ptrs_from_types (genericTypeArguments), ptrs_from_types (genericMethodArguments), out error);
362                         if (m == null)
363                                 throw resolve_token_exception (metadataToken, error, "MemberInfo");
364                         else
365                                 return m;
366                 }
367
368                 public MethodBase ResolveMethod (int metadataToken) {
369                         return ResolveMethod (metadataToken, null, null);
370                 }
371
372                 public MethodBase ResolveMethod (int metadataToken, Type [] genericTypeArguments, Type [] genericMethodArguments) {
373                         ResolveTokenError error;
374
375                         IntPtr handle = ResolveMethodToken (_impl, metadataToken, ptrs_from_types (genericTypeArguments), ptrs_from_types (genericMethodArguments), out error);
376                         if (handle == IntPtr.Zero)
377                                 throw resolve_token_exception (metadataToken, error, "MethodBase");
378                         else
379                                 return MethodBase.GetMethodFromHandleNoGenericCheck (new RuntimeMethodHandle (handle));
380                 }
381
382                 public string ResolveString (int metadataToken) {
383                         ResolveTokenError error;
384
385                         string s = ResolveStringToken (_impl, metadataToken, out error);
386                         if (s == null)
387                                 throw resolve_token_exception (metadataToken, error, "string");
388                         else
389                                 return s;
390                 }
391
392                 public Type ResolveType (int metadataToken) {
393                         return ResolveType (metadataToken, null, null);
394                 }
395
396                 public Type ResolveType (int metadataToken, Type [] genericTypeArguments, Type [] genericMethodArguments) {
397                         ResolveTokenError error;
398
399                         IntPtr handle = ResolveTypeToken (_impl, metadataToken, ptrs_from_types (genericTypeArguments), ptrs_from_types (genericMethodArguments), out error);
400                         if (handle == IntPtr.Zero)
401                                 throw resolve_token_exception (metadataToken, error, "Type");
402                         else
403                                 return Type.GetTypeFromHandle (new RuntimeTypeHandle (handle));
404                 }
405
406                 public byte[] ResolveSignature (int metadataToken) {
407                         ResolveTokenError error;
408
409                     byte[] res = ResolveSignature (_impl, metadataToken, out error);
410                         if (res == null)
411                                 throw resolve_token_exception (metadataToken, error, "signature");
412                         else
413                                 return res;
414                 }
415 #endif
416
417                 internal static Type MonoDebugger_ResolveType (Module module, int token)
418                 {
419                         ResolveTokenError error;
420
421                         IntPtr handle = ResolveTypeToken (module._impl, token, null, null, out error);
422                         if (handle == IntPtr.Zero)
423                                 return null;
424                         else
425                                 return Type.GetTypeFromHandle (new RuntimeTypeHandle (handle));
426                 }
427
428                 // Mono Extension: returns the GUID of this module
429                 internal static Guid Mono_GetGuid (Module module)
430                 {
431                         return new Guid (module.GetGuidInternal ());
432                 }
433
434                 private static bool filter_by_type_name (Type m, object filterCriteria) {
435                         string s = (string)filterCriteria;
436                         if (s.EndsWith ("*"))
437                                 return m.Name.StartsWith (s.Substring (0, s.Length - 1));
438                         else
439                                 return m.Name == s;
440                 }
441
442                 private static bool filter_by_type_name_ignore_case (Type m, object filterCriteria) {
443                         string s = (string)filterCriteria;
444                         if (s.EndsWith ("*"))
445                                 return m.Name.ToLower ().StartsWith (s.Substring (0, s.Length - 1).ToLower ());
446                         else
447                                 return String.Compare (m.Name, s, true) == 0;
448                 }
449
450                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
451                 internal extern IntPtr GetHINSTANCE ();
452
453                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
454                 private extern string GetGuidInternal ();
455
456                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
457                 private extern Type GetGlobalType ();
458
459                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
460                 internal static extern IntPtr ResolveTypeToken (IntPtr module, int token, IntPtr[] type_args, IntPtr[] method_args, out ResolveTokenError error);
461
462                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
463                 internal static extern IntPtr ResolveMethodToken (IntPtr module, int token, IntPtr[] type_args, IntPtr[] method_args, out ResolveTokenError error);
464
465                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
466                 internal static extern IntPtr ResolveFieldToken (IntPtr module, int token, IntPtr[] type_args, IntPtr[] method_args, out ResolveTokenError error);
467
468                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
469                 internal static extern string ResolveStringToken (IntPtr module, int token, out ResolveTokenError error);
470
471                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
472                 internal static extern MemberInfo ResolveMemberToken (IntPtr module, int token, IntPtr[] type_args, IntPtr[] method_args, out ResolveTokenError error);
473
474                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
475                 internal static extern byte[] ResolveSignature (IntPtr module, int metadataToken, out ResolveTokenError error);
476
477                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
478                 internal static extern void GetPEKind (IntPtr module, out PortableExecutableKinds peKind, out ImageFileMachine machine);
479
480 #if NET_1_1
481                 void _Module.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
482                 {
483                         throw new NotImplementedException ();
484                 }
485
486                 void _Module.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
487                 {
488                         throw new NotImplementedException ();
489                 }
490
491                 void _Module.GetTypeInfoCount (out uint pcTInfo)
492                 {
493                         throw new NotImplementedException ();
494                 }
495
496                 void _Module.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams,
497                         IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
498                 {
499                         throw new NotImplementedException ();
500                 }
501 #endif
502         }
503 }