Switch to compiler-tester
[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         [ClassInterfaceAttribute (ClassInterfaceType.None)]
48         [ComDefaultInterfaceAttribute (typeof (_Module))]
49 #endif
50         [Serializable]
51         public class Module : ISerializable, ICustomAttributeProvider {
52         
53                 public static readonly TypeFilter FilterTypeName;
54                 public static readonly TypeFilter FilterTypeNameIgnoreCase;
55         
56                 private IntPtr _impl; /* a pointer to a MonoImage */
57                 internal Assembly assembly;
58                 internal string fqname;
59                 internal string name;
60                 internal string scopename;
61                 internal bool is_resource;
62                 internal int token;
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 (SecurityManager.SecurityEnabled) {
82                                         new FileIOPermission (FileIOPermissionAccess.PathDiscovery, fqname).Demand ();
83                                 }
84                                 return fqname;
85                         }
86                 }
87
88                 // Note: we do not ask for PathDiscovery because no path is returned here.
89                 // However MS Fx requires it (see FDBK23572 for details).
90                 public string Name {
91                         get { return name; }
92                 }
93         
94                 public string ScopeName {
95                         get { return scopename; }
96                 }
97
98 #if NET_2_0
99                 public ModuleHandle ModuleHandle {
100                         get {
101                                 return new ModuleHandle (_impl);
102                         }
103                 }
104
105                 public extern int MetadataToken {
106                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
107                         get;
108                 }               
109 #endif
110         
111                 public virtual Type[] FindTypes(TypeFilter filter, object filterCriteria) 
112                 {
113                         System.Collections.ArrayList filtered = new System.Collections.ArrayList ();
114                         Type[] types = GetTypes ();
115                         foreach (Type t in types)
116                                 if (filter (t, filterCriteria))
117                                         filtered.Add (t);
118                         return (Type[])filtered.ToArray (typeof(Type));
119                 }
120         
121                 public virtual object[] GetCustomAttributes(bool inherit) 
122                 {
123                         return MonoCustomAttrs.GetCustomAttributes (this, inherit);
124                 }
125         
126                 public virtual object[] GetCustomAttributes(Type attributeType, bool inherit) 
127                 {
128                         return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
129                 }
130         
131                 public FieldInfo GetField (string name) 
132                 {
133                         if (IsResource ())
134                                 return null;
135
136                         Type globalType = GetGlobalType ();
137                         return (globalType != null) ? globalType.GetField (name, BindingFlags.Public | BindingFlags.Static) : null;
138                 }
139         
140                 public FieldInfo GetField (string name, BindingFlags flags) 
141                 {
142                         if (IsResource ())
143                                 return null;
144
145                         Type globalType = GetGlobalType ();
146                         return (globalType != null) ? globalType.GetField (name, flags) : null;
147                 }
148         
149                 public FieldInfo[] GetFields () 
150                 {
151                         if (IsResource ())
152                                 return new FieldInfo [0];
153
154                         Type globalType = GetGlobalType ();
155                         return (globalType != null) ? globalType.GetFields (BindingFlags.Public | BindingFlags.Static) : new FieldInfo [0];
156                 }
157         
158                 public MethodInfo GetMethod (string name) 
159                 {
160                         return GetMethodImpl (name, defaultBindingFlags, null, CallingConventions.Any, Type.EmptyTypes, null);
161                 }
162         
163                 public MethodInfo GetMethod (string name, Type[] types) 
164                 {
165                         return GetMethodImpl (name, defaultBindingFlags, null, CallingConventions.Any, types, null);
166                 }
167         
168                 public MethodInfo GetMethod (string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) 
169                 {
170                         return GetMethodImpl (name, bindingAttr, binder, callConvention, types, modifiers);
171                 }
172         
173                 protected virtual MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) 
174                 {
175                         if (IsResource ())
176                                 return null;
177
178                         Type globalType = GetGlobalType ();
179                         return (globalType != null) ? globalType.GetMethod (name, bindingAttr, binder, callConvention, types, modifiers) : null;
180                 }
181         
182                 public MethodInfo[] GetMethods () 
183                 {
184                         if (IsResource ())
185                                 return new MethodInfo [0];
186
187                         Type globalType = GetGlobalType ();
188                         return (globalType != null) ? globalType.GetMethods () : new MethodInfo [0];
189                 }
190
191 #if NET_2_0
192                 public MethodInfo[] GetMethods (BindingFlags flags) {
193                         if (IsResource ())
194                                 return new MethodInfo [0];
195
196                         Type globalType = GetGlobalType ();
197                         return (globalType != null) ? globalType.GetMethods (flags) : new MethodInfo [0];
198                 }
199
200                 public FieldInfo[] GetFields (BindingFlags flags) 
201                 {
202                         if (IsResource ())
203                                 return new FieldInfo [0];
204
205                         Type globalType = GetGlobalType ();
206                         return (globalType != null) ? globalType.GetFields (flags) : new FieldInfo [0];
207                 }
208 #endif
209         
210                 [SecurityPermission (SecurityAction.LinkDemand, SerializationFormatter = true)]
211                 public virtual void GetObjectData (SerializationInfo info, StreamingContext context) 
212                 {
213                         if (info == null)
214                                 throw new ArgumentNullException ("info");
215
216                         UnitySerializationHolder.GetModuleData (this, info, context);
217                 }
218         
219                 public X509Certificate GetSignerCertificate ()
220                 {
221                         try {
222                                 return X509Certificate.CreateFromSignedFile (assembly.Location);
223                         }
224                         catch {
225                                 return null;
226                         }
227                 }
228
229 #if NET_2_0
230                 [ComVisible (true)]
231 #endif
232                 public virtual Type GetType(string className) 
233                 {
234                         return GetType (className, false, false);
235                 }
236
237 #if NET_2_0
238                 [ComVisible (true)]
239 #endif  
240                 public virtual Type GetType(string className, bool ignoreCase) 
241                 {
242                         return GetType (className, false, ignoreCase);
243                 }
244         
245 #if NET_2_0
246                 [ComVisible (true)]
247 #endif
248                 public virtual Type GetType(string className, bool throwOnError, bool ignoreCase) 
249                 {
250                         if (className == null)
251                                 throw new ArgumentNullException ("className");
252                         if (className == String.Empty)
253                                 throw new ArgumentException ("Type name can't be empty");
254                         return assembly.InternalGetType (this, className, throwOnError, ignoreCase);
255                 }
256
257                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
258                 private extern Type[] InternalGetTypes ();
259         
260                 public virtual Type[] GetTypes() 
261                 {
262                         return InternalGetTypes ();
263                 }
264         
265                 public virtual bool IsDefined (Type attributeType, bool inherit) 
266                 {
267                         return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
268                 }
269         
270                 public bool IsResource()
271                 {
272                         return is_resource;
273                 }
274         
275                 public override string ToString () 
276                 {
277                         return name;
278                 }
279
280 #if NET_2_0
281                 [Obsolete ("Please use ModuleVersionId instead - this will be removed before Whidbey ships.")]
282                 public
283 #else
284                 internal 
285 #endif
286                 Guid MvId {
287                         get {
288                                 return Mono_GetGuid (this);
289                         }
290                 }
291
292 #if NET_2_0
293                 public Guid ModuleVersionId {
294                         get {
295                                 return Mono_GetGuid (this);
296                         }
297                 }
298
299                 public void GetPEKind (out PortableExecutableKinds peKind, out ImageFileMachine machine) {
300                         ModuleHandle.GetPEKind (out peKind, out machine);
301                 }
302 #endif
303                 
304
305 #if NET_2_0
306                 private Exception resolve_token_exception (int metadataToken, ResolveTokenError error, string tokenType) {
307                         if (error == ResolveTokenError.OutOfRange)
308                                 return new ArgumentOutOfRangeException ("metadataToken", String.Format ("Token 0x{0:x} is not valid in the scope of module {1}", metadataToken, name));
309                         else
310                                 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");
311                 }
312
313                 [Obsolete ("Please use ResolveField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) - this will be removed before Whidbey ships.")]
314                 public FieldInfo ResolveField (int metadataToken) {
315                         ResolveTokenError error;
316
317                         IntPtr handle = ResolveFieldToken (_impl, metadataToken, out error);
318                         if (handle == IntPtr.Zero)
319                                 throw resolve_token_exception (metadataToken, error, "Field");
320                         else
321                                 return FieldInfo.GetFieldFromHandle (new RuntimeFieldHandle (handle));
322                 }
323
324                 public MemberInfo ResolveMember (int metadataToken) {
325                         ResolveTokenError error;
326
327                         MemberInfo m = ResolveMemberToken (_impl, metadataToken, out error);
328                         if (m == null)
329                                 throw resolve_token_exception (metadataToken, error, "MemberInfo");
330                         else
331                                 return m;
332                 }
333
334                 [Obsolete ("Please use ResolveMethod(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) - this will be removed before Whidbey ships.")]
335                 public MethodBase ResolveMethod (int metadataToken) {
336                         ResolveTokenError error;
337
338                         IntPtr handle = ResolveMethodToken (_impl, metadataToken, out error);
339                         if (handle == IntPtr.Zero)
340                                 throw resolve_token_exception (metadataToken, error, "MethodBase");
341                         else
342                                 return MethodBase.GetMethodFromHandle (new RuntimeMethodHandle (handle));
343                 }
344
345                 public string ResolveString (int metadataToken) {
346                         ResolveTokenError error;
347
348                         string s = ResolveStringToken (_impl, metadataToken, out error);
349                         if (s == null)
350                                 throw resolve_token_exception (metadataToken, error, "string");
351                         else
352                                 return s;
353                 }
354
355                 [Obsolete ("Please use ResolveType(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) - this will be removed before Whidbey ships.")]
356                 public Type ResolveType (int metadataToken) {
357                         ResolveTokenError error;
358
359                         IntPtr handle = ResolveTypeToken (_impl, metadataToken, out error);
360                         if (handle == IntPtr.Zero)
361                                 throw resolve_token_exception (metadataToken, error, "Type");
362                         else
363                                 return Type.GetTypeFromHandle (new RuntimeTypeHandle (handle));
364                 }
365 #endif
366
367                 internal static Type MonoDebugger_ResolveType (Module module, int token)
368                 {
369                         ResolveTokenError error;
370
371                         IntPtr handle = ResolveTypeToken (module._impl, token, out error);
372                         if (handle == IntPtr.Zero)
373                                 return null;
374                         else
375                                 return Type.GetTypeFromHandle (new RuntimeTypeHandle (handle));
376                 }
377
378                 // Mono Extension: returns the GUID of this module
379                 internal static Guid Mono_GetGuid (Module module)
380                 {
381                         return new Guid (module.GetGuidInternal ());
382                 }
383
384                 private static bool filter_by_type_name (Type m, object filterCriteria) {
385                         string s = (string)filterCriteria;
386                         if (s.EndsWith ("*"))
387                                 return m.Name.StartsWith (s.Substring (0, s.Length - 1));
388                         else
389                                 return m.Name == s;
390                 }
391
392                 private static bool filter_by_type_name_ignore_case (Type m, object filterCriteria) {
393                         string s = (string)filterCriteria;
394                         if (s.EndsWith ("*"))
395                                 return m.Name.ToLower ().StartsWith (s.Substring (0, s.Length - 1).ToLower ());
396                         else
397                                 return String.Compare (m.Name, s, true) == 0;
398                 }
399
400                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
401                 private extern string GetGuidInternal ();
402
403                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
404                 private extern Type GetGlobalType ();
405
406                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
407                 internal static extern IntPtr ResolveTypeToken (IntPtr module, int token, out ResolveTokenError error);
408
409                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
410                 internal static extern IntPtr ResolveMethodToken (IntPtr module, int token, out ResolveTokenError error);
411
412                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
413                 internal static extern IntPtr ResolveFieldToken (IntPtr module, int token, out ResolveTokenError error);
414
415                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
416                 internal static extern string ResolveStringToken (IntPtr module, int token, out ResolveTokenError error);
417
418                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
419                 internal static extern MemberInfo ResolveMemberToken (IntPtr module, int token, out ResolveTokenError error);
420
421                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
422                 internal static extern void GetPEKind (IntPtr module, out PortableExecutableKinds peKind, out ImageFileMachine machine);
423         }
424 }