Update to the latest ikvm.reflection
[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 Dictionary<ScopedTypeName, Type> missingTypes;
88                 private bool resolveMissingTypes;
89                 private Type typeof_System_Object;
90                 private Type typeof_System_ValueType;
91                 private Type typeof_System_Enum;
92                 private Type typeof_System_Void;
93                 private Type typeof_System_Boolean;
94                 private Type typeof_System_Char;
95                 private Type typeof_System_SByte;
96                 private Type typeof_System_Byte;
97                 private Type typeof_System_Int16;
98                 private Type typeof_System_UInt16;
99                 private Type typeof_System_Int32;
100                 private Type typeof_System_UInt32;
101                 private Type typeof_System_Int64;
102                 private Type typeof_System_UInt64;
103                 private Type typeof_System_Single;
104                 private Type typeof_System_Double;
105                 private Type typeof_System_String;
106                 private Type typeof_System_IntPtr;
107                 private Type typeof_System_UIntPtr;
108                 private Type typeof_System_TypedReference;
109                 private Type typeof_System_Type;
110                 private Type typeof_System_Array;
111                 private Type typeof_System_DateTime;
112                 private Type typeof_System_DBNull;
113                 private Type typeof_System_Decimal;
114                 private Type typeof_System_NonSerializedAttribute;
115                 private Type typeof_System_SerializableAttribute;
116                 private Type typeof_System_AttributeUsageAttribute;
117                 private Type typeof_System_Reflection_AssemblyCultureAttribute;
118                 private Type typeof_System_Runtime_InteropServices_DllImportAttribute;
119                 private Type typeof_System_Runtime_InteropServices_FieldOffsetAttribute;
120                 private Type typeof_System_Runtime_InteropServices_InAttribute;
121                 private Type typeof_System_Runtime_InteropServices_MarshalAsAttribute;
122                 private Type typeof_System_Runtime_InteropServices_UnmanagedType;
123                 private Type typeof_System_Runtime_InteropServices_VarEnum;
124                 private Type typeof_System_Runtime_InteropServices_OutAttribute;
125                 private Type typeof_System_Runtime_InteropServices_StructLayoutAttribute;
126                 private Type typeof_System_Runtime_InteropServices_OptionalAttribute;
127                 private Type typeof_System_Runtime_InteropServices_PreserveSigAttribute;
128                 private Type typeof_System_Runtime_InteropServices_ComImportAttribute;
129                 private Type typeof_System_Runtime_CompilerServices_DecimalConstantAttribute;
130                 private Type typeof_System_Runtime_CompilerServices_SpecialNameAttribute;
131                 private Type typeof_System_Runtime_CompilerServices_MethodImplAttribute;
132                 private Type typeof_System_Security_SuppressUnmanagedCodeSecurityAttribute;
133                 private Type typeof_System_Reflection_AssemblyCopyrightAttribute;
134                 private Type typeof_System_Reflection_AssemblyTrademarkAttribute;
135                 private Type typeof_System_Reflection_AssemblyProductAttribute;
136                 private Type typeof_System_Reflection_AssemblyCompanyAttribute;
137                 private Type typeof_System_Reflection_AssemblyDescriptionAttribute;
138                 private Type typeof_System_Reflection_AssemblyTitleAttribute;
139                 private Type typeof_System_Reflection_AssemblyInformationalVersionAttribute;
140                 private Type typeof_System_Reflection_AssemblyFileVersionAttribute;
141                 private Type typeof_System_Security_Permissions_CodeAccessSecurityAttribute;
142                 private Type typeof_System_Security_Permissions_HostProtectionAttribute;
143                 private Type typeof_System_Security_Permissions_PermissionSetAttribute;
144                 private Type typeof_System_Security_Permissions_SecurityAction;
145                 private List<ResolveEventHandler> resolvers = new List<ResolveEventHandler>();
146
147                 internal Assembly Mscorlib
148                 {
149                         get { return Load("mscorlib"); }
150                 }
151
152                 private Type ImportMscorlibType(System.Type type)
153                 {
154                         // We use FindType instead of ResolveType here, because on some versions of mscorlib some of
155                         // the special types we use/support are missing and the type properties are defined to
156                         // return null in that case.
157                         // Note that we don't have to unescape type.Name here, because none of the names contain special characters.
158                         return Mscorlib.FindType(new TypeName(type.Namespace, type.Name));
159                 }
160
161                 internal Type System_Object
162                 {
163                         get { return typeof_System_Object ?? (typeof_System_Object = ImportMscorlibType(typeof(System.Object))); }
164                 }
165
166                 internal Type System_ValueType
167                 {
168                         get { return typeof_System_ValueType ?? (typeof_System_ValueType = ImportMscorlibType(typeof(System.ValueType))); }
169                 }
170
171                 internal Type System_Enum
172                 {
173                         get { return typeof_System_Enum ?? (typeof_System_Enum = ImportMscorlibType(typeof(System.Enum))); }
174                 }
175
176                 internal Type System_Void
177                 {
178                         get { return typeof_System_Void ?? (typeof_System_Void = ImportMscorlibType(typeof(void))); }
179                 }
180
181                 internal Type System_Boolean
182                 {
183                         get { return typeof_System_Boolean ?? (typeof_System_Boolean = ImportMscorlibType(typeof(System.Boolean))); }
184                 }
185
186                 internal Type System_Char
187                 {
188                         get { return typeof_System_Char ?? (typeof_System_Char = ImportMscorlibType(typeof(System.Char))); }
189                 }
190
191                 internal Type System_SByte
192                 {
193                         get { return typeof_System_SByte ?? (typeof_System_SByte = ImportMscorlibType(typeof(System.SByte))); }
194                 }
195
196                 internal Type System_Byte
197                 {
198                         get { return typeof_System_Byte ?? (typeof_System_Byte = ImportMscorlibType(typeof(System.Byte))); }
199                 }
200
201                 internal Type System_Int16
202                 {
203                         get { return typeof_System_Int16 ?? (typeof_System_Int16 = ImportMscorlibType(typeof(System.Int16))); }
204                 }
205
206                 internal Type System_UInt16
207                 {
208                         get { return typeof_System_UInt16 ?? (typeof_System_UInt16 = ImportMscorlibType(typeof(System.UInt16))); }
209                 }
210
211                 internal Type System_Int32
212                 {
213                         get { return typeof_System_Int32 ?? (typeof_System_Int32 = ImportMscorlibType(typeof(System.Int32))); }
214                 }
215
216                 internal Type System_UInt32
217                 {
218                         get { return typeof_System_UInt32 ?? (typeof_System_UInt32 = ImportMscorlibType(typeof(System.UInt32))); }
219                 }
220
221                 internal Type System_Int64
222                 {
223                         get { return typeof_System_Int64 ?? (typeof_System_Int64 = ImportMscorlibType(typeof(System.Int64))); }
224                 }
225
226                 internal Type System_UInt64
227                 {
228                         get { return typeof_System_UInt64 ?? (typeof_System_UInt64 = ImportMscorlibType(typeof(System.UInt64))); }
229                 }
230
231                 internal Type System_Single
232                 {
233                         get { return typeof_System_Single ?? (typeof_System_Single = ImportMscorlibType(typeof(System.Single))); }
234                 }
235
236                 internal Type System_Double
237                 {
238                         get { return typeof_System_Double ?? (typeof_System_Double = ImportMscorlibType(typeof(System.Double))); }
239                 }
240
241                 internal Type System_String
242                 {
243                         get { return typeof_System_String ?? (typeof_System_String = ImportMscorlibType(typeof(System.String))); }
244                 }
245
246                 internal Type System_IntPtr
247                 {
248                         get { return typeof_System_IntPtr ?? (typeof_System_IntPtr = ImportMscorlibType(typeof(System.IntPtr))); }
249                 }
250
251                 internal Type System_UIntPtr
252                 {
253                         get { return typeof_System_UIntPtr ?? (typeof_System_UIntPtr = ImportMscorlibType(typeof(System.UIntPtr))); }
254                 }
255
256                 internal Type System_TypedReference
257                 {
258                         get { return typeof_System_TypedReference ?? (typeof_System_TypedReference = ImportMscorlibType(typeof(System.TypedReference))); }
259                 }
260
261                 internal Type System_Type
262                 {
263                         get { return typeof_System_Type ?? (typeof_System_Type = ImportMscorlibType(typeof(System.Type))); }
264                 }
265
266                 internal Type System_Array
267                 {
268                         get { return typeof_System_Array ?? (typeof_System_Array = ImportMscorlibType(typeof(System.Array))); }
269                 }
270
271                 internal Type System_DateTime
272                 {
273                         get { return typeof_System_DateTime ?? (typeof_System_DateTime = ImportMscorlibType(typeof(System.DateTime))); }
274                 }
275
276                 internal Type System_DBNull
277                 {
278                         get { return typeof_System_DBNull ?? (typeof_System_DBNull = ImportMscorlibType(typeof(System.DBNull))); }
279                 }
280
281                 internal Type System_Decimal
282                 {
283                         get { return typeof_System_Decimal ?? (typeof_System_Decimal = ImportMscorlibType(typeof(System.Decimal))); }
284                 }
285
286                 internal Type System_NonSerializedAttribute
287                 {
288                         get { return typeof_System_NonSerializedAttribute ?? (typeof_System_NonSerializedAttribute = ImportMscorlibType(typeof(System.NonSerializedAttribute))); }
289                 }
290
291                 internal Type System_SerializableAttribute
292                 {
293                         get { return typeof_System_SerializableAttribute ?? (typeof_System_SerializableAttribute = ImportMscorlibType(typeof(System.SerializableAttribute))); }
294                 }
295
296                 internal Type System_AttributeUsageAttribute
297                 {
298                         get { return typeof_System_AttributeUsageAttribute ?? (typeof_System_AttributeUsageAttribute = ImportMscorlibType(typeof(System.AttributeUsageAttribute))); }
299                 }
300
301                 internal Type System_Reflection_AssemblyCultureAttribute
302                 {
303                         get { return typeof_System_Reflection_AssemblyCultureAttribute ?? (typeof_System_Reflection_AssemblyCultureAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyCultureAttribute))); }
304                 }
305
306                 internal Type System_Runtime_InteropServices_DllImportAttribute
307                 {
308                         get { return typeof_System_Runtime_InteropServices_DllImportAttribute ?? (typeof_System_Runtime_InteropServices_DllImportAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.DllImportAttribute))); }
309                 }
310
311                 internal Type System_Runtime_InteropServices_FieldOffsetAttribute
312                 {
313                         get { return typeof_System_Runtime_InteropServices_FieldOffsetAttribute ?? (typeof_System_Runtime_InteropServices_FieldOffsetAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.FieldOffsetAttribute))); }
314                 }
315
316                 internal Type System_Runtime_InteropServices_InAttribute
317                 {
318                         get { return typeof_System_Runtime_InteropServices_InAttribute ?? (typeof_System_Runtime_InteropServices_InAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.InAttribute))); }
319                 }
320
321                 internal Type System_Runtime_InteropServices_MarshalAsAttribute
322                 {
323                         get { return typeof_System_Runtime_InteropServices_MarshalAsAttribute ?? (typeof_System_Runtime_InteropServices_MarshalAsAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.MarshalAsAttribute))); }
324                 }
325
326                 internal Type System_Runtime_InteropServices_UnmanagedType
327                 {
328                         get { return typeof_System_Runtime_InteropServices_UnmanagedType ?? (typeof_System_Runtime_InteropServices_UnmanagedType = ImportMscorlibType(typeof(System.Runtime.InteropServices.UnmanagedType))); }
329                 }
330
331                 internal Type System_Runtime_InteropServices_VarEnum
332                 {
333                         get { return typeof_System_Runtime_InteropServices_VarEnum ?? (typeof_System_Runtime_InteropServices_VarEnum = ImportMscorlibType(typeof(System.Runtime.InteropServices.VarEnum))); }
334                 }
335
336                 internal Type System_Runtime_InteropServices_OutAttribute
337                 {
338                         get { return typeof_System_Runtime_InteropServices_OutAttribute ?? (typeof_System_Runtime_InteropServices_OutAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.OutAttribute))); }
339                 }
340
341                 internal Type System_Runtime_InteropServices_StructLayoutAttribute
342                 {
343                         get { return typeof_System_Runtime_InteropServices_StructLayoutAttribute ?? (typeof_System_Runtime_InteropServices_StructLayoutAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.StructLayoutAttribute))); }
344                 }
345
346                 internal Type System_Runtime_InteropServices_OptionalAttribute
347                 {
348                         get { return typeof_System_Runtime_InteropServices_OptionalAttribute ?? (typeof_System_Runtime_InteropServices_OptionalAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.OptionalAttribute))); }
349                 }
350
351                 internal Type System_Runtime_InteropServices_PreserveSigAttribute
352                 {
353                         get { return typeof_System_Runtime_InteropServices_PreserveSigAttribute ?? (typeof_System_Runtime_InteropServices_PreserveSigAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.PreserveSigAttribute))); }
354                 }
355
356                 internal Type System_Runtime_InteropServices_ComImportAttribute
357                 {
358                         get { return typeof_System_Runtime_InteropServices_ComImportAttribute ?? (typeof_System_Runtime_InteropServices_ComImportAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.ComImportAttribute))); }
359                 }
360
361                 internal Type System_Runtime_CompilerServices_DecimalConstantAttribute
362                 {
363                         get { return typeof_System_Runtime_CompilerServices_DecimalConstantAttribute ?? (typeof_System_Runtime_CompilerServices_DecimalConstantAttribute = ImportMscorlibType(typeof(System.Runtime.CompilerServices.DecimalConstantAttribute))); }
364                 }
365
366                 internal Type System_Runtime_CompilerServices_SpecialNameAttribute
367                 {
368                         get { return typeof_System_Runtime_CompilerServices_SpecialNameAttribute ?? (typeof_System_Runtime_CompilerServices_SpecialNameAttribute = ImportMscorlibType(typeof(System.Runtime.CompilerServices.SpecialNameAttribute))); }
369                 }
370
371                 internal Type System_Runtime_CompilerServices_MethodImplAttribute
372                 {
373                         get { return typeof_System_Runtime_CompilerServices_MethodImplAttribute ?? (typeof_System_Runtime_CompilerServices_MethodImplAttribute = ImportMscorlibType(typeof(System.Runtime.CompilerServices.MethodImplAttribute))); }
374                 }
375
376                 internal Type System_Security_SuppressUnmanagedCodeSecurityAttribute
377                 {
378                         get { return typeof_System_Security_SuppressUnmanagedCodeSecurityAttribute ?? (typeof_System_Security_SuppressUnmanagedCodeSecurityAttribute = ImportMscorlibType(typeof(System.Security.SuppressUnmanagedCodeSecurityAttribute))); }
379                 }
380
381                 internal Type System_Reflection_AssemblyCopyrightAttribute
382                 {
383                         get { return typeof_System_Reflection_AssemblyCopyrightAttribute ?? (typeof_System_Reflection_AssemblyCopyrightAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyCopyrightAttribute))); }
384                 }
385
386                 internal Type System_Reflection_AssemblyTrademarkAttribute
387                 {
388                         get { return typeof_System_Reflection_AssemblyTrademarkAttribute ?? (typeof_System_Reflection_AssemblyTrademarkAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyTrademarkAttribute))); }
389                 }
390
391                 internal Type System_Reflection_AssemblyProductAttribute
392                 {
393                         get { return typeof_System_Reflection_AssemblyProductAttribute ?? (typeof_System_Reflection_AssemblyProductAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyProductAttribute))); }
394                 }
395
396                 internal Type System_Reflection_AssemblyCompanyAttribute
397                 {
398                         get { return typeof_System_Reflection_AssemblyCompanyAttribute ?? (typeof_System_Reflection_AssemblyCompanyAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyCompanyAttribute))); }
399                 }
400
401                 internal Type System_Reflection_AssemblyDescriptionAttribute
402                 {
403                         get { return typeof_System_Reflection_AssemblyDescriptionAttribute ?? (typeof_System_Reflection_AssemblyDescriptionAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyDescriptionAttribute))); }
404                 }
405
406                 internal Type System_Reflection_AssemblyTitleAttribute
407                 {
408                         get { return typeof_System_Reflection_AssemblyTitleAttribute ?? (typeof_System_Reflection_AssemblyTitleAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyTitleAttribute))); }
409                 }
410
411                 internal Type System_Reflection_AssemblyInformationalVersionAttribute
412                 {
413                         get { return typeof_System_Reflection_AssemblyInformationalVersionAttribute ?? (typeof_System_Reflection_AssemblyInformationalVersionAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyInformationalVersionAttribute))); }
414                 }
415
416                 internal Type System_Reflection_AssemblyFileVersionAttribute
417                 {
418                         get { return typeof_System_Reflection_AssemblyFileVersionAttribute ?? (typeof_System_Reflection_AssemblyFileVersionAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyFileVersionAttribute))); }
419                 }
420
421                 internal Type System_Security_Permissions_CodeAccessSecurityAttribute
422                 {
423                         get { return typeof_System_Security_Permissions_CodeAccessSecurityAttribute ?? (typeof_System_Security_Permissions_CodeAccessSecurityAttribute = ImportMscorlibType(typeof(System.Security.Permissions.CodeAccessSecurityAttribute))); }
424                 }
425
426                 internal Type System_Security_Permissions_HostProtectionAttribute
427                 {
428                         get { return typeof_System_Security_Permissions_HostProtectionAttribute ?? (typeof_System_Security_Permissions_HostProtectionAttribute = ImportMscorlibType(typeof(System.Security.Permissions.HostProtectionAttribute))); }
429                 }
430
431                 internal Type System_Security_Permissions_PermissionSetAttribute
432                 {
433                         get { return typeof_System_Security_Permissions_PermissionSetAttribute ?? (typeof_System_Security_Permissions_PermissionSetAttribute = ImportMscorlibType(typeof(System.Security.Permissions.PermissionSetAttribute))); }
434                 }
435
436                 internal Type System_Security_Permissions_SecurityAction
437                 {
438                         get { return typeof_System_Security_Permissions_SecurityAction ?? (typeof_System_Security_Permissions_SecurityAction = ImportMscorlibType(typeof(System.Security.Permissions.SecurityAction))); }
439                 }
440
441                 internal bool HasMscorlib
442                 {
443                         get { return GetLoadedAssembly("mscorlib") != null; }
444                 }
445
446                 public event ResolveEventHandler AssemblyResolve
447                 {
448                         add { resolvers.Add(value); }
449                         remove { resolvers.Remove(value); }
450                 }
451
452                 public Type Import(System.Type type)
453                 {
454                         Type imported;
455                         if (!importedTypes.TryGetValue(type, out imported))
456                         {
457                                 imported = ImportImpl(type);
458                                 if (imported != null)
459                                 {
460                                         importedTypes.Add(type, imported);
461                                 }
462                         }
463                         return imported;
464                 }
465
466                 private Type ImportImpl(System.Type type)
467                 {
468                         if (type.Assembly == typeof(IKVM.Reflection.Type).Assembly)
469                         {
470                                 throw new ArgumentException("Did you really want to import " + type.FullName + "?");
471                         }
472                         if (type.HasElementType)
473                         {
474                                 if (type.IsArray)
475                                 {
476                                         if (type.Name.EndsWith("[]"))
477                                         {
478                                                 return Import(type.GetElementType()).MakeArrayType();
479                                         }
480                                         else
481                                         {
482                                                 return Import(type.GetElementType()).MakeArrayType(type.GetArrayRank());
483                                         }
484                                 }
485                                 else if (type.IsByRef)
486                                 {
487                                         return Import(type.GetElementType()).MakeByRefType();
488                                 }
489                                 else if (type.IsPointer)
490                                 {
491                                         return Import(type.GetElementType()).MakePointerType();
492                                 }
493                                 else
494                                 {
495                                         throw new InvalidOperationException();
496                                 }
497                         }
498                         else if (type.IsGenericParameter)
499                         {
500                                 if (type.DeclaringMethod != null)
501                                 {
502                                         throw new NotImplementedException();
503                                 }
504                                 else
505                                 {
506                                         return Import(type.DeclaringType).GetGenericArguments()[type.GenericParameterPosition];
507                                 }
508                         }
509                         else if (type.IsGenericType && !type.IsGenericTypeDefinition)
510                         {
511                                 System.Type[] args = type.GetGenericArguments();
512                                 Type[] importedArgs = new Type[args.Length];
513                                 for (int i = 0; i < args.Length; i++)
514                                 {
515                                         importedArgs[i] = Import(args[i]);
516                                 }
517                                 return Import(type.GetGenericTypeDefinition()).MakeGenericType(importedArgs);
518                         }
519                         else
520                         {
521                                 return Import(type.Assembly).GetType(type.FullName);
522                         }
523                 }
524
525                 private Assembly Import(System.Reflection.Assembly asm)
526                 {
527                         return Load(asm.FullName);
528                 }
529
530                 public RawModule OpenRawModule(string path)
531                 {
532                         path = Path.GetFullPath(path);
533                         return OpenRawModule(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read), path);
534                 }
535
536                 public RawModule OpenRawModule(Stream stream, string location)
537                 {
538                         if (!stream.CanRead || !stream.CanSeek || stream.Position != 0)
539                         {
540                                 throw new ArgumentException("Stream must support read/seek and current position must be zero.", "stream");
541                         }
542                         return new RawModule(new ModuleReader(null, this, stream, location));
543                 }
544
545                 public Assembly LoadAssembly(RawModule module)
546                 {
547                         string refname = module.GetAssemblyName().FullName;
548                         Assembly asm = GetLoadedAssembly(refname);
549                         if (asm == null)
550                         {
551                                 asm = module.ToAssembly();
552                                 assemblies.Add(asm);
553                         }
554                         return asm;
555                 }
556
557                 public Assembly LoadFile(string path)
558                 {
559                         try
560                         {
561                                 using (RawModule module = OpenRawModule(path))
562                                 {
563                                         return LoadAssembly(module);
564                                 }
565                         }
566                         catch (IOException x)
567                         {
568                                 throw new FileNotFoundException(x.Message, x);
569                         }
570                         catch (UnauthorizedAccessException x)
571                         {
572                                 throw new FileNotFoundException(x.Message, x);
573                         }
574                 }
575
576                 private Assembly GetLoadedAssembly(string refname)
577                 {
578                         Assembly asm;
579                         if (!assembliesByName.TryGetValue(refname, out asm))
580                         {
581                                 for (int i = 0; i < assemblies.Count; i++)
582                                 {
583                                         AssemblyComparisonResult result;
584                                         // We won't allow FX unification here, because our own (non-Fusion) implementation of CompareAssemblyIdentity doesn't support it and
585                                         // we don't want to create a fundamental functional difference based on that.
586                                         if (CompareAssemblyIdentity(refname, false, assemblies[i].FullName, false, out result) && result != AssemblyComparisonResult.EquivalentFXUnified)
587                                         {
588                                                 asm = assemblies[i];
589                                                 assembliesByName.Add(refname, asm);
590                                                 break;
591                                         }
592                                 }
593                         }
594                         return asm;
595                 }
596
597                 private Assembly GetDynamicAssembly(string refname)
598                 {
599                         foreach (AssemblyBuilder asm in dynamicAssemblies)
600                         {
601                                 AssemblyComparisonResult result;
602                                 // We won't allow FX unification here, because our own (non-Fusion) implementation of CompareAssemblyIdentity doesn't support it and
603                                 // we don't want to create a fundamental functional difference based on that.
604                                 if (CompareAssemblyIdentity(refname, false, asm.FullName, false, out result) && result != AssemblyComparisonResult.EquivalentFXUnified)
605                                 {
606                                         return asm;
607                                 }
608                         }
609                         return null;
610                 }
611
612                 public Assembly Load(string refname)
613                 {
614                         return Load(refname, null, true);
615                 }
616
617                 internal Assembly Load(string refname, Assembly requestingAssembly, bool throwOnError)
618                 {
619                         Assembly asm = GetLoadedAssembly(refname);
620                         if (asm != null)
621                         {
622                                 return asm;
623                         }
624                         if (resolvers.Count == 0)
625                         {
626                                 asm = DefaultResolver(refname, throwOnError);
627                         }
628                         else
629                         {
630                                 ResolveEventArgs args = new ResolveEventArgs(refname, requestingAssembly);
631                                 foreach (ResolveEventHandler evt in resolvers)
632                                 {
633                                         asm = evt(this, args);
634                                         if (asm != null)
635                                         {
636                                                 break;
637                                         }
638                                 }
639                                 if (asm == null)
640                                 {
641                                         asm = GetDynamicAssembly(refname);
642                                 }
643                         }
644                         if (asm != null)
645                         {
646                                 string defname = asm.FullName;
647                                 if (refname != defname)
648                                 {
649                                         assembliesByName.Add(refname, asm);
650                                 }
651                                 return asm;
652                         }
653                         if (throwOnError)
654                         {
655                                 throw new FileNotFoundException(refname);
656                         }
657                         return null;
658                 }
659
660                 private Assembly DefaultResolver(string refname, bool throwOnError)
661                 {
662                         Assembly asm = GetDynamicAssembly(refname);
663                         if (asm != null)
664                         {
665                                 return asm;
666                         }
667                         string fileName;
668                         if (throwOnError)
669                         {
670                                 try
671                                 {
672                                         fileName = System.Reflection.Assembly.ReflectionOnlyLoad(refname).Location;
673                                 }
674                                 catch (System.BadImageFormatException x)
675                                 {
676                                         throw new BadImageFormatException(x.Message, x);
677                                 }
678                         }
679                         else
680                         {
681                                 try
682                                 {
683                                         fileName = System.Reflection.Assembly.ReflectionOnlyLoad(refname).Location;
684                                 }
685                                 catch (System.BadImageFormatException x)
686                                 {
687                                         throw new BadImageFormatException(x.Message, x);
688                                 }
689                                 catch (FileNotFoundException)
690                                 {
691                                         // we intentionally only swallow the FileNotFoundException, if the file exists but isn't a valid assembly,
692                                         // we should throw an exception
693                                         return null;
694                                 }
695                         }
696                         return LoadFile(fileName);
697                 }
698
699                 public Type GetType(string assemblyQualifiedTypeName)
700                 {
701                         // to be more compatible with Type.GetType(), we could call Assembly.GetCallingAssembly(),
702                         // import that assembly and pass it as the context, but implicitly importing is considered evil
703                         return GetType(null, assemblyQualifiedTypeName, false);
704                 }
705
706                 public Type GetType(string assemblyQualifiedTypeName, bool throwOnError)
707                 {
708                         // to be more compatible with Type.GetType(), we could call Assembly.GetCallingAssembly(),
709                         // import that assembly and pass it as the context, but implicitly importing is considered evil
710                         return GetType(null, assemblyQualifiedTypeName, throwOnError);
711                 }
712
713                 // note that context is slightly different from the calling assembly (System.Type.GetType),
714                 // because context is passed to the AssemblyResolve event as the RequestingAssembly
715                 public Type GetType(Assembly context, string assemblyQualifiedTypeName, bool throwOnError)
716                 {
717                         TypeNameParser parser = TypeNameParser.Parse(assemblyQualifiedTypeName, throwOnError);
718                         if (parser.Error)
719                         {
720                                 return null;
721                         }
722                         return parser.GetType(this, context, throwOnError, assemblyQualifiedTypeName);
723                 }
724
725                 public Assembly[] GetAssemblies()
726                 {
727                         Assembly[] array = new Assembly[assemblies.Count + dynamicAssemblies.Count];
728                         assemblies.CopyTo(array);
729                         for (int i = 0, j = assemblies.Count; j < array.Length; i++, j++)
730                         {
731                                 array[j] = dynamicAssemblies[i];
732                         }
733                         return array;
734                 }
735
736                 // this is equivalent to the Fusion CompareAssemblyIdentity API
737                 public bool CompareAssemblyIdentity(string assemblyIdentity1, bool unified1, string assemblyIdentity2, bool unified2, out AssemblyComparisonResult result)
738                 {
739                         return Fusion.CompareAssemblyIdentity(assemblyIdentity1, unified1, assemblyIdentity2, unified2, out result);
740                 }
741
742                 public AssemblyBuilder DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access)
743                 {
744                         return DefineDynamicAssemblyImpl(name, access, null, null, null, null);
745                 }
746
747                 public AssemblyBuilder DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access, string dir)
748                 {
749                         return DefineDynamicAssemblyImpl(name, access, dir, null, null, null);
750                 }
751
752 #if NET_4_0
753                 [Obsolete]
754 #endif
755                 public AssemblyBuilder DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access, string dir, PermissionSet requiredPermissions, PermissionSet optionalPermissions, PermissionSet refusedPermissions)
756                 {
757                         return DefineDynamicAssemblyImpl(name, access, dir, requiredPermissions, optionalPermissions, refusedPermissions);
758                 }
759
760                 private AssemblyBuilder DefineDynamicAssemblyImpl(AssemblyName name, AssemblyBuilderAccess access, string dir, PermissionSet requiredPermissions, PermissionSet optionalPermissions, PermissionSet refusedPermissions)
761                 {
762                         AssemblyBuilder asm = new AssemblyBuilder(this, name, dir, requiredPermissions, optionalPermissions, refusedPermissions);
763                         dynamicAssemblies.Add(asm);
764                         return asm;
765                 }
766
767                 internal void RenameAssembly(Assembly assembly, AssemblyName oldName)
768                 {
769                         List<string> remove = new List<string>();
770                         foreach (KeyValuePair<string, Assembly> kv in assembliesByName)
771                         {
772                                 if (kv.Value == assembly)
773                                 {
774                                         remove.Add(kv.Key);
775                                 }
776                         }
777                         foreach (string key in remove)
778                         {
779                                 assembliesByName.Remove(key);
780                         }
781                 }
782
783                 public void Dispose()
784                 {
785                         foreach (Assembly asm in assemblies)
786                         {
787                                 foreach (Module mod in asm.GetLoadedModules())
788                                 {
789                                         mod.Dispose();
790                                 }
791                         }
792                         foreach (AssemblyBuilder asm in dynamicAssemblies)
793                         {
794                                 foreach (Module mod in asm.GetLoadedModules())
795                                 {
796                                         mod.Dispose();
797                                 }
798                         }
799                 }
800
801                 public Assembly CreateMissingAssembly(string assemblyName)
802                 {
803                         return new MissingAssembly(this, assemblyName);
804                 }
805
806                 public void EnableMissingTypeResolution()
807                 {
808                         resolveMissingTypes = true;
809                 }
810
811                 private struct ScopedTypeName : IEquatable<ScopedTypeName>
812                 {
813                         private readonly object scope;
814                         private readonly TypeName name;
815
816                         internal ScopedTypeName(object scope, TypeName name)
817                         {
818                                 this.scope = scope;
819                                 this.name = name;
820                         }
821
822                         public override bool Equals(object obj)
823                         {
824                                 ScopedTypeName? other = obj as ScopedTypeName?;
825                                 return other != null && ((IEquatable<ScopedTypeName>)other.Value).Equals(this);
826                         }
827
828                         public override int GetHashCode()
829                         {
830                                 return scope.GetHashCode() * 7 + name.GetHashCode();
831                         }
832
833                         bool IEquatable<ScopedTypeName>.Equals(ScopedTypeName other)
834                         {
835                                 return other.scope == scope && other.name == name;
836                         }
837                 }
838
839                 internal Type GetMissingType(Module module, Type declaringType, TypeName typeName)
840                 {
841                         if (resolveMissingTypes || module.Assembly.__IsMissing)
842                         {
843                                 if (missingTypes == null)
844                                 {
845                                         missingTypes = new Dictionary<ScopedTypeName, Type>();
846                                 }
847                                 ScopedTypeName stn = new ScopedTypeName(declaringType ?? (object)module, typeName);
848                                 Type type;
849                                 if (!missingTypes.TryGetValue(stn, out type))
850                                 {
851                                         type = new MissingType(module, declaringType, typeName.Namespace, typeName.Name);
852                                         missingTypes.Add(stn, type);
853                                 }
854                                 return type;
855                         }
856                         return null;
857                 }
858         }
859 }