2010-01-20 Zoltan Varga <vargaz@gmail.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         [ComVisible (true)]
46         [ComDefaultInterfaceAttribute (typeof (_Module))]
47         [Serializable]
48         [ClassInterfaceAttribute (ClassInterfaceType.None)]
49         public class Module : ISerializable, ICustomAttributeProvider, _Module {
50         
51                 public static readonly TypeFilter FilterTypeName;
52                 public static readonly TypeFilter FilterTypeNameIgnoreCase;
53         
54 #pragma warning disable 649     
55                 private IntPtr _impl; /* a pointer to a MonoImage */
56                 internal Assembly assembly;
57                 internal string fqname;
58                 internal string name;
59                 internal string scopename;
60                 internal bool is_resource;
61                 internal int token;
62 #pragma warning restore 649             
63         
64                 const BindingFlags defaultBindingFlags = 
65                         BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance;
66                 
67                 static Module () {
68                         FilterTypeName = new TypeFilter (filter_by_type_name);
69                         FilterTypeNameIgnoreCase = new TypeFilter (filter_by_type_name_ignore_case);
70                 }
71
72                 internal Module () {
73                 }
74
75                 public Assembly Assembly {
76                         get { return assembly; }
77                 }
78         
79                 public virtual string FullyQualifiedName {
80                         get {
81 #if !NET_2_1
82                                 if (SecurityManager.SecurityEnabled) {
83                                         new FileIOPermission (FileIOPermissionAccess.PathDiscovery, fqname).Demand ();
84                                 }
85 #endif
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                 public ModuleHandle ModuleHandle {
101                         get {
102                                 return new ModuleHandle (_impl);
103                         }
104                 }
105
106                 public extern int MetadataToken {
107                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
108                         get;
109                 }
110
111                 public int MDStreamVersion {
112                         get {
113                                 if (_impl == IntPtr.Zero)
114                                         throw new NotSupportedException ();
115                                 return GetMDStreamVersion (_impl);
116                         }
117                 }
118
119                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
120                 internal static extern int GetMDStreamVersion (IntPtr module_handle);
121         
122                 public virtual Type[] FindTypes(TypeFilter filter, object filterCriteria) 
123                 {
124                         System.Collections.ArrayList filtered = new System.Collections.ArrayList ();
125                         Type[] types = GetTypes ();
126                         foreach (Type t in types)
127                                 if (filter (t, filterCriteria))
128                                         filtered.Add (t);
129                         return (Type[])filtered.ToArray (typeof(Type));
130                 }
131         
132                 public virtual object[] GetCustomAttributes(bool inherit) 
133                 {
134                         return MonoCustomAttrs.GetCustomAttributes (this, inherit);
135                 }
136         
137                 public virtual object[] GetCustomAttributes(Type attributeType, bool inherit) 
138                 {
139                         return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
140                 }
141         
142                 public FieldInfo GetField (string name) 
143                 {
144                         if (IsResource ())
145                                 return null;
146
147                         Type globalType = GetGlobalType ();
148                         return (globalType != null) ? globalType.GetField (name, BindingFlags.Public | BindingFlags.Static) : null;
149                 }
150         
151                 public FieldInfo GetField (string name, BindingFlags bindingAttr) 
152                 {
153                         if (IsResource ())
154                                 return null;
155
156                         Type globalType = GetGlobalType ();
157                         return (globalType != null) ? globalType.GetField (name, bindingAttr) : null;
158                 }
159         
160                 public FieldInfo[] GetFields () 
161                 {
162                         if (IsResource ())
163                                 return new FieldInfo [0];
164
165                         Type globalType = GetGlobalType ();
166                         return (globalType != null) ? globalType.GetFields (BindingFlags.Public | BindingFlags.Static) : new FieldInfo [0];
167                 }
168         
169                 public MethodInfo GetMethod (string name) 
170                 {
171                         // Can't call the other overloads since they call Type.GetMethod () which does a null check on the 'types' array
172                         if (IsResource ())
173                                 return null;
174
175                         Type globalType = GetGlobalType ();
176                         return (globalType != null) ? globalType.GetMethod (name) : null;
177                 }
178         
179                 public MethodInfo GetMethod (string name, Type[] types) 
180                 {
181                         return GetMethodImpl (name, defaultBindingFlags, null, CallingConventions.Any, types, null);
182                 }
183         
184                 public MethodInfo GetMethod (string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) 
185                 {
186                         return GetMethodImpl (name, bindingAttr, binder, callConvention, types, modifiers);
187                 }
188         
189                 protected virtual MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) 
190                 {
191                         if (IsResource ())
192                                 return null;
193
194                         Type globalType = GetGlobalType ();
195                         return (globalType != null) ? globalType.GetMethod (name, bindingAttr, binder, callConvention, types, modifiers) : null;
196                 }
197         
198                 public MethodInfo[] GetMethods () 
199                 {
200                         if (IsResource ())
201                                 return new MethodInfo [0];
202
203                         Type globalType = GetGlobalType ();
204                         return (globalType != null) ? globalType.GetMethods () : new MethodInfo [0];
205                 }
206
207                 public MethodInfo[] GetMethods (BindingFlags bindingFlags) {
208                         if (IsResource ())
209                                 return new MethodInfo [0];
210
211                         Type globalType = GetGlobalType ();
212                         return (globalType != null) ? globalType.GetMethods (bindingFlags) : new MethodInfo [0];
213                 }
214
215                 public FieldInfo[] GetFields (BindingFlags bindingFlags)
216                 {
217                         if (IsResource ())
218                                 return new FieldInfo [0];
219
220                         Type globalType = GetGlobalType ();
221                         return (globalType != null) ? globalType.GetFields (bindingFlags) : new FieldInfo [0];
222                 }
223         
224                 [SecurityPermission (SecurityAction.LinkDemand, SerializationFormatter = true)]
225                 public virtual void GetObjectData (SerializationInfo info, StreamingContext context) 
226                 {
227                         if (info == null)
228                                 throw new ArgumentNullException ("info");
229
230                         UnitySerializationHolder.GetModuleData (this, info, context);
231                 }
232
233 #if !NET_2_1
234                 public X509Certificate GetSignerCertificate ()
235                 {
236                         try {
237                                 return X509Certificate.CreateFromSignedFile (assembly.Location);
238                         }
239                         catch {
240                                 return null;
241                         }
242                 }
243 #endif
244
245                 [ComVisible (true)]
246                 public virtual Type GetType(string className) 
247                 {
248                         return GetType (className, false, false);
249                 }
250
251                 [ComVisible (true)]
252                 public virtual Type GetType(string className, bool ignoreCase) 
253                 {
254                         return GetType (className, false, ignoreCase);
255                 }
256         
257                 [ComVisible (true)]
258                 public virtual Type GetType(string className, bool throwOnError, bool ignoreCase) 
259                 {
260                         if (className == null)
261                                 throw new ArgumentNullException ("className");
262                         if (className == String.Empty)
263                                 throw new ArgumentException ("Type name can't be empty");
264                         return assembly.InternalGetType (this, className, throwOnError, ignoreCase);
265                 }
266
267                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
268                 private extern Type[] InternalGetTypes ();
269         
270                 public virtual Type[] GetTypes() 
271                 {
272                         return InternalGetTypes ();
273                 }
274         
275                 public virtual bool IsDefined (Type attributeType, bool inherit) 
276                 {
277                         return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
278                 }
279         
280                 public bool IsResource()
281                 {
282                         return is_resource;
283                 }
284         
285                 public override string ToString () 
286                 {
287                         return name;
288                 }
289
290                 internal Guid MvId {
291                         get {
292                                 return GetModuleVersionId ();
293                         }
294                 }
295
296                 public Guid ModuleVersionId {
297                         get {
298                                 return GetModuleVersionId ();
299                         }
300                 }
301
302                 public void GetPEKind (out PortableExecutableKinds peKind, out ImageFileMachine machine) {
303                         ModuleHandle.GetPEKind (out peKind, out machine);
304                 }
305                 
306
307                 private Exception resolve_token_exception (int metadataToken, ResolveTokenError error, string tokenType) {
308                         if (error == ResolveTokenError.OutOfRange)
309                                 return new ArgumentOutOfRangeException ("metadataToken", String.Format ("Token 0x{0:x} is not valid in the scope of module {1}", metadataToken, name));
310                         else
311                                 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");
312                 }
313
314                 private IntPtr[] ptrs_from_types (Type[] types) {
315                         if (types == null)
316                                 return null;
317                         else {
318                                 IntPtr[] res = new IntPtr [types.Length];
319                                 for (int i = 0; i < types.Length; ++i) {
320                                         if (types [i] == null)
321                                                 throw new ArgumentException ();
322                                         res [i] = types [i].TypeHandle.Value;
323                                 }
324                                 return res;
325                         }
326                 }
327
328                 public FieldInfo ResolveField (int metadataToken) {
329                         return ResolveField (metadataToken, null, null);
330                 }
331
332                 public FieldInfo ResolveField (int metadataToken, Type [] genericTypeArguments, Type [] genericMethodArguments) {
333                         ResolveTokenError error;
334
335                         IntPtr handle = ResolveFieldToken (_impl, metadataToken, ptrs_from_types (genericTypeArguments), ptrs_from_types (genericMethodArguments), out error);
336                         if (handle == IntPtr.Zero)
337                                 throw resolve_token_exception (metadataToken, error, "Field");
338                         else
339                                 return FieldInfo.GetFieldFromHandle (new RuntimeFieldHandle (handle));
340                 }
341
342                 public MemberInfo ResolveMember (int metadataToken) {
343                         return ResolveMember (metadataToken, null, null);
344                 }
345
346                 public MemberInfo ResolveMember (int metadataToken, Type [] genericTypeArguments, Type [] genericMethodArguments) {
347
348                         ResolveTokenError error;
349
350                         MemberInfo m = ResolveMemberToken (_impl, metadataToken, ptrs_from_types (genericTypeArguments), ptrs_from_types (genericMethodArguments), out error);
351                         if (m == null)
352                                 throw resolve_token_exception (metadataToken, error, "MemberInfo");
353                         else
354                                 return m;
355                 }
356
357                 public MethodBase ResolveMethod (int metadataToken) {
358                         return ResolveMethod (metadataToken, null, null);
359                 }
360
361                 public MethodBase ResolveMethod (int metadataToken, Type [] genericTypeArguments, Type [] genericMethodArguments) {
362                         ResolveTokenError error;
363
364                         IntPtr handle = ResolveMethodToken (_impl, metadataToken, ptrs_from_types (genericTypeArguments), ptrs_from_types (genericMethodArguments), out error);
365                         if (handle == IntPtr.Zero)
366                                 throw resolve_token_exception (metadataToken, error, "MethodBase");
367                         else
368                                 return MethodBase.GetMethodFromHandleNoGenericCheck (new RuntimeMethodHandle (handle));
369                 }
370
371                 public string ResolveString (int metadataToken) {
372                         ResolveTokenError error;
373
374                         string s = ResolveStringToken (_impl, metadataToken, out error);
375                         if (s == null)
376                                 throw resolve_token_exception (metadataToken, error, "string");
377                         else
378                                 return s;
379                 }
380
381                 public Type ResolveType (int metadataToken) {
382                         return ResolveType (metadataToken, null, null);
383                 }
384
385                 public Type ResolveType (int metadataToken, Type [] genericTypeArguments, Type [] genericMethodArguments) {
386                         ResolveTokenError error;
387
388                         IntPtr handle = ResolveTypeToken (_impl, metadataToken, ptrs_from_types (genericTypeArguments), ptrs_from_types (genericMethodArguments), out error);
389                         if (handle == IntPtr.Zero)
390                                 throw resolve_token_exception (metadataToken, error, "Type");
391                         else
392                                 return Type.GetTypeFromHandle (new RuntimeTypeHandle (handle));
393                 }
394
395                 public byte[] ResolveSignature (int metadataToken) {
396                         ResolveTokenError error;
397
398                     byte[] res = ResolveSignature (_impl, metadataToken, out error);
399                         if (res == null)
400                                 throw resolve_token_exception (metadataToken, error, "signature");
401                         else
402                                 return res;
403                 }
404
405                 internal static Type MonoDebugger_ResolveType (Module module, int token)
406                 {
407                         ResolveTokenError error;
408
409                         IntPtr handle = ResolveTypeToken (module._impl, token, null, null, out error);
410                         if (handle == IntPtr.Zero)
411                                 return null;
412                         else
413                                 return Type.GetTypeFromHandle (new RuntimeTypeHandle (handle));
414                 }
415
416                 // Used by mcs, the symbol writer, and mdb through reflection
417                 internal static Guid Mono_GetGuid (Module module)
418                 {
419                         return module.GetModuleVersionId ();
420                 }
421
422                 internal virtual Guid GetModuleVersionId ()
423                 {
424                         return new Guid (GetGuidInternal ());
425                 }
426
427                 private static bool filter_by_type_name (Type m, object filterCriteria) {
428                         string s = (string)filterCriteria;
429                         if (s.EndsWith ("*"))
430                                 return m.Name.StartsWith (s.Substring (0, s.Length - 1));
431                         else
432                                 return m.Name == s;
433                 }
434
435                 private static bool filter_by_type_name_ignore_case (Type m, object filterCriteria) {
436                         string s = (string)filterCriteria;
437                         if (s.EndsWith ("*"))
438                                 return m.Name.ToLower ().StartsWith (s.Substring (0, s.Length - 1).ToLower ());
439                         else
440                                 return String.Compare (m.Name, s, true) == 0;
441                 }
442
443                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
444                 internal extern IntPtr GetHINSTANCE ();
445
446                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
447                 private extern string GetGuidInternal ();
448
449                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
450                 private extern Type GetGlobalType ();
451
452                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
453                 internal static extern IntPtr ResolveTypeToken (IntPtr module, int token, IntPtr[] type_args, IntPtr[] method_args, out ResolveTokenError error);
454
455                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
456                 internal static extern IntPtr ResolveMethodToken (IntPtr module, int token, IntPtr[] type_args, IntPtr[] method_args, out ResolveTokenError error);
457
458                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
459                 internal static extern IntPtr ResolveFieldToken (IntPtr module, int token, IntPtr[] type_args, IntPtr[] method_args, out ResolveTokenError error);
460
461                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
462                 internal static extern string ResolveStringToken (IntPtr module, int token, out ResolveTokenError error);
463
464                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
465                 internal static extern MemberInfo ResolveMemberToken (IntPtr module, int token, IntPtr[] type_args, IntPtr[] method_args, out ResolveTokenError error);
466
467                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
468                 internal static extern byte[] ResolveSignature (IntPtr module, int metadataToken, out ResolveTokenError error);
469
470                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
471                 internal static extern void GetPEKind (IntPtr module, out PortableExecutableKinds peKind, out ImageFileMachine machine);
472
473                 void _Module.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
474                 {
475                         throw new NotImplementedException ();
476                 }
477
478                 void _Module.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
479                 {
480                         throw new NotImplementedException ();
481                 }
482
483                 void _Module.GetTypeInfoCount (out uint pcTInfo)
484                 {
485                         throw new NotImplementedException ();
486                 }
487
488                 void _Module.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams,
489                         IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
490                 {
491                         throw new NotImplementedException ();
492                 }
493         }
494 }