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