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