Update to the latest IKVM which now has support for missing types
[mono.git] / mcs / class / IKVM.Reflection / Universe.cs
1 /*
2   Copyright (C) 2009-2011 Jeroen Frijters
3
4   This software is provided 'as-is', without any express or implied
5   warranty.  In no event will the authors be held liable for any damages
6   arising from the use of this software.
7
8   Permission is granted to anyone to use this software for any purpose,
9   including commercial applications, and to alter it and redistribute it
10   freely, subject to the following restrictions:
11
12   1. The origin of this software must not be misrepresented; you must not
13      claim that you wrote the original software. If you use this software
14      in a product, an acknowledgment in the product documentation would be
15      appreciated but is not required.
16   2. Altered source versions must be plainly marked as such, and must not be
17      misrepresented as being the original software.
18   3. This notice may not be removed or altered from any source distribution.
19
20   Jeroen Frijters
21   jeroen@frijters.net
22   
23 */
24 using System;
25 using System.Collections.Generic;
26 using System.IO;
27 using System.Security;
28 using System.Text;
29 using System.Diagnostics;
30 using IKVM.Reflection.Reader;
31 using IKVM.Reflection.Emit;
32
33 namespace IKVM.Reflection
34 {
35         public sealed class ResolveEventArgs : EventArgs
36         {
37                 private readonly string name;
38                 private readonly Assembly requestingAssembly;
39
40                 public ResolveEventArgs(string name)
41                         : this(name, null)
42                 {
43                 }
44
45                 public ResolveEventArgs(string name, Assembly requestingAssembly)
46                 {
47                         this.name = name;
48                         this.requestingAssembly = requestingAssembly;
49                 }
50
51                 public string Name
52                 {
53                         get { return name; }
54                 }
55
56                 public Assembly RequestingAssembly
57                 {
58                         get { return requestingAssembly; }
59                 }
60         }
61
62         public enum AssemblyComparisonResult
63         {
64                 Unknown = 0,
65                 EquivalentFullMatch = 1,
66                 EquivalentWeakNamed = 2,
67                 EquivalentFXUnified = 3,
68                 EquivalentUnified = 4,
69                 NonEquivalentVersion = 5,
70                 NonEquivalent = 6,
71                 EquivalentPartialMatch = 7,
72                 EquivalentPartialWeakNamed = 8,
73                 EquivalentPartialUnified = 9,
74                 EquivalentPartialFXUnified = 10,
75                 NonEquivalentPartialVersion = 11,
76         }
77
78         public delegate Assembly ResolveEventHandler(object sender, ResolveEventArgs args);
79
80         public sealed class Universe : IDisposable
81         {
82                 internal readonly Dictionary<Type, Type> canonicalizedTypes = new Dictionary<Type, Type>();
83                 private readonly List<Assembly> assemblies = new List<Assembly>();
84                 private readonly List<AssemblyBuilder> dynamicAssemblies = new List<AssemblyBuilder>();
85                 private readonly Dictionary<string, Assembly> assembliesByName = new Dictionary<string, Assembly>();
86                 private readonly Dictionary<System.Type, Type> importedTypes = new Dictionary<System.Type, Type>();
87                 private Type typeof_System_Object;
88                 private Type typeof_System_ValueType;
89                 private Type typeof_System_Enum;
90                 private Type typeof_System_Void;
91                 private Type typeof_System_Boolean;
92                 private Type typeof_System_Char;
93                 private Type typeof_System_SByte;
94                 private Type typeof_System_Byte;
95                 private Type typeof_System_Int16;
96                 private Type typeof_System_UInt16;
97                 private Type typeof_System_Int32;
98                 private Type typeof_System_UInt32;
99                 private Type typeof_System_Int64;
100                 private Type typeof_System_UInt64;
101                 private Type typeof_System_Single;
102                 private Type typeof_System_Double;
103                 private Type typeof_System_String;
104                 private Type typeof_System_IntPtr;
105                 private Type typeof_System_UIntPtr;
106                 private Type typeof_System_TypedReference;
107                 private Type typeof_System_Type;
108                 private Type typeof_System_Array;
109                 private Type typeof_System_DateTime;
110                 private Type typeof_System_DBNull;
111                 private Type typeof_System_Decimal;
112                 private Type typeof_System_NonSerializedAttribute;
113                 private Type typeof_System_SerializableAttribute;
114                 private Type typeof_System_AttributeUsageAttribute;
115                 private Type typeof_System_Reflection_AssemblyCultureAttribute;
116                 private Type typeof_System_Runtime_InteropServices_DllImportAttribute;
117                 private Type typeof_System_Runtime_InteropServices_FieldOffsetAttribute;
118                 private Type typeof_System_Runtime_InteropServices_InAttribute;
119                 private Type typeof_System_Runtime_InteropServices_MarshalAsAttribute;
120                 private Type typeof_System_Runtime_InteropServices_UnmanagedType;
121                 private Type typeof_System_Runtime_InteropServices_VarEnum;
122                 private Type typeof_System_Runtime_InteropServices_OutAttribute;
123                 private Type typeof_System_Runtime_InteropServices_StructLayoutAttribute;
124                 private Type typeof_System_Runtime_InteropServices_OptionalAttribute;
125                 private Type typeof_System_Runtime_InteropServices_PreserveSigAttribute;
126                 private Type typeof_System_Runtime_InteropServices_ComImportAttribute;
127                 private Type typeof_System_Runtime_CompilerServices_DecimalConstantAttribute;
128                 private Type typeof_System_Runtime_CompilerServices_SpecialNameAttribute;
129                 private Type typeof_System_Runtime_CompilerServices_MethodImplAttribute;
130                 private Type typeof_System_Security_SuppressUnmanagedCodeSecurityAttribute;
131                 private Type typeof_System_Reflection_AssemblyCopyrightAttribute;
132                 private Type typeof_System_Reflection_AssemblyTrademarkAttribute;
133                 private Type typeof_System_Reflection_AssemblyProductAttribute;
134                 private Type typeof_System_Reflection_AssemblyCompanyAttribute;
135                 private Type typeof_System_Reflection_AssemblyDescriptionAttribute;
136                 private Type typeof_System_Reflection_AssemblyTitleAttribute;
137                 private Type typeof_System_Reflection_AssemblyInformationalVersionAttribute;
138                 private Type typeof_System_Reflection_AssemblyFileVersionAttribute;
139                 private Type typeof_System_Security_Permissions_CodeAccessSecurityAttribute;
140                 private Type typeof_System_Security_Permissions_HostProtectionAttribute;
141                 private Type typeof_System_Security_Permissions_PermissionSetAttribute;
142                 private Type typeof_System_Security_Permissions_SecurityAction;
143                 private List<ResolveEventHandler> resolvers = new List<ResolveEventHandler>();
144
145                 internal Assembly Mscorlib
146                 {
147                         get { return Load("mscorlib"); }
148                 }
149
150                 private Type ImportMscorlibType(System.Type type)
151                 {
152                         return Mscorlib.GetTypeImpl(type.FullName);
153                 }
154
155                 internal Type System_Object
156                 {
157                         get { return typeof_System_Object ?? (typeof_System_Object = ImportMscorlibType(typeof(System.Object))); }
158                 }
159
160                 internal Type System_ValueType
161                 {
162                         get { return typeof_System_ValueType ?? (typeof_System_ValueType = ImportMscorlibType(typeof(System.ValueType))); }
163                 }
164
165                 internal Type System_Enum
166                 {
167                         get { return typeof_System_Enum ?? (typeof_System_Enum = ImportMscorlibType(typeof(System.Enum))); }
168                 }
169
170                 internal Type System_Void
171                 {
172                         get { return typeof_System_Void ?? (typeof_System_Void = ImportMscorlibType(typeof(void))); }
173                 }
174
175                 internal Type System_Boolean
176                 {
177                         get { return typeof_System_Boolean ?? (typeof_System_Boolean = ImportMscorlibType(typeof(System.Boolean))); }
178                 }
179
180                 internal Type System_Char
181                 {
182                         get { return typeof_System_Char ?? (typeof_System_Char = ImportMscorlibType(typeof(System.Char))); }
183                 }
184
185                 internal Type System_SByte
186                 {
187                         get { return typeof_System_SByte ?? (typeof_System_SByte = ImportMscorlibType(typeof(System.SByte))); }
188                 }
189
190                 internal Type System_Byte
191                 {
192                         get { return typeof_System_Byte ?? (typeof_System_Byte = ImportMscorlibType(typeof(System.Byte))); }
193                 }
194
195                 internal Type System_Int16
196                 {
197                         get { return typeof_System_Int16 ?? (typeof_System_Int16 = ImportMscorlibType(typeof(System.Int16))); }
198                 }
199
200                 internal Type System_UInt16
201                 {
202                         get { return typeof_System_UInt16 ?? (typeof_System_UInt16 = ImportMscorlibType(typeof(System.UInt16))); }
203                 }
204
205                 internal Type System_Int32
206                 {
207                         get { return typeof_System_Int32 ?? (typeof_System_Int32 = ImportMscorlibType(typeof(System.Int32))); }
208                 }
209
210                 internal Type System_UInt32
211                 {
212                         get { return typeof_System_UInt32 ?? (typeof_System_UInt32 = ImportMscorlibType(typeof(System.UInt32))); }
213                 }
214
215                 internal Type System_Int64
216                 {
217                         get { return typeof_System_Int64 ?? (typeof_System_Int64 = ImportMscorlibType(typeof(System.Int64))); }
218                 }
219
220                 internal Type System_UInt64
221                 {
222                         get { return typeof_System_UInt64 ?? (typeof_System_UInt64 = ImportMscorlibType(typeof(System.UInt64))); }
223                 }
224
225                 internal Type System_Single
226                 {
227                         get { return typeof_System_Single ?? (typeof_System_Single = ImportMscorlibType(typeof(System.Single))); }
228                 }
229
230                 internal Type System_Double
231                 {
232                         get { return typeof_System_Double ?? (typeof_System_Double = ImportMscorlibType(typeof(System.Double))); }
233                 }
234
235                 internal Type System_String
236                 {
237                         get { return typeof_System_String ?? (typeof_System_String = ImportMscorlibType(typeof(System.String))); }
238                 }
239
240                 internal Type System_IntPtr
241                 {
242                         get { return typeof_System_IntPtr ?? (typeof_System_IntPtr = ImportMscorlibType(typeof(System.IntPtr))); }
243                 }
244
245                 internal Type System_UIntPtr
246                 {
247                         get { return typeof_System_UIntPtr ?? (typeof_System_UIntPtr = ImportMscorlibType(typeof(System.UIntPtr))); }
248                 }
249
250                 internal Type System_TypedReference
251                 {
252                         get { return typeof_System_TypedReference ?? (typeof_System_TypedReference = ImportMscorlibType(typeof(System.TypedReference))); }
253                 }
254
255                 internal Type System_Type
256                 {
257                         get { return typeof_System_Type ?? (typeof_System_Type = ImportMscorlibType(typeof(System.Type))); }
258                 }
259
260                 internal Type System_Array
261                 {
262                         get { return typeof_System_Array ?? (typeof_System_Array = ImportMscorlibType(typeof(System.Array))); }
263                 }
264
265                 internal Type System_DateTime
266                 {
267                         get { return typeof_System_DateTime ?? (typeof_System_DateTime = ImportMscorlibType(typeof(System.DateTime))); }
268                 }
269
270                 internal Type System_DBNull
271                 {
272                         get { return typeof_System_DBNull ?? (typeof_System_DBNull = ImportMscorlibType(typeof(System.DBNull))); }
273                 }
274
275                 internal Type System_Decimal
276                 {
277                         get { return typeof_System_Decimal ?? (typeof_System_Decimal = ImportMscorlibType(typeof(System.Decimal))); }
278                 }
279
280                 internal Type System_NonSerializedAttribute
281                 {
282                         get { return typeof_System_NonSerializedAttribute ?? (typeof_System_NonSerializedAttribute = ImportMscorlibType(typeof(System.NonSerializedAttribute))); }
283                 }
284
285                 internal Type System_SerializableAttribute
286                 {
287                         get { return typeof_System_SerializableAttribute ?? (typeof_System_SerializableAttribute = ImportMscorlibType(typeof(System.SerializableAttribute))); }
288                 }
289
290                 internal Type System_AttributeUsageAttribute
291                 {
292                         get { return typeof_System_AttributeUsageAttribute ?? (typeof_System_AttributeUsageAttribute = ImportMscorlibType(typeof(System.AttributeUsageAttribute))); }
293                 }
294
295                 internal Type System_Reflection_AssemblyCultureAttribute
296                 {
297                         get { return typeof_System_Reflection_AssemblyCultureAttribute ?? (typeof_System_Reflection_AssemblyCultureAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyCultureAttribute))); }
298                 }
299
300                 internal Type System_Runtime_InteropServices_DllImportAttribute
301                 {
302                         get { return typeof_System_Runtime_InteropServices_DllImportAttribute ?? (typeof_System_Runtime_InteropServices_DllImportAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.DllImportAttribute))); }
303                 }
304
305                 internal Type System_Runtime_InteropServices_FieldOffsetAttribute
306                 {
307                         get { return typeof_System_Runtime_InteropServices_FieldOffsetAttribute ?? (typeof_System_Runtime_InteropServices_FieldOffsetAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.FieldOffsetAttribute))); }
308                 }
309
310                 internal Type System_Runtime_InteropServices_InAttribute
311                 {
312                         get { return typeof_System_Runtime_InteropServices_InAttribute ?? (typeof_System_Runtime_InteropServices_InAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.InAttribute))); }
313                 }
314
315                 internal Type System_Runtime_InteropServices_MarshalAsAttribute
316                 {
317                         get { return typeof_System_Runtime_InteropServices_MarshalAsAttribute ?? (typeof_System_Runtime_InteropServices_MarshalAsAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.MarshalAsAttribute))); }
318                 }
319
320                 internal Type System_Runtime_InteropServices_UnmanagedType
321                 {
322                         get { return typeof_System_Runtime_InteropServices_UnmanagedType ?? (typeof_System_Runtime_InteropServices_UnmanagedType = ImportMscorlibType(typeof(System.Runtime.InteropServices.UnmanagedType))); }
323                 }
324
325                 internal Type System_Runtime_InteropServices_VarEnum
326                 {
327                         get { return typeof_System_Runtime_InteropServices_VarEnum ?? (typeof_System_Runtime_InteropServices_VarEnum = ImportMscorlibType(typeof(System.Runtime.InteropServices.VarEnum))); }
328                 }
329
330                 internal Type System_Runtime_InteropServices_OutAttribute
331                 {
332                         get { return typeof_System_Runtime_InteropServices_OutAttribute ?? (typeof_System_Runtime_InteropServices_OutAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.OutAttribute))); }
333                 }
334
335                 internal Type System_Runtime_InteropServices_StructLayoutAttribute
336                 {
337                         get { return typeof_System_Runtime_InteropServices_StructLayoutAttribute ?? (typeof_System_Runtime_InteropServices_StructLayoutAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.StructLayoutAttribute))); }
338                 }
339
340                 internal Type System_Runtime_InteropServices_OptionalAttribute
341                 {
342                         get { return typeof_System_Runtime_InteropServices_OptionalAttribute ?? (typeof_System_Runtime_InteropServices_OptionalAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.OptionalAttribute))); }
343                 }
344
345                 internal Type System_Runtime_InteropServices_PreserveSigAttribute
346                 {
347                         get { return typeof_System_Runtime_InteropServices_PreserveSigAttribute ?? (typeof_System_Runtime_InteropServices_PreserveSigAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.PreserveSigAttribute))); }
348                 }
349
350                 internal Type System_Runtime_InteropServices_ComImportAttribute
351                 {
352                         get { return typeof_System_Runtime_InteropServices_ComImportAttribute ?? (typeof_System_Runtime_InteropServices_ComImportAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.ComImportAttribute))); }
353                 }
354
355                 internal Type System_Runtime_CompilerServices_DecimalConstantAttribute
356                 {
357                         get { return typeof_System_Runtime_CompilerServices_DecimalConstantAttribute ?? (typeof_System_Runtime_CompilerServices_DecimalConstantAttribute = ImportMscorlibType(typeof(System.Runtime.CompilerServices.DecimalConstantAttribute))); }
358                 }
359
360                 internal Type System_Runtime_CompilerServices_SpecialNameAttribute
361                 {
362                         get { return typeof_System_Runtime_CompilerServices_SpecialNameAttribute ?? (typeof_System_Runtime_CompilerServices_SpecialNameAttribute = ImportMscorlibType(typeof(System.Runtime.CompilerServices.SpecialNameAttribute))); }
363                 }
364
365                 internal Type System_Runtime_CompilerServices_MethodImplAttribute
366                 {
367                         get { return typeof_System_Runtime_CompilerServices_MethodImplAttribute ?? (typeof_System_Runtime_CompilerServices_MethodImplAttribute = ImportMscorlibType(typeof(System.Runtime.CompilerServices.MethodImplAttribute))); }
368                 }
369
370                 internal Type System_Security_SuppressUnmanagedCodeSecurityAttribute
371                 {
372                         get { return typeof_System_Security_SuppressUnmanagedCodeSecurityAttribute ?? (typeof_System_Security_SuppressUnmanagedCodeSecurityAttribute = ImportMscorlibType(typeof(System.Security.SuppressUnmanagedCodeSecurityAttribute))); }
373                 }
374
375                 internal Type System_Reflection_AssemblyCopyrightAttribute
376                 {
377                         get { return typeof_System_Reflection_AssemblyCopyrightAttribute ?? (typeof_System_Reflection_AssemblyCopyrightAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyCopyrightAttribute))); }
378                 }
379
380                 internal Type System_Reflection_AssemblyTrademarkAttribute
381                 {
382                         get { return typeof_System_Reflection_AssemblyTrademarkAttribute ?? (typeof_System_Reflection_AssemblyTrademarkAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyTrademarkAttribute))); }
383                 }
384
385                 internal Type System_Reflection_AssemblyProductAttribute
386                 {
387                         get { return typeof_System_Reflection_AssemblyProductAttribute ?? (typeof_System_Reflection_AssemblyProductAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyProductAttribute))); }
388                 }
389
390                 internal Type System_Reflection_AssemblyCompanyAttribute
391                 {
392                         get { return typeof_System_Reflection_AssemblyCompanyAttribute ?? (typeof_System_Reflection_AssemblyCompanyAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyCompanyAttribute))); }
393                 }
394
395                 internal Type System_Reflection_AssemblyDescriptionAttribute
396                 {
397                         get { return typeof_System_Reflection_AssemblyDescriptionAttribute ?? (typeof_System_Reflection_AssemblyDescriptionAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyDescriptionAttribute))); }
398                 }
399
400                 internal Type System_Reflection_AssemblyTitleAttribute
401                 {
402                         get { return typeof_System_Reflection_AssemblyTitleAttribute ?? (typeof_System_Reflection_AssemblyTitleAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyTitleAttribute))); }
403                 }
404
405                 internal Type System_Reflection_AssemblyInformationalVersionAttribute
406                 {
407                         get { return typeof_System_Reflection_AssemblyInformationalVersionAttribute ?? (typeof_System_Reflection_AssemblyInformationalVersionAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyInformationalVersionAttribute))); }
408                 }
409
410                 internal Type System_Reflection_AssemblyFileVersionAttribute
411                 {
412                         get { return typeof_System_Reflection_AssemblyFileVersionAttribute ?? (typeof_System_Reflection_AssemblyFileVersionAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyFileVersionAttribute))); }
413                 }
414
415                 internal Type System_Security_Permissions_CodeAccessSecurityAttribute
416                 {
417                         get { return typeof_System_Security_Permissions_CodeAccessSecurityAttribute ?? (typeof_System_Security_Permissions_CodeAccessSecurityAttribute = ImportMscorlibType(typeof(System.Security.Permissions.CodeAccessSecurityAttribute))); }
418                 }
419
420                 internal Type System_Security_Permissions_HostProtectionAttribute
421                 {
422                         get { return typeof_System_Security_Permissions_HostProtectionAttribute ?? (typeof_System_Security_Permissions_HostProtectionAttribute = ImportMscorlibType(typeof(System.Security.Permissions.HostProtectionAttribute))); }
423                 }
424
425                 internal Type System_Security_Permissions_PermissionSetAttribute
426                 {
427                         get { return typeof_System_Security_Permissions_PermissionSetAttribute ?? (typeof_System_Security_Permissions_PermissionSetAttribute = ImportMscorlibType(typeof(System.Security.Permissions.PermissionSetAttribute))); }
428                 }
429
430                 internal Type System_Security_Permissions_SecurityAction
431                 {
432                         get { return typeof_System_Security_Permissions_SecurityAction ?? (typeof_System_Security_Permissions_SecurityAction = ImportMscorlibType(typeof(System.Security.Permissions.SecurityAction))); }
433                 }
434
435                 internal bool HasMscorlib
436                 {
437                         get { return GetLoadedAssembly("mscorlib") != null; }
438                 }
439
440                 public event ResolveEventHandler AssemblyResolve
441                 {
442                         add { resolvers.Add(value); }
443                         remove { resolvers.Remove(value); }
444                 }
445
446                 public Type Import(System.Type type)
447                 {
448                         Type imported;
449                         if (!importedTypes.TryGetValue(type, out imported))
450                         {
451                                 imported = ImportImpl(type);
452                                 if (imported != null)
453                                 {
454                                         importedTypes.Add(type, imported);
455                                 }
456                         }
457                         return imported;
458                 }
459
460                 private Type ImportImpl(System.Type type)
461                 {
462                         if (type.Assembly == typeof(IKVM.Reflection.Type).Assembly)
463                         {
464                                 throw new ArgumentException("Did you really want to import " + type.FullName + "?");
465                         }
466                         if (type.HasElementType)
467                         {
468                                 if (type.IsArray)
469                                 {
470                                         if (type.Name.EndsWith("[]"))
471                                         {
472                                                 return Import(type.GetElementType()).MakeArrayType();
473                                         }
474                                         else
475                                         {
476                                                 return Import(type.GetElementType()).MakeArrayType(type.GetArrayRank());
477                                         }
478                                 }
479                                 else if (type.IsByRef)
480                                 {
481                                         return Import(type.GetElementType()).MakeByRefType();
482                                 }
483                                 else if (type.IsPointer)
484                                 {
485                                         return Import(type.GetElementType()).MakePointerType();
486                                 }
487                                 else
488                                 {
489                                         throw new InvalidOperationException();
490                                 }
491                         }
492                         else if (type.IsGenericParameter)
493                         {
494                                 if (type.DeclaringMethod != null)
495                                 {
496                                         throw new NotImplementedException();
497                                 }
498                                 else
499                                 {
500                                         return Import(type.DeclaringType).GetGenericArguments()[type.GenericParameterPosition];
501                                 }
502                         }
503                         else if (type.IsGenericType && !type.IsGenericTypeDefinition)
504                         {
505                                 System.Type[] args = type.GetGenericArguments();
506                                 Type[] importedArgs = new Type[args.Length];
507                                 for (int i = 0; i < args.Length; i++)
508                                 {
509                                         importedArgs[i] = Import(args[i]);
510                                 }
511                                 return Import(type.GetGenericTypeDefinition()).MakeGenericType(importedArgs);
512                         }
513                         else
514                         {
515                                 return Import(type.Assembly).GetType(type.FullName);
516                         }
517                 }
518
519                 private Assembly Import(System.Reflection.Assembly asm)
520                 {
521                         return Load(asm.FullName);
522                 }
523
524                 public RawModule OpenRawModule(string path)
525                 {
526                         path = Path.GetFullPath(path);
527                         return OpenRawModule(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read), path);
528                 }
529
530                 public RawModule OpenRawModule(Stream stream, string location)
531                 {
532                         if (!stream.CanRead || !stream.CanSeek)
533                         {
534                                 throw new NotSupportedException();
535                         }
536                         return new RawModule(new ModuleReader(null, this, stream, location));
537                 }
538
539                 public Assembly LoadAssembly(RawModule module)
540                 {
541                         string refname = module.GetAssemblyName().FullName;
542                         Assembly asm = GetLoadedAssembly(refname);
543                         if (asm == null)
544                         {
545                                 asm = module.ToAssembly();
546                                 assemblies.Add(asm);
547                         }
548                         return asm;
549                 }
550
551                 public Assembly LoadFile(string path)
552                 {
553                         try
554                         {
555                                 using (RawModule module = OpenRawModule(path))
556                                 {
557                                         return LoadAssembly(module);
558                                 }
559                         }
560                         catch (IOException x)
561                         {
562                                 throw new FileNotFoundException(x.Message, x);
563                         }
564                         catch (UnauthorizedAccessException x)
565                         {
566                                 throw new FileNotFoundException(x.Message, x);
567                         }
568                 }
569
570                 private Assembly GetLoadedAssembly(string refname)
571                 {
572                         Assembly asm;
573                         if (!assembliesByName.TryGetValue(refname, out asm))
574                         {
575                                 for (int i = 0; i < assemblies.Count; i++)
576                                 {
577                                         AssemblyComparisonResult result;
578                                         // We won't allow FX unification here, because our own (non-Fusion) implementation of CompareAssemblyIdentity doesn't support it and
579                                         // we don't want to create a fundamental functional difference based on that.
580                                         if (CompareAssemblyIdentity(refname, false, assemblies[i].FullName, false, out result) && result != AssemblyComparisonResult.EquivalentFXUnified)
581                                         {
582                                                 asm = assemblies[i];
583                                                 assembliesByName.Add(refname, asm);
584                                                 break;
585                                         }
586                                 }
587                         }
588                         return asm;
589                 }
590
591                 private Assembly GetDynamicAssembly(string refname)
592                 {
593                         foreach (AssemblyBuilder asm in dynamicAssemblies)
594                         {
595                                 AssemblyComparisonResult result;
596                                 // We won't allow FX unification here, because our own (non-Fusion) implementation of CompareAssemblyIdentity doesn't support it and
597                                 // we don't want to create a fundamental functional difference based on that.
598                                 if (CompareAssemblyIdentity(refname, false, asm.FullName, false, out result) && result != AssemblyComparisonResult.EquivalentFXUnified)
599                                 {
600                                         return asm;
601                                 }
602                         }
603                         return null;
604                 }
605
606                 public Assembly Load(string refname)
607                 {
608                         return Load(refname, null, true);
609                 }
610
611                 internal Assembly Load(string refname, Assembly requestingAssembly, bool throwOnError)
612                 {
613                         Assembly asm = GetLoadedAssembly(refname);
614                         if (asm != null)
615                         {
616                                 return asm;
617                         }
618                         if (resolvers.Count == 0)
619                         {
620                                 asm = DefaultResolver(refname, throwOnError);
621                         }
622                         else
623                         {
624                                 ResolveEventArgs args = new ResolveEventArgs(refname, requestingAssembly);
625                                 foreach (ResolveEventHandler evt in resolvers)
626                                 {
627                                         asm = evt(this, args);
628                                         if (asm != null)
629                                         {
630                                                 break;
631                                         }
632                                 }
633                                 if (asm == null)
634                                 {
635                                         asm = GetDynamicAssembly(refname);
636                                 }
637                         }
638                         if (asm != null)
639                         {
640                                 string defname = asm.FullName;
641                                 if (refname != defname)
642                                 {
643                                         assembliesByName.Add(refname, asm);
644                                 }
645                                 return asm;
646                         }
647                         if (throwOnError)
648                         {
649                                 throw new FileNotFoundException(refname);
650                         }
651                         return null;
652                 }
653
654                 private Assembly DefaultResolver(string refname, bool throwOnError)
655                 {
656                         Assembly asm = GetDynamicAssembly(refname);
657                         if (asm != null)
658                         {
659                                 return asm;
660                         }
661                         string fileName;
662                         if (throwOnError)
663                         {
664                                 try
665                                 {
666                                         fileName = System.Reflection.Assembly.ReflectionOnlyLoad(refname).Location;
667                                 }
668                                 catch (System.BadImageFormatException x)
669                                 {
670                                         throw new BadImageFormatException(x.Message, x);
671                                 }
672                         }
673                         else
674                         {
675                                 try
676                                 {
677                                         fileName = System.Reflection.Assembly.ReflectionOnlyLoad(refname).Location;
678                                 }
679                                 catch (System.BadImageFormatException x)
680                                 {
681                                         throw new BadImageFormatException(x.Message, x);
682                                 }
683                                 catch (FileNotFoundException)
684                                 {
685                                         // we intentionally only swallow the FileNotFoundException, if the file exists but isn't a valid assembly,
686                                         // we should throw an exception
687                                         return null;
688                                 }
689                         }
690                         return LoadFile(fileName);
691                 }
692
693                 public Type GetType(string assemblyQualifiedTypeName)
694                 {
695                         // to be more compatible with Type.GetType(), we could call Assembly.GetCallingAssembly(),
696                         // import that assembly and pass it as the context, but implicitly importing is considered evil
697                         return GetType(null, assemblyQualifiedTypeName, false);
698                 }
699
700                 public Type GetType(string assemblyQualifiedTypeName, bool throwOnError)
701                 {
702                         // to be more compatible with Type.GetType(), we could call Assembly.GetCallingAssembly(),
703                         // import that assembly and pass it as the context, but implicitly importing is considered evil
704                         return GetType(null, assemblyQualifiedTypeName, throwOnError);
705                 }
706
707                 // note that context is slightly different from the calling assembly (System.Type.GetType),
708                 // because context is passed to the AssemblyResolve event as the RequestingAssembly
709                 public Type GetType(Assembly context, string assemblyQualifiedTypeName, bool throwOnError)
710                 {
711                         TypeNameParser parser = TypeNameParser.Parse(assemblyQualifiedTypeName, throwOnError);
712                         if (parser.Error)
713                         {
714                                 return null;
715                         }
716                         return parser.GetType(this, context, throwOnError, assemblyQualifiedTypeName);
717                 }
718
719                 public Assembly[] GetAssemblies()
720                 {
721                         Assembly[] array = new Assembly[assemblies.Count + dynamicAssemblies.Count];
722                         assemblies.CopyTo(array);
723                         for (int i = 0, j = assemblies.Count; j < array.Length; i++, j++)
724                         {
725                                 array[j] = dynamicAssemblies[i];
726                         }
727                         return array;
728                 }
729
730                 // this is equivalent to the Fusion CompareAssemblyIdentity API
731                 public bool CompareAssemblyIdentity(string assemblyIdentity1, bool unified1, string assemblyIdentity2, bool unified2, out AssemblyComparisonResult result)
732                 {
733                         return Fusion.CompareAssemblyIdentity(assemblyIdentity1, unified1, assemblyIdentity2, unified2, out result);
734                 }
735
736                 public AssemblyBuilder DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access)
737                 {
738                         return DefineDynamicAssemblyImpl(name, access, null, null, null, null);
739                 }
740
741                 public AssemblyBuilder DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access, string dir)
742                 {
743                         return DefineDynamicAssemblyImpl(name, access, dir, null, null, null);
744                 }
745
746 #if NET_4_0
747                 [Obsolete]
748 #endif
749                 public AssemblyBuilder DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access, string dir, PermissionSet requiredPermissions, PermissionSet optionalPermissions, PermissionSet refusedPermissions)
750                 {
751                         return DefineDynamicAssemblyImpl(name, access, dir, requiredPermissions, optionalPermissions, refusedPermissions);
752                 }
753
754                 private AssemblyBuilder DefineDynamicAssemblyImpl(AssemblyName name, AssemblyBuilderAccess access, string dir, PermissionSet requiredPermissions, PermissionSet optionalPermissions, PermissionSet refusedPermissions)
755                 {
756                         AssemblyBuilder asm = new AssemblyBuilder(this, name, dir, requiredPermissions, optionalPermissions, refusedPermissions);
757                         dynamicAssemblies.Add(asm);
758                         return asm;
759                 }
760
761                 internal void RenameAssembly(Assembly assembly, AssemblyName oldName)
762                 {
763                         List<string> remove = new List<string>();
764                         foreach (KeyValuePair<string, Assembly> kv in assembliesByName)
765                         {
766                                 if (kv.Value == assembly)
767                                 {
768                                         remove.Add(kv.Key);
769                                 }
770                         }
771                         foreach (string key in remove)
772                         {
773                                 assembliesByName.Remove(key);
774                         }
775                 }
776
777                 public void Dispose()
778                 {
779                         foreach (Assembly asm in assemblies)
780                         {
781                                 foreach (Module mod in asm.GetLoadedModules())
782                                 {
783                                         mod.Dispose();
784                                 }
785                         }
786                         foreach (AssemblyBuilder asm in dynamicAssemblies)
787                         {
788                                 foreach (Module mod in asm.GetLoadedModules())
789                                 {
790                                         mod.Dispose();
791                                 }
792                         }
793                 }
794
795                 public Assembly CreateMissingAssembly(string assemblyName)
796                 {
797                         return new MissingAssembly(this, assemblyName);
798                 }
799         }
800 }