* roottypes.cs: Rename from tree.cs.
[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                 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
110                 public extern int MDStreamVersion {
111                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
112                         get;
113                 }
114 #endif
115         
116                 public virtual Type[] FindTypes(TypeFilter filter, object filterCriteria) 
117                 {
118                         System.Collections.ArrayList filtered = new System.Collections.ArrayList ();
119                         Type[] types = GetTypes ();
120                         foreach (Type t in types)
121                                 if (filter (t, filterCriteria))
122                                         filtered.Add (t);
123                         return (Type[])filtered.ToArray (typeof(Type));
124                 }
125         
126                 public virtual object[] GetCustomAttributes(bool inherit) 
127                 {
128                         return MonoCustomAttrs.GetCustomAttributes (this, inherit);
129                 }
130         
131                 public virtual object[] GetCustomAttributes(Type attributeType, bool inherit) 
132                 {
133                         return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
134                 }
135         
136                 public FieldInfo GetField (string name) 
137                 {
138                         if (IsResource ())
139                                 return null;
140
141                         Type globalType = GetGlobalType ();
142                         return (globalType != null) ? globalType.GetField (name, BindingFlags.Public | BindingFlags.Static) : null;
143                 }
144         
145                 public FieldInfo GetField (string name, BindingFlags flags) 
146                 {
147                         if (IsResource ())
148                                 return null;
149
150                         Type globalType = GetGlobalType ();
151                         return (globalType != null) ? globalType.GetField (name, flags) : null;
152                 }
153         
154                 public FieldInfo[] GetFields () 
155                 {
156                         if (IsResource ())
157                                 return new FieldInfo [0];
158
159                         Type globalType = GetGlobalType ();
160                         return (globalType != null) ? globalType.GetFields (BindingFlags.Public | BindingFlags.Static) : new FieldInfo [0];
161                 }
162         
163                 public MethodInfo GetMethod (string name) 
164                 {
165                         // Can't call the other overloads since they call Type.GetMethod () which does a null check on the 'types' array
166                         if (IsResource ())
167                                 return null;
168
169                         Type globalType = GetGlobalType ();
170                         return (globalType != null) ? globalType.GetMethod (name) : null;
171                 }
172         
173                 public MethodInfo GetMethod (string name, Type[] types) 
174                 {
175                         return GetMethodImpl (name, defaultBindingFlags, null, CallingConventions.Any, types, null);
176                 }
177         
178                 public MethodInfo GetMethod (string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) 
179                 {
180                         return GetMethodImpl (name, bindingAttr, binder, callConvention, types, modifiers);
181                 }
182         
183                 protected virtual MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) 
184                 {
185                         if (IsResource ())
186                                 return null;
187
188                         Type globalType = GetGlobalType ();
189                         return (globalType != null) ? globalType.GetMethod (name, bindingAttr, binder, callConvention, types, modifiers) : null;
190                 }
191         
192                 public MethodInfo[] GetMethods () 
193                 {
194                         if (IsResource ())
195                                 return new MethodInfo [0];
196
197                         Type globalType = GetGlobalType ();
198                         return (globalType != null) ? globalType.GetMethods () : new MethodInfo [0];
199                 }
200
201 #if NET_2_0
202                 public MethodInfo[] GetMethods (BindingFlags flags) {
203                         if (IsResource ())
204                                 return new MethodInfo [0];
205
206                         Type globalType = GetGlobalType ();
207                         return (globalType != null) ? globalType.GetMethods (flags) : new MethodInfo [0];
208                 }
209
210                 public FieldInfo[] GetFields (BindingFlags flags) 
211                 {
212                         if (IsResource ())
213                                 return new FieldInfo [0];
214
215                         Type globalType = GetGlobalType ();
216                         return (globalType != null) ? globalType.GetFields (flags) : new FieldInfo [0];
217                 }
218 #endif
219         
220                 [SecurityPermission (SecurityAction.LinkDemand, SerializationFormatter = true)]
221                 public virtual void GetObjectData (SerializationInfo info, StreamingContext context) 
222                 {
223                         if (info == null)
224                                 throw new ArgumentNullException ("info");
225
226                         UnitySerializationHolder.GetModuleData (this, info, context);
227                 }
228         
229                 public X509Certificate GetSignerCertificate ()
230                 {
231                         try {
232                                 return X509Certificate.CreateFromSignedFile (assembly.Location);
233                         }
234                         catch {
235                                 return null;
236                         }
237                 }
238
239 #if NET_2_0
240                 [ComVisible (true)]
241 #endif
242                 public virtual Type GetType(string className) 
243                 {
244                         return GetType (className, false, false);
245                 }
246
247 #if NET_2_0
248                 [ComVisible (true)]
249 #endif  
250                 public virtual Type GetType(string className, bool ignoreCase) 
251                 {
252                         return GetType (className, false, ignoreCase);
253                 }
254         
255 #if NET_2_0
256                 [ComVisible (true)]
257 #endif
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 Mono_GetGuid (this);
293                         }
294                 }
295
296 #if NET_2_0
297                 public Guid ModuleVersionId {
298                         get {
299                                 return Mono_GetGuid (this);
300                         }
301                 }
302
303                 public void GetPEKind (out PortableExecutableKinds peKind, out ImageFileMachine machine) {
304                         ModuleHandle.GetPEKind (out peKind, out machine);
305                 }
306 #endif
307                 
308
309 #if NET_2_0
310                 private Exception resolve_token_exception (int metadataToken, ResolveTokenError error, string tokenType) {
311                         if (error == ResolveTokenError.OutOfRange)
312                                 return new ArgumentOutOfRangeException ("metadataToken", String.Format ("Token 0x{0:x} is not valid in the scope of module {1}", metadataToken, name));
313                         else
314                                 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");
315                 }
316
317                 public FieldInfo ResolveField (int metadataToken) {
318                         ResolveTokenError error;
319
320                         IntPtr handle = ResolveFieldToken (_impl, metadataToken, out error);
321                         if (handle == IntPtr.Zero)
322                                 throw resolve_token_exception (metadataToken, error, "Field");
323                         else
324                                 return FieldInfo.GetFieldFromHandle (new RuntimeFieldHandle (handle));
325                 }
326
327                 public MemberInfo ResolveMember (int metadataToken) {
328                         ResolveTokenError error;
329
330                         MemberInfo m = ResolveMemberToken (_impl, metadataToken, out error);
331                         if (m == null)
332                                 throw resolve_token_exception (metadataToken, error, "MemberInfo");
333                         else
334                                 return m;
335                 }
336
337                 public MethodBase ResolveMethod (int metadataToken) {
338                         ResolveTokenError error;
339
340                         IntPtr handle = ResolveMethodToken (_impl, metadataToken, out error);
341                         if (handle == IntPtr.Zero)
342                                 throw resolve_token_exception (metadataToken, error, "MethodBase");
343                         else
344                                 return MethodBase.GetMethodFromHandle (new RuntimeMethodHandle (handle));
345                 }
346
347                 public string ResolveString (int metadataToken) {
348                         ResolveTokenError error;
349
350                         string s = ResolveStringToken (_impl, metadataToken, out error);
351                         if (s == null)
352                                 throw resolve_token_exception (metadataToken, error, "string");
353                         else
354                                 return s;
355                 }
356
357                 public Type ResolveType (int metadataToken) {
358                         ResolveTokenError error;
359
360                         IntPtr handle = ResolveTypeToken (_impl, metadataToken, out error);
361                         if (handle == IntPtr.Zero)
362                                 throw resolve_token_exception (metadataToken, error, "Type");
363                         else
364                                 return Type.GetTypeFromHandle (new RuntimeTypeHandle (handle));
365                 }
366
367                 [MonoTODO]
368                 public byte[] ResolveSignature (int metadataToken) {
369                         throw new NotImplementedException ();
370                 }
371 #endif
372
373                 internal static Type MonoDebugger_ResolveType (Module module, int token)
374                 {
375                         ResolveTokenError error;
376
377                         IntPtr handle = ResolveTypeToken (module._impl, token, out error);
378                         if (handle == IntPtr.Zero)
379                                 return null;
380                         else
381                                 return Type.GetTypeFromHandle (new RuntimeTypeHandle (handle));
382                 }
383
384                 // Mono Extension: returns the GUID of this module
385                 internal static Guid Mono_GetGuid (Module module)
386                 {
387                         return new Guid (module.GetGuidInternal ());
388                 }
389
390                 private static bool filter_by_type_name (Type m, object filterCriteria) {
391                         string s = (string)filterCriteria;
392                         if (s.EndsWith ("*"))
393                                 return m.Name.StartsWith (s.Substring (0, s.Length - 1));
394                         else
395                                 return m.Name == s;
396                 }
397
398                 private static bool filter_by_type_name_ignore_case (Type m, object filterCriteria) {
399                         string s = (string)filterCriteria;
400                         if (s.EndsWith ("*"))
401                                 return m.Name.ToLower ().StartsWith (s.Substring (0, s.Length - 1).ToLower ());
402                         else
403                                 return String.Compare (m.Name, s, true) == 0;
404                 }
405
406                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
407                 private extern string GetGuidInternal ();
408
409                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
410                 private extern Type GetGlobalType ();
411
412                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
413                 internal static extern IntPtr ResolveTypeToken (IntPtr module, int token, out ResolveTokenError error);
414
415                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
416                 internal static extern IntPtr ResolveMethodToken (IntPtr module, int token, out ResolveTokenError error);
417
418                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
419                 internal static extern IntPtr ResolveFieldToken (IntPtr module, int token, out ResolveTokenError error);
420
421                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
422                 internal static extern string ResolveStringToken (IntPtr module, int token, out ResolveTokenError error);
423
424                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
425                 internal static extern MemberInfo ResolveMemberToken (IntPtr module, int token, out ResolveTokenError error);
426
427                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
428                 internal static extern void GetPEKind (IntPtr module, out PortableExecutableKinds peKind, out ImageFileMachine machine);
429
430 #if NET_1_1
431                 void _Module.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
432                 {
433                         throw new NotImplementedException ();
434                 }
435
436                 void _Module.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
437                 {
438                         throw new NotImplementedException ();
439                 }
440
441                 void _Module.GetTypeInfoCount (out uint pcTInfo)
442                 {
443                         throw new NotImplementedException ();
444                 }
445
446                 void _Module.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams,
447                         IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
448                 {
449                         throw new NotImplementedException ();
450                 }
451 #endif
452         }
453 }