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