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