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