2004-04-27 Martin Baulig <martin@ximian.com>
[mono.git] / mcs / class / corlib / System.Reflection / Assembly.cs
1 //
2 // System.Reflection/Assembly.cs
3 //
4 // Author:
5 //   Paolo Molaro (lupus@ximian.com)
6 //
7 // (C) 2001 Ximian, Inc.  http://www.ximian.com
8 //
9
10 using System;
11 using System.Security.Policy;
12 using System.Runtime.Serialization;
13 using System.Reflection.Emit;
14 using System.IO;
15 using System.Globalization;
16 using System.Runtime.CompilerServices;
17 using System.Runtime.InteropServices;
18 using System.Collections;
19
20 namespace System.Reflection {
21
22         [Serializable]
23         [ClassInterface(ClassInterfaceType.AutoDual)]
24         public class Assembly : System.Reflection.ICustomAttributeProvider,
25                 System.Security.IEvidenceFactory, System.Runtime.Serialization.ISerializable {
26                 private IntPtr _mono_assembly;
27                 
28                 internal Assembly () {}
29
30                 //TODO: when adding this, MonoReflectionAssembly must be modified too.
31                 // Probably, adding a delegate field after _mono_assbmely and using it in add/remove 
32                 // is the way to go (to avoid the compiler inserting the delegate field before).
33                 //public event ModuleResolveEventHandler ModuleResolve;
34
35                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
36                 private extern string get_code_base ();
37                 
38                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
39                 private extern string get_location ();
40
41                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
42                 private extern string InternalImageRuntimeVersion ();
43
44                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
45                 private extern bool get_global_assembly_cache ();
46
47                 public virtual string CodeBase {
48                         get {
49                                 return get_code_base ();
50                         }
51                 }
52
53                 internal virtual string CopiedCodeBase {
54                         get {
55                                 return get_code_base ();
56                         }
57                 } 
58
59                 [MonoTODO]
60                 public virtual string EscapedCodeBase {
61                         get {
62                                 //FIXME: escape characters -> Uri
63                                 return get_code_base ();
64                         }
65                 }
66
67                 public virtual string FullName {
68                         get {
69                                 //
70                                 // FIXME: This is wrong, but it gets us going
71                                 // in the compiler for now
72                                 //
73                                 return GetName (false).ToString ();
74                         }
75                 }
76
77                 public virtual extern MethodInfo EntryPoint {
78                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
79                         get;
80                 }
81
82                 public virtual Evidence Evidence {
83                         get {
84                                 return null;
85                         }
86                 }
87
88                 [MonoTODO]
89                 public bool GlobalAssemblyCache {
90                         get {
91                                 return get_global_assembly_cache ();
92                         }
93                 }
94                 
95                 public virtual String Location {
96                         get {
97                                 return get_location ();
98                         }
99                 }
100
101 #if NET_1_1
102                 public virtual string ImageRuntimeVersion {
103                         get {
104                                 return InternalImageRuntimeVersion ();
105                         }
106                 }
107 #endif
108
109                 public virtual void GetObjectData (SerializationInfo info, StreamingContext context)
110                 {
111                         UnitySerializationHolder.GetAssemblyData (this, info, context);
112                 }
113
114                 public virtual bool IsDefined (Type attributeType, bool inherit)
115                 {
116                         return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
117                 }
118
119                 public virtual object [] GetCustomAttributes (bool inherit)
120                 {
121                         return MonoCustomAttrs.GetCustomAttributes (this, inherit);
122                 }
123
124                 public virtual object [] GetCustomAttributes (Type attributeType, bool inherit)
125                 {
126                         return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
127                 }
128
129                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
130                 private extern object GetFilesInternal (String name);
131
132                 public virtual FileStream[] GetFiles ()
133                 {
134                         string[] names = (string[]) GetFilesInternal (null);
135                         if (names == null)
136                                 return new FileStream [0];
137
138                         FileStream[] res = new FileStream [names.Length];
139                         for (int i = 0; i < names.Length; ++i)
140                                 res [i] = new FileStream (names [i], FileMode.Open, FileAccess.Read);
141                         return res;
142                 }
143
144                 [MonoTODO]
145                 public virtual FileStream [] GetFiles (bool getResourceModules)
146                 {
147                         throw new NotImplementedException ();
148                 }
149
150                 public virtual FileStream GetFile (String name)
151                 {
152                         if (name == null)
153                                 throw new ArgumentNullException ("name");
154                         string filename = (string)GetFilesInternal (name);
155                         if (filename != null)
156                                 return new FileStream (filename, FileMode.Open, FileAccess.Read);
157                         else
158                                 return null;
159                 }
160
161                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
162                 private extern IntPtr GetManifestResourceInternal (String name, out int size, out Module module);
163
164                 public virtual Stream GetManifestResourceStream (String name)
165                 {
166                         if (name == null)
167                                 throw new ArgumentNullException ("name");
168                         if (name == "")
169                                 throw new ArgumentException ("name cannot have zero length.");
170
171                         ManifestResourceInfo info = GetManifestResourceInfo (name);
172                         if (info == null)
173                                 return null;
174
175                         if (info.ReferencedAssembly != null)
176                                 return info.ReferencedAssembly.GetManifestResourceStream (name);
177                         if ((info.FileName != null) && (info.ResourceLocation == 0)) {
178                                 string filename = Path.Combine (Path.GetDirectoryName (Location),
179                                                                                         info.FileName);
180                                 return new FileStream (filename, FileMode.Open, FileAccess.Read);
181                         }
182
183                         int size;
184                         Module module;
185                         IntPtr data = GetManifestResourceInternal (name, out size, out module);
186                         if (data == (IntPtr) 0)
187                                 return null;
188                         else {
189                                 IntPtrStream stream = new IntPtrStream (data, size);
190                                 /* 
191                                  * The returned pointer points inside metadata, so
192                                  * we have to increase the refcount of the module, and decrease
193                                  * it when the stream is finalized.
194                                  */
195                                 stream.Closed += new EventHandler (new ResourceCloseHandler (module).OnClose);
196                                 return stream;
197                         }
198                 }
199
200                 public virtual Stream GetManifestResourceStream (Type type, String name)
201                 {
202                         string ns;
203                         if (type != null)
204                                 ns = type.Namespace;
205                         else 
206                                 ns = null;
207
208                         if ((ns == null) || (ns == ""))
209                                 return GetManifestResourceStream (name);
210                         else
211                                 return GetManifestResourceStream (ns + "." + name);
212                 }
213
214                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
215                 private extern Type[] GetTypes (bool exportedOnly);
216                 
217                 public virtual Type[] GetTypes ()
218                 {
219                         return GetTypes (false);
220                 }
221
222                 public virtual Type[] GetExportedTypes ()
223                 {
224                         return GetTypes (true);
225                 }
226
227                 public virtual Type GetType (String name, Boolean throwOnError)
228                 {
229                         return GetType (name, throwOnError, false);
230                 }
231
232                 public virtual Type GetType (String name) {
233                         return GetType (name, false, false);
234                 }
235
236                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
237                 internal extern Type InternalGetType (Module module, String name, Boolean throwOnError, Boolean ignoreCase);
238
239                 public Type GetType (string name, bool throwOnError, bool ignoreCase)
240                 {
241                         if (name == null)
242                                 throw new ArgumentNullException (name);
243
244                         return InternalGetType (null, name, throwOnError, ignoreCase);
245                 }
246
247                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
248                 internal extern static void InternalGetAssemblyName (string assemblyFile, AssemblyName aname);
249                 
250                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
251                 static extern void FillName (Assembly ass, AssemblyName aname);
252                 
253                 public virtual AssemblyName GetName (Boolean copiedName)
254                 {
255                         AssemblyName aname = new AssemblyName ();
256                         FillName (this, aname);
257                         return aname;
258                 }
259
260                 public virtual AssemblyName GetName ()
261                 {
262                         return GetName (false);
263                 }
264
265                 public override String ToString ()
266                 {
267                         return GetName ().Name;
268                 }
269
270                 public static String CreateQualifiedName (String assemblyName, String typeName) 
271                 {
272                         return typeName + ", " + assemblyName;
273                 }
274
275                 public static Assembly GetAssembly (Type type)
276                 {
277                         if (type != null)
278                                 return type.Assembly;
279                         throw new ArgumentNullException ("type");
280                 }
281
282
283                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
284                 public static extern Assembly GetEntryAssembly();
285
286                 public Assembly GetSatelliteAssembly (CultureInfo culture)
287                 {
288                         return GetSatelliteAssembly (culture, null);
289                 }
290
291                 public Assembly GetSatelliteAssembly (CultureInfo culture, Version version)
292                 {
293                         if (culture == null)
294                                 throw new ArgumentException ("culture");
295
296                         AssemblyName aname = GetName (true);
297                         if (version != null)
298                                 aname.Version = version;
299
300                         aname.CultureInfo = culture;
301                         aname.Name = aname.Name + ".resources";
302                         return Load (aname);
303                 }
304                 
305                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
306                 public extern static Assembly LoadFrom (String assemblyFile);
307
308                 [MonoTODO]
309                 public static Assembly LoadFrom (String assemblyFile, Evidence securityEvidence)
310                 {
311                         // Evidence is ignored
312                         return LoadFrom (assemblyFile);
313                 }
314
315 #if NET_1_1
316                 [MonoTODO]
317                 public static Assembly LoadFile (String path, Evidence securityEvidence) {
318                         if (path == null)
319                                 throw new ArgumentNullException ("path");
320                         if (path == String.Empty)
321                                 throw new ArgumentException ("Path can't be empty", "path");
322                         // FIXME: Make this do the right thing
323                         return LoadFrom (path, securityEvidence);
324                 }
325
326                 public static Assembly LoadFile (String path) {
327                         return LoadFile (path, null);
328                 }
329 #endif
330
331                 public static Assembly Load (String assemblyString)
332                 {
333                         return AppDomain.CurrentDomain.Load (assemblyString);
334                 }
335                 
336                 public static Assembly Load (String assemblyString, Evidence assemblySecurity)
337                 {
338                         return AppDomain.CurrentDomain.Load (assemblyString, assemblySecurity);
339                 }
340
341                 public static Assembly Load (AssemblyName assemblyRef)
342                 {
343                         return AppDomain.CurrentDomain.Load (assemblyRef);
344                 }
345
346                 public static Assembly Load (AssemblyName assemblyRef, Evidence assemblySecurity)
347                 {
348                         return AppDomain.CurrentDomain.Load (assemblyRef, assemblySecurity);
349                 }
350
351                 public static Assembly Load (Byte[] rawAssembly)
352                 {
353                         return AppDomain.CurrentDomain.Load (rawAssembly);
354                 }
355
356                 public static Assembly Load (Byte[] rawAssembly, Byte[] rawSymbolStore)
357                 {
358                         return AppDomain.CurrentDomain.Load (rawAssembly, rawSymbolStore);
359                 }
360
361                 public static Assembly Load (Byte[] rawAssembly, Byte[] rawSymbolStore,
362                                              Evidence securityEvidence)
363                 {
364                         return AppDomain.CurrentDomain.Load (rawAssembly, rawSymbolStore, securityEvidence);
365                 }
366
367                 public static Assembly LoadWithPartialName (string partialName)
368                 {
369                         return LoadWithPartialName (partialName, null);
370                 }
371
372                 [MonoTODO]
373                 public Module LoadModule (string moduleName, byte [] rawModule)
374                 {
375                         throw new NotImplementedException ();
376                 }
377
378                 [MonoTODO]
379                 public Module LoadModule (string moduleName, byte [] rawModule, byte [] rawSymbolStore)
380                 {
381                         throw new NotImplementedException ();
382                 }
383
384                 [MonoTODO]
385                 public static Assembly LoadWithPartialName (string partialName, Evidence securityEvidence)
386                 {
387                         try {
388                                 return AppDomain.CurrentDomain.Load (partialName, securityEvidence);
389                         }
390                         catch (Exception) {
391                                 // According to MSDN, this should return null instead of
392                                 // throwing an exception
393                                 return null;
394                         }
395                 }
396
397                 public Object CreateInstance (String typeName) 
398                 {
399                         return CreateInstance (typeName, false);
400                 }
401
402                 public Object CreateInstance (String typeName, Boolean ignoreCase)
403                 {
404                         Type t = GetType (typeName, false, ignoreCase);
405                         if (t == null)
406                                 return null;
407
408                         return Activator.CreateInstance (t);
409                 }
410
411                 public Object CreateInstance (String typeName, Boolean ignoreCase,
412                                               BindingFlags bindingAttr, Binder binder,
413                                               Object[] args, CultureInfo culture,
414                                               Object[] activationAttributes)
415                 {
416                         Type t = GetType (typeName, false, ignoreCase);
417                         if (t == null)
418                                 return null;
419
420                         return Activator.CreateInstance (t, bindingAttr, binder, args, culture, activationAttributes);
421                 }
422
423                 public Module[] GetLoadedModules ()
424                 {
425                         return GetLoadedModules (false);
426                 }
427
428                 [MonoTODO]
429                 public Module[] GetLoadedModules (bool getResourceModules)
430                 {
431                         // Currently, the two sets of modules are equal
432                         return GetModules (getResourceModules);
433                 }
434
435                 public Module[] GetModules ()
436                 {
437                         return GetModules (false);
438                 }
439
440                 public Module GetModule (String name)
441                 {
442                         if (name == null)
443                                 throw new ArgumentNullException ("name");
444                         if (name == "")
445                                 throw new ArgumentException ("Name can't be empty");
446
447                         Module[] modules = GetModules (true);
448                         foreach (Module module in GetModules (true)) {
449                                 if (module.ScopeName == name)
450                                         return module;
451                         }
452
453                         return null;
454                 }
455
456                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
457                 internal extern Module[] GetModulesInternal ();
458
459                 public Module[] GetModules (bool getResourceModules) {
460                         Module[] modules = GetModulesInternal ();
461
462                         if (!getResourceModules) {
463                                 ArrayList result = new ArrayList (modules.Length);
464                                 foreach (Module m in modules)
465                                         if (!m.IsResource ())
466                                                 result.Add (m);
467                                 return (Module[])result.ToArray (typeof (Module));
468                         }
469                         else
470                                 return modules;
471                 }
472
473                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
474                 internal extern string[] GetNamespaces ();
475                 
476                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
477                 public extern virtual String[] GetManifestResourceNames ();
478
479                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
480                 public extern static Assembly GetExecutingAssembly ();
481
482                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
483                 public extern static Assembly GetCallingAssembly ();
484
485                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
486                 public extern AssemblyName[] GetReferencedAssemblies ();
487
488                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
489                 private extern bool GetManifestResourceInfoInternal (String name, ManifestResourceInfo info);
490
491                 public virtual ManifestResourceInfo GetManifestResourceInfo (String resourceName)
492                 {
493                         if (resourceName == null)
494                                 throw new ArgumentNullException ("resourceName");
495                         if (resourceName == "")
496                                 throw new ArgumentException ("String cannot have zero length.");
497                         ManifestResourceInfo result = new ManifestResourceInfo ();
498                         bool found = GetManifestResourceInfoInternal (resourceName, result);
499                         if (found)
500                                 return result;
501                         else
502                                 return null;
503                 }
504
505                 private class ResourceCloseHandler {
506
507                         Module module;
508
509                         public ResourceCloseHandler (Module module) {
510                                 this.module = module;
511                         }
512
513                         public void OnClose (object sender, EventArgs e) {
514                                 // The module dtor will take care of things
515                                 module = null;
516                         }
517                 }
518
519                 //
520                 // The following functions are only for the Mono Debugger.
521                 //
522
523                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
524                 internal static extern MethodBase MonoDebugger_GetMethod (Assembly assembly, int token);
525
526                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
527                 internal static extern int MonoDebugger_GetMethodToken (Assembly assembly, MethodBase method);
528
529                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
530                 internal static extern Type MonoDebugger_GetLocalTypeFromSignature (Assembly assembly, byte[] signature);
531
532                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
533                 internal static extern Type MonoDebugger_GetType (Assembly assembly, int token);
534         }
535 }