Update to the latest ikvm reflection
[mono.git] / mcs / class / IKVM.Reflection / Type.cs
1 /*
2   Copyright (C) 2009-2011 Jeroen Frijters
3
4   This software is provided 'as-is', without any express or implied
5   warranty.  In no event will the authors be held liable for any damages
6   arising from the use of this software.
7
8   Permission is granted to anyone to use this software for any purpose,
9   including commercial applications, and to alter it and redistribute it
10   freely, subject to the following restrictions:
11
12   1. The origin of this software must not be misrepresented; you must not
13      claim that you wrote the original software. If you use this software
14      in a product, an acknowledgment in the product documentation would be
15      appreciated but is not required.
16   2. Altered source versions must be plainly marked as such, and must not be
17      misrepresented as being the original software.
18   3. This notice may not be removed or altered from any source distribution.
19
20   Jeroen Frijters
21   jeroen@frijters.net
22   
23 */
24 using System;
25 using System.Runtime.InteropServices;
26 using System.Text;
27 using System.Collections.Generic;
28 using IKVM.Reflection.Emit;
29
30 namespace IKVM.Reflection
31 {
32         interface IGenericContext
33         {
34                 Type GetGenericTypeArgument(int index);
35                 Type GetGenericMethodArgument(int index);
36         }
37
38         interface IGenericBinder
39         {
40                 Type BindTypeParameter(Type type);
41                 Type BindMethodParameter(Type type);
42         }
43
44         public abstract class Type : MemberInfo, IGenericContext, IGenericBinder
45         {
46                 public static readonly Type[] EmptyTypes = Empty<Type>.Array;
47                 protected readonly Type underlyingType;
48                 protected TypeFlags typeFlags;
49
50                 [Flags]
51                 protected enum TypeFlags
52                 {
53                         // for use by TypeBuilder
54                         IsGenericTypeDefinition = 1,
55                         HasNestedTypes = 2,
56                         Baked = 4,
57
58                         // for use by MissingType
59                         ValueType = 8,
60                         NotValueType = 16,
61
62                         // for use by TypeDef, TypeBuilder or MissingType
63                         EnumOrValueType = 32,
64                 }
65
66                 // prevent subclassing by outsiders
67                 internal Type()
68                 {
69                         this.underlyingType = this;
70                 }
71
72                 internal Type(Type underlyingType)
73                 {
74                         System.Diagnostics.Debug.Assert(underlyingType.underlyingType == underlyingType);
75                         this.underlyingType = underlyingType;
76                         this.typeFlags = underlyingType.typeFlags;
77                 }
78
79                 public static Binder DefaultBinder
80                 {
81                         get { return null; }
82                 }
83
84                 public sealed override MemberTypes MemberType
85                 {
86                         get { return IsNested ? MemberTypes.NestedType : MemberTypes.TypeInfo; }
87                 }
88
89                 public virtual string AssemblyQualifiedName
90                 {
91                         // NOTE the assembly name is not escaped here, only when used in a generic type instantiation
92                         get { return this.FullName + ", " + this.Assembly.FullName; }
93                 }
94
95                 public abstract Type BaseType
96                 {
97                         get;
98                 }
99
100                 public abstract TypeAttributes Attributes
101                 {
102                         get;
103                 }
104
105                 public virtual Type GetElementType()
106                 {
107                         return null;
108                 }
109
110                 internal virtual void CheckBaked()
111                 {
112                 }
113
114                 public virtual Type[] __GetDeclaredTypes()
115                 {
116                         return Type.EmptyTypes;
117                 }
118
119                 public virtual Type[] __GetDeclaredInterfaces()
120                 {
121                         return Type.EmptyTypes;
122                 }
123
124                 public virtual MethodBase[] __GetDeclaredMethods()
125                 {
126                         return Empty<MethodBase>.Array;
127                 }
128
129                 public virtual __MethodImplMap __GetMethodImplMap()
130                 {
131                         throw new NotSupportedException();
132                 }
133
134                 public virtual FieldInfo[] __GetDeclaredFields()
135                 {
136                         return Empty<FieldInfo>.Array;
137                 }
138
139                 public virtual EventInfo[] __GetDeclaredEvents()
140                 {
141                         return Empty<EventInfo>.Array;
142                 }
143
144                 public virtual PropertyInfo[] __GetDeclaredProperties()
145                 {
146                         return Empty<PropertyInfo>.Array;
147                 }
148
149                 public virtual Type[] __GetRequiredCustomModifiers()
150                 {
151                         return Type.EmptyTypes;
152                 }
153
154                 public virtual Type[] __GetOptionalCustomModifiers()
155                 {
156                         return Type.EmptyTypes;
157                 }
158
159                 public virtual bool HasElementType
160                 {
161                         get { return false; }
162                 }
163
164                 public virtual bool IsArray
165                 {
166                         get { return false; }
167                 }
168
169                 public virtual bool __IsVector
170                 {
171                         get { return false; }
172                 }
173
174                 public virtual bool IsByRef
175                 {
176                         get { return false; }
177                 }
178
179                 public virtual bool IsPointer
180                 {
181                         get { return false; }
182                 }
183
184                 public virtual bool IsValueType
185                 {
186                         get
187                         {
188                                 Type baseType = this.BaseType;
189                                 return baseType != null
190                                         && (baseType.typeFlags & TypeFlags.EnumOrValueType) != 0
191                                         && (typeFlags & TypeFlags.EnumOrValueType) == 0;
192                         }
193                 }
194
195                 public virtual bool IsGenericParameter
196                 {
197                         get { return false; }
198                 }
199
200                 public virtual int GenericParameterPosition
201                 {
202                         get { throw new NotSupportedException(); }
203                 }
204
205                 public virtual MethodBase DeclaringMethod
206                 {
207                         get { return null; }
208                 }
209
210                 public Type UnderlyingSystemType
211                 {
212                         get { return underlyingType; }
213                 }
214
215                 public override Type DeclaringType
216                 {
217                         get { return null; }
218                 }
219
220                 public virtual string __Name
221                 {
222                         get { throw new InvalidOperationException(); }
223                 }
224
225                 public virtual string __Namespace
226                 {
227                         get { throw new InvalidOperationException(); }
228                 }
229
230                 public abstract override string Name
231                 {
232                         get;
233                 }
234
235                 public virtual string Namespace
236                 {
237                         get
238                         {
239                                 if (IsNested)
240                                 {
241                                         return DeclaringType.Namespace;
242                                 }
243                                 return __Namespace;
244                         }
245                 }
246
247                 internal virtual int GetModuleBuilderToken()
248                 {
249                         throw new InvalidOperationException();
250                 }
251
252                 public static bool operator ==(Type t1, Type t2)
253                 {
254                         // Casting to object results in smaller code than calling ReferenceEquals and makes
255                         // this method more likely to be inlined.
256                         // On CLR v2 x86, microbenchmarks show this to be faster than calling ReferenceEquals.
257                         return (object)t1 == (object)t2
258                                 || ((object)t1 != null && (object)t2 != null && (object)t1.underlyingType == (object)t2.underlyingType);
259                 }
260
261                 public static bool operator !=(Type t1, Type t2)
262                 {
263                         return !(t1 == t2);
264                 }
265
266                 public bool Equals(Type type)
267                 {
268                         return this == type;
269                 }
270
271                 public override bool Equals(object obj)
272                 {
273                         return Equals(obj as Type);
274                 }
275
276                 public override int GetHashCode()
277                 {
278                         Type type = this.UnderlyingSystemType;
279                         return ReferenceEquals(type, this) ? base.GetHashCode() : type.GetHashCode();
280                 }
281
282                 public virtual Type[] GetGenericArguments()
283                 {
284                         return Type.EmptyTypes;
285                 }
286
287                 public virtual Type[][] __GetGenericArgumentsRequiredCustomModifiers()
288                 {
289                         return Empty<Type[]>.Array;
290                 }
291
292                 public virtual Type[][] __GetGenericArgumentsOptionalCustomModifiers()
293                 {
294                         return Empty<Type[]>.Array;
295                 }
296
297                 public virtual Type GetGenericTypeDefinition()
298                 {
299                         throw new InvalidOperationException();
300                 }
301
302                 public virtual StructLayoutAttribute StructLayoutAttribute
303                 {
304                         get { return null; }
305                 }
306
307                 public virtual bool __GetLayout(out int packingSize, out int typeSize)
308                 {
309                         packingSize = 0;
310                         typeSize = 0;
311                         return false;
312                 }
313
314                 public virtual bool IsGenericType
315                 {
316                         get { return false; }
317                 }
318
319                 public virtual bool IsGenericTypeDefinition
320                 {
321                         get { return false; }
322                 }
323
324                 internal virtual bool IsGenericTypeInstance
325                 {
326                         get { return false; }
327                 }
328
329                 public virtual bool ContainsGenericParameters
330                 {
331                         get
332                         {
333                                 if (this.IsGenericParameter)
334                                 {
335                                         return true;
336                                 }
337                                 foreach (Type arg in this.GetGenericArguments())
338                                 {
339                                         if (arg.ContainsGenericParameters)
340                                         {
341                                                 return true;
342                                         }
343                                 }
344                                 return false;
345                         }
346                 }
347
348                 public virtual Type[] GetGenericParameterConstraints()
349                 {
350                         throw new InvalidOperationException();
351                 }
352
353                 public virtual GenericParameterAttributes GenericParameterAttributes
354                 {
355                         get { throw new InvalidOperationException(); }
356                 }
357
358                 public virtual int GetArrayRank()
359                 {
360                         throw new NotSupportedException();
361                 }
362
363                 public virtual int[] __GetArraySizes()
364                 {
365                         throw new NotSupportedException();
366                 }
367
368                 public virtual int[] __GetArrayLowerBounds()
369                 {
370                         throw new NotSupportedException();
371                 }
372
373                 // .NET 4.0 API
374                 public virtual Type GetEnumUnderlyingType()
375                 {
376                         if (!this.IsEnum)
377                         {
378                                 throw new ArgumentException();
379                         }
380                         CheckBaked();
381                         return GetEnumUnderlyingTypeImpl();
382                 }
383
384                 internal Type GetEnumUnderlyingTypeImpl()
385                 {
386                         foreach (FieldInfo field in __GetDeclaredFields())
387                         {
388                                 if (!field.IsStatic)
389                                 {
390                                         // the CLR assumes that an enum has only one instance field, so we can do the same
391                                         return field.FieldType;
392                                 }
393                         }
394                         throw new InvalidOperationException();
395                 }
396
397                 public override string ToString()
398                 {
399                         return FullName;
400                 }
401
402                 public abstract string FullName
403                 {
404                         get;
405                 }
406
407                 protected string GetFullName()
408                 {
409                         string ns = TypeNameParser.Escape(this.__Namespace);
410                         Type decl = this.DeclaringType;
411                         if (decl == null)
412                         {
413                                 if (ns == null)
414                                 {
415                                         return this.Name;
416                                 }
417                                 else
418                                 {
419                                         return ns + "." + this.Name;
420                                 }
421                         }
422                         else
423                         {
424                                 if (ns == null)
425                                 {
426                                         return decl.FullName + "+" + this.Name;
427                                 }
428                                 else
429                                 {
430                                         return decl.FullName + "+" + ns + "." + this.Name;
431                                 }
432                         }
433                 }
434
435                 internal virtual bool IsModulePseudoType
436                 {
437                         get { return false; }
438                 }
439
440                 internal virtual Type GetGenericTypeArgument(int index)
441                 {
442                         throw new InvalidOperationException();
443                 }
444
445                 public MemberInfo[] GetDefaultMembers()
446                 {
447                         Type defaultMemberAttribute = this.Module.universe.Import(typeof(System.Reflection.DefaultMemberAttribute));
448                         foreach (CustomAttributeData cad in CustomAttributeData.GetCustomAttributes(this))
449                         {
450                                 if (cad.Constructor.DeclaringType.Equals(defaultMemberAttribute))
451                                 {
452                                         return GetMember((string)cad.ConstructorArguments[0].Value);
453                                 }
454                         }
455                         return Empty<MemberInfo>.Array;
456                 }
457
458                 public MemberInfo[] GetMember(string name)
459                 {
460                         return GetMember(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
461                 }
462
463                 public MemberInfo[] GetMember(string name, BindingFlags bindingAttr)
464                 {
465                         return GetMember(name, MemberTypes.All, bindingAttr);
466                 }
467
468                 public MemberInfo[] GetMembers()
469                 {
470                         return GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
471                 }
472
473                 public MemberInfo[] GetMembers(BindingFlags bindingAttr)
474                 {
475                         List<MemberInfo> members = new List<MemberInfo>();
476                         members.AddRange(GetConstructors(bindingAttr));
477                         members.AddRange(GetMethods(bindingAttr));
478                         members.AddRange(GetFields(bindingAttr));
479                         members.AddRange(GetProperties(bindingAttr));
480                         members.AddRange(GetEvents(bindingAttr));
481                         members.AddRange(GetNestedTypes(bindingAttr));
482                         return members.ToArray();
483                 }
484
485                 public MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr)
486                 {
487                         MemberFilter filter = delegate(MemberInfo member, object filterCriteria) { return member.Name.Equals(filterCriteria); };
488                         return FindMembers(type, bindingAttr, filter, name);
489                 }
490
491                 private static void AddMembers(List<MemberInfo> list, MemberFilter filter, object filterCriteria, MemberInfo[] members)
492                 {
493                         foreach (MemberInfo member in members)
494                         {
495                                 if (filter == null || filter(member, filterCriteria))
496                                 {
497                                         list.Add(member);
498                                 }
499                         }
500                 }
501
502                 public MemberInfo[] FindMembers(MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, object filterCriteria)
503                 {
504                         List<MemberInfo> members = new List<MemberInfo>();
505                         if ((memberType & MemberTypes.Constructor) != 0)
506                         {
507                                 AddMembers(members, filter, filterCriteria, GetConstructors(bindingAttr));
508                         }
509                         if ((memberType & MemberTypes.Method) != 0)
510                         {
511                                 AddMembers(members, filter, filterCriteria, GetMethods(bindingAttr));
512                         }
513                         if ((memberType & MemberTypes.Field) != 0)
514                         {
515                                 AddMembers(members, filter, filterCriteria, GetFields(bindingAttr));
516                         }
517                         if ((memberType & MemberTypes.Property) != 0)
518                         {
519                                 AddMembers(members, filter, filterCriteria, GetProperties(bindingAttr));
520                         }
521                         if ((memberType & MemberTypes.Event) != 0)
522                         {
523                                 AddMembers(members, filter, filterCriteria, GetEvents(bindingAttr));
524                         }
525                         if ((memberType & MemberTypes.NestedType) != 0)
526                         {
527                                 AddMembers(members, filter, filterCriteria, GetNestedTypes(bindingAttr));
528                         }
529                         return members.ToArray();
530                 }
531
532                 public EventInfo GetEvent(string name)
533                 {
534                         return GetEvent(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
535                 }
536
537                 public EventInfo GetEvent(string name, BindingFlags bindingAttr)
538                 {
539                         foreach (EventInfo evt in GetEvents(bindingAttr))
540                         {
541                                 if (evt.Name == name)
542                                 {
543                                         return evt;
544                                 }
545                         }
546                         return null;
547                 }
548
549                 public EventInfo[] GetEvents()
550                 {
551                         return GetEvents(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
552                 }
553
554                 public EventInfo[] GetEvents(BindingFlags bindingAttr)
555                 {
556                         List<EventInfo> list = new List<EventInfo>();
557                         Type type = this;
558                         while (type != null)
559                         {
560                                 type.CheckBaked();
561                                 foreach (EventInfo evt in type.__GetDeclaredEvents())
562                                 {
563                                         if (BindingFlagsMatch(evt.IsPublic, bindingAttr, BindingFlags.Public, BindingFlags.NonPublic)
564                                                 && BindingFlagsMatch(evt.IsStatic, bindingAttr, BindingFlags.Static, BindingFlags.Instance))
565                                         {
566                                                 list.Add(evt);
567                                         }
568                                 }
569                                 if ((bindingAttr & BindingFlags.DeclaredOnly) == 0)
570                                 {
571                                         if ((bindingAttr & BindingFlags.FlattenHierarchy) == 0)
572                                         {
573                                                 bindingAttr &= ~BindingFlags.Static;
574                                         }
575                                         type = type.BaseType;
576                                 }
577                                 else
578                                 {
579                                         break;
580                                 }
581                         }
582                         return list.ToArray();
583                 }
584
585                 public FieldInfo GetField(string name)
586                 {
587                         return GetField(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
588                 }
589
590                 public FieldInfo GetField(string name, BindingFlags bindingAttr)
591                 {
592                         foreach (FieldInfo field in GetFields(bindingAttr))
593                         {
594                                 if (field.Name == name)
595                                 {
596                                         return field;
597                                 }
598                         }
599                         return null;
600                 }
601
602                 public FieldInfo[] GetFields()
603                 {
604                         return GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
605                 }
606
607                 public FieldInfo[] GetFields(BindingFlags bindingAttr)
608                 {
609                         List<FieldInfo> list = new List<FieldInfo>();
610                         CheckBaked();
611                         foreach (FieldInfo field in __GetDeclaredFields())
612                         {
613                                 if (BindingFlagsMatch(field.IsPublic, bindingAttr, BindingFlags.Public, BindingFlags.NonPublic)
614                                         && BindingFlagsMatch(field.IsStatic, bindingAttr, BindingFlags.Static, BindingFlags.Instance))
615                                 {
616                                         list.Add(field);
617                                 }
618                         }
619                         if ((bindingAttr & BindingFlags.DeclaredOnly) == 0)
620                         {
621                                 for (Type type = this.BaseType; type != null; type = type.BaseType)
622                                 {
623                                         type.CheckBaked();
624                                         foreach (FieldInfo field in type.__GetDeclaredFields())
625                                         {
626                                                 if ((field.Attributes & FieldAttributes.FieldAccessMask) > FieldAttributes.Private
627                                                         && BindingFlagsMatch(field.IsStatic, bindingAttr, BindingFlags.Static | BindingFlags.FlattenHierarchy, BindingFlags.Instance))
628                                                 {
629                                                         list.Add(field);
630                                                 }
631                                         }
632                                 }
633                         }
634                         return list.ToArray();
635                 }
636
637                 public Type[] GetInterfaces()
638                 {
639                         List<Type> list = new List<Type>();
640                         for (Type type = this; type != null; type = type.BaseType)
641                         {
642                                 AddInterfaces(list, type);
643                         }
644                         return list.ToArray();
645                 }
646
647                 private static void AddInterfaces(List<Type> list, Type type)
648                 {
649                         type.CheckBaked();
650                         foreach (Type iface in type.__GetDeclaredInterfaces())
651                         {
652                                 if (!list.Contains(iface))
653                                 {
654                                         list.Add(iface);
655                                         AddInterfaces(list, iface);
656                                 }
657                         }
658                 }
659
660                 public MethodInfo[] GetMethods(BindingFlags bindingAttr)
661                 {
662                         CheckBaked();
663                         List<MethodInfo> list = new List<MethodInfo>();
664                         foreach (MethodBase mb in __GetDeclaredMethods())
665                         {
666                                 MethodInfo mi = mb as MethodInfo;
667                                 if (mi != null
668                                         && BindingFlagsMatch(mi.IsPublic, bindingAttr, BindingFlags.Public, BindingFlags.NonPublic)
669                                         && BindingFlagsMatch(mi.IsStatic, bindingAttr, BindingFlags.Static, BindingFlags.Instance))
670                                 {
671                                         list.Add(mi);
672                                 }
673                         }
674                         if ((bindingAttr & BindingFlags.DeclaredOnly) == 0)
675                         {
676                                 for (Type type = this.BaseType; type != null; type = type.BaseType)
677                                 {
678                                         type.CheckBaked();
679                                         foreach (MethodBase mb in type.__GetDeclaredMethods())
680                                         {
681                                                 MethodInfo mi = mb as MethodInfo;
682                                                 if (mi != null
683                                                         && (mi.Attributes & MethodAttributes.MemberAccessMask) > MethodAttributes.Private
684                                                         && BindingFlagsMatch(mi.IsPublic, bindingAttr, BindingFlags.Public, BindingFlags.NonPublic)
685                                                         && BindingFlagsMatch(mi.IsStatic, bindingAttr, BindingFlags.Static | BindingFlags.FlattenHierarchy, BindingFlags.Instance)
686                                                         && !FindMethod(list, mi))
687                                                 {
688                                                         list.Add(mi);
689                                                 }
690                                         }
691                                 }
692                         }
693                         return list.ToArray();
694                 }
695
696                 private static bool FindMethod(List<MethodInfo> methods, MethodInfo method)
697                 {
698                         foreach (MethodInfo m in methods)
699                         {
700                                 if (m.Name == method.Name && m.MethodSignature.Equals(method.MethodSignature))
701                                 {
702                                         return true;
703                                 }
704                         }
705                         return false;
706                 }
707
708                 public MethodInfo[] GetMethods()
709                 {
710                         return GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
711                 }
712
713                 public MethodInfo GetMethod(string name)
714                 {
715                         return GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
716                 }
717
718                 public MethodInfo GetMethod(string name, BindingFlags bindingAttr)
719                 {
720                         MethodInfo found = null;
721                         foreach (MethodInfo method in GetMethods(bindingAttr))
722                         {
723                                 if (method.Name == name)
724                                 {
725                                         if (found != null)
726                                         {
727                                                 throw new AmbiguousMatchException();
728                                         }
729                                         found = method;
730                                 }
731                         }
732                         return found;
733                 }
734
735                 public MethodInfo GetMethod(string name, Type[] types)
736                 {
737                         return GetMethod(name, types, null);
738                 }
739
740                 public MethodInfo GetMethod(string name, Type[] types, ParameterModifier[] modifiers)
741                 {
742                         return GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public, null, types, modifiers);
743                 }
744
745                 public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
746                 {
747                         MethodInfo found = null;
748                         foreach (MethodInfo method in GetMethods(bindingAttr))
749                         {
750                                 if (method.Name == name && method.MethodSignature.MatchParameterTypes(types))
751                                 {
752                                         if (found != null)
753                                         {
754                                                 throw new AmbiguousMatchException();
755                                         }
756                                         found = method;
757                                 }
758                         }
759                         return found;
760                 }
761
762                 public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
763                 {
764                         // FXBUG callConvention seems to be ignored
765                         return GetMethod(name, bindingAttr, binder, types, modifiers);
766                 }
767
768                 public ConstructorInfo[] GetConstructors()
769                 {
770                         return GetConstructors(BindingFlags.Public | BindingFlags.Instance);
771                 }
772
773                 public ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
774                 {
775                         CheckBaked();
776                         List<ConstructorInfo> list = new List<ConstructorInfo>();
777                         foreach (MethodBase mb in __GetDeclaredMethods())
778                         {
779                                 ConstructorInfo constructor = mb as ConstructorInfo;
780                                 if (constructor != null
781                                         && BindingFlagsMatch(constructor.IsPublic, bindingAttr, BindingFlags.Public, BindingFlags.NonPublic)
782                                         && BindingFlagsMatch(constructor.IsStatic, bindingAttr, BindingFlags.Static, BindingFlags.Instance))
783                                 {
784                                         list.Add(constructor);
785                                 }
786                         }
787                         return list.ToArray();
788                 }
789
790                 public ConstructorInfo GetConstructor(Type[] types)
791                 {
792                         return GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, CallingConventions.Standard, types, null);
793                 }
794
795                 public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
796                 {
797                         foreach (ConstructorInfo constructor in GetConstructors(bindingAttr))
798                         {
799                                 if (constructor.MethodSignature.MatchParameterTypes(types))
800                                 {
801                                         return constructor;
802                                 }
803                         }
804                         return null;
805                 }
806
807                 public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, CallingConventions callingConvention, Type[] types, ParameterModifier[] modifiers)
808                 {
809                         // FXBUG callConvention seems to be ignored
810                         return GetConstructor(bindingAttr, binder, types, modifiers);
811                 }
812
813                 internal Type ResolveNestedType(TypeName typeName)
814                 {
815                         return FindNestedType(typeName) ?? Module.universe.GetMissingTypeOrThrow(Module, this, typeName);
816                 }
817
818                 // unlike the public API, this takes the namespace and name into account
819                 internal virtual Type FindNestedType(TypeName name)
820                 {
821                         foreach (Type type in __GetDeclaredTypes())
822                         {
823                                 if (type.__Namespace == name.Namespace && type.__Name == name.Name)
824                                 {
825                                         return type;
826                                 }
827                         }
828                         return null;
829                 }
830
831                 public Type GetNestedType(string name)
832                 {
833                         return GetNestedType(name, BindingFlags.Public);
834                 }
835
836                 public Type GetNestedType(string name, BindingFlags bindingAttr)
837                 {
838                         foreach (Type type in GetNestedTypes(bindingAttr))
839                         {
840                                 // FXBUG the namespace is ignored
841                                 if (type.__Name == name)
842                                 {
843                                         return type;
844                                 }
845                         }
846                         return null;
847                 }
848
849                 public Type[] GetNestedTypes()
850                 {
851                         return GetNestedTypes(BindingFlags.Public);
852                 }
853
854                 public Type[] GetNestedTypes(BindingFlags bindingAttr)
855                 {
856                         CheckBaked();
857                         List<Type> list = new List<Type>();
858                         foreach (Type type in __GetDeclaredTypes())
859                         {
860                                 if (BindingFlagsMatch(type.IsNestedPublic, bindingAttr, BindingFlags.Public, BindingFlags.NonPublic))
861                                 {
862                                         list.Add(type);
863                                 }
864                         }
865                         return list.ToArray();
866                 }
867
868                 public PropertyInfo[] GetProperties()
869                 {
870                         return GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
871                 }
872
873                 public PropertyInfo[] GetProperties(BindingFlags bindingAttr)
874                 {
875                         List<PropertyInfo> list = new List<PropertyInfo>();
876                         Type type = this;
877                         while (type != null)
878                         {
879                                 type.CheckBaked();
880                                 foreach (PropertyInfo property in type.__GetDeclaredProperties())
881                                 {
882                                         if (BindingFlagsMatch(property.IsPublic, bindingAttr, BindingFlags.Public, BindingFlags.NonPublic)
883                                                 && BindingFlagsMatch(property.IsStatic, bindingAttr, BindingFlags.Static, BindingFlags.Instance))
884                                         {
885                                                 list.Add(property);
886                                         }
887                                 }
888                                 if ((bindingAttr & BindingFlags.DeclaredOnly) == 0)
889                                 {
890                                         if ((bindingAttr & BindingFlags.FlattenHierarchy) == 0)
891                                         {
892                                                 bindingAttr &= ~BindingFlags.Static;
893                                         }
894                                         type = type.BaseType;
895                                 }
896                                 else
897                                 {
898                                         break;
899                                 }
900                         }
901                         return list.ToArray();
902                 }
903
904                 public PropertyInfo GetProperty(string name)
905                 {
906                         return GetProperty(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
907                 }
908
909                 public PropertyInfo GetProperty(string name, BindingFlags bindingAttr)
910                 {
911                         foreach (PropertyInfo prop in GetProperties(bindingAttr))
912                         {
913                                 if (prop.Name == name)
914                                 {
915                                         return prop;
916                                 }
917                         }
918                         return null;
919                 }
920
921                 public PropertyInfo GetProperty(string name, Type returnType)
922                 {
923                         PropertyInfo found = null;
924                         foreach (PropertyInfo prop in GetProperties())
925                         {
926                                 if (prop.Name == name && prop.PropertyType.Equals(returnType))
927                                 {
928                                         if (found != null)
929                                         {
930                                                 throw new AmbiguousMatchException();
931                                         }
932                                         found = prop;
933                                 }
934                         }
935                         return found;
936                 }
937
938                 public PropertyInfo GetProperty(string name, Type[] types)
939                 {
940                         PropertyInfo found = null;
941                         foreach (PropertyInfo prop in GetProperties())
942                         {
943                                 if (prop.Name == name && MatchParameterTypes(prop.GetIndexParameters(), types))
944                                 {
945                                         if (found != null)
946                                         {
947                                                 throw new AmbiguousMatchException();
948                                         }
949                                         found = prop;
950                                 }
951                         }
952                         return found;
953                 }
954
955                 private static bool MatchParameterTypes(ParameterInfo[] parameters, Type[] types)
956                 {
957                         if (parameters.Length == types.Length)
958                         {
959                                 for (int i = 0; i < parameters.Length; i++)
960                                 {
961                                         if (!parameters[i].ParameterType.Equals(types[i]))
962                                         {
963                                                 return false;
964                                         }
965                                 }
966                                 return true;
967                         }
968                         return false;
969                 }
970
971                 public PropertyInfo GetProperty(string name, Type returnType, Type[] types)
972                 {
973                         return GetProperty(name, returnType, types, null);
974                 }
975
976                 public PropertyInfo GetProperty(string name, Type returnType, Type[] types, ParameterModifier[] modifiers)
977                 {
978                         return GetProperty(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static, null, returnType, types, modifiers);
979                 }
980
981                 public PropertyInfo GetProperty(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
982                 {
983                         PropertyInfo found = null;
984                         foreach (PropertyInfo prop in GetProperties(bindingAttr))
985                         {
986                                 if (prop.Name == name && prop.PropertyType.Equals(returnType) && MatchParameterTypes(prop.GetIndexParameters(), types))
987                                 {
988                                         if (found != null)
989                                         {
990                                                 throw new AmbiguousMatchException();
991                                         }
992                                         found = prop;
993                                 }
994                         }
995                         return found;
996                 }
997
998                 public Type GetInterface(string name)
999                 {
1000                         return GetInterface(name, false);
1001                 }
1002
1003                 public Type GetInterface(string name, bool ignoreCase)
1004                 {
1005                         if (ignoreCase)
1006                         {
1007                                 throw new NotImplementedException();
1008                         }
1009                         foreach (Type type in GetInterfaces())
1010                         {
1011                                 if (type.FullName == name)
1012                                 {
1013                                         return type;
1014                                 }
1015                         }
1016                         return null;
1017                 }
1018
1019                 public Type[] FindInterfaces(TypeFilter filter, object filterCriteria)
1020                 {
1021                         List<Type> list = new List<Type>();
1022                         foreach (Type type in GetInterfaces())
1023                         {
1024                                 if (filter(type, filterCriteria))
1025                                 {
1026                                         list.Add(type);
1027                                 }
1028                         }
1029                         return list.ToArray();
1030                 }
1031
1032                 public ConstructorInfo TypeInitializer
1033                 {
1034                         get { return GetConstructor(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); }
1035                 }
1036
1037                 public bool IsPrimitive
1038                 {
1039                         get
1040                         {
1041                                 Universe u = this.Module.universe;
1042                                 return this == u.System_Boolean
1043                                         || this == u.System_Byte
1044                                         || this == u.System_SByte
1045                                         || this == u.System_Int16
1046                                         || this == u.System_UInt16
1047                                         || this == u.System_Int32
1048                                         || this == u.System_UInt32
1049                                         || this == u.System_Int64
1050                                         || this == u.System_UInt64
1051                                         || this == u.System_IntPtr
1052                                         || this == u.System_UIntPtr
1053                                         || this == u.System_Char
1054                                         || this == u.System_Double
1055                                         || this == u.System_Single
1056                                         ;
1057                         }
1058                 }
1059
1060                 public bool IsEnum
1061                 {
1062                         get
1063                         {
1064                                 Type baseType = this.BaseType;
1065                                 return baseType != null
1066                                         && (baseType.typeFlags & TypeFlags.EnumOrValueType) != 0
1067                                         && baseType.__Name[0] == 'E';
1068                         }
1069                 }
1070
1071                 public bool IsSealed
1072                 {
1073                         get { return (Attributes & TypeAttributes.Sealed) != 0; }
1074                 }
1075
1076                 public bool IsAbstract
1077                 {
1078                         get { return (Attributes & TypeAttributes.Abstract) != 0; }
1079                 }
1080
1081                 private bool CheckVisibility(TypeAttributes access)
1082                 {
1083                         return (Attributes & TypeAttributes.VisibilityMask) == access;
1084                 }
1085
1086                 public bool IsPublic
1087                 {
1088                         get { return CheckVisibility(TypeAttributes.Public); }
1089                 }
1090
1091                 public bool IsNestedPublic
1092                 {
1093                         get { return CheckVisibility(TypeAttributes.NestedPublic); }
1094                 }
1095
1096                 public bool IsNestedPrivate
1097                 {
1098                         get { return CheckVisibility(TypeAttributes.NestedPrivate); }
1099                 }
1100
1101                 public bool IsNestedFamily
1102                 {
1103                         get { return CheckVisibility(TypeAttributes.NestedFamily); }
1104                 }
1105
1106                 public bool IsNestedAssembly
1107                 {
1108                         get { return CheckVisibility(TypeAttributes.NestedAssembly); }
1109                 }
1110
1111                 public bool IsNestedFamANDAssem
1112                 {
1113                         get { return CheckVisibility(TypeAttributes.NestedFamANDAssem); }
1114                 }
1115
1116                 public bool IsNestedFamORAssem
1117                 {
1118                         get { return CheckVisibility(TypeAttributes.NestedFamORAssem); }
1119                 }
1120
1121                 public bool IsNotPublic
1122                 {
1123                         get { return CheckVisibility(TypeAttributes.NotPublic); }
1124                 }
1125
1126                 public bool IsImport
1127                 {
1128                         get { return (Attributes & TypeAttributes.Import) != 0; }
1129                 }
1130
1131                 public bool IsCOMObject
1132                 {
1133                         get { return IsClass && IsImport; }
1134                 }
1135
1136                 public bool IsContextful
1137                 {
1138                         get { return IsSubclassOf(this.Module.universe.Import(typeof(ContextBoundObject))); }
1139                 }
1140
1141                 public bool IsMarshalByRef
1142                 {
1143                         get { return IsSubclassOf(this.Module.universe.Import(typeof(MarshalByRefObject))); }
1144                 }
1145
1146                 public virtual bool IsVisible
1147                 {
1148                         get { return IsPublic || (IsNestedPublic && this.DeclaringType.IsVisible); }
1149                 }
1150
1151                 public bool IsAnsiClass
1152                 {
1153                         get { return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AnsiClass; }
1154                 }
1155
1156                 public bool IsUnicodeClass
1157                 {
1158                         get { return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass; }
1159                 }
1160
1161                 public bool IsAutoClass
1162                 {
1163                         get { return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass; }
1164                 }
1165
1166                 public bool IsAutoLayout
1167                 {
1168                         get { return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout; }
1169                 }
1170
1171                 public bool IsLayoutSequential
1172                 {
1173                         get { return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout; }
1174                 }
1175
1176                 public bool IsExplicitLayout
1177                 {
1178                         get { return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout; }
1179                 }
1180
1181                 public bool IsSpecialName
1182                 {
1183                         get { return (Attributes & TypeAttributes.SpecialName) != 0; }
1184                 }
1185
1186                 public bool IsSerializable
1187                 {
1188                         get { return (Attributes & TypeAttributes.Serializable) != 0; }
1189                 }
1190
1191                 public bool IsClass
1192                 {
1193                         get { return !IsInterface && !IsValueType; }
1194                 }
1195
1196                 public bool IsInterface
1197                 {
1198                         get { return (Attributes & TypeAttributes.Interface) != 0; }
1199                 }
1200
1201                 public bool IsNested
1202                 {
1203                         // FXBUG we check the declaring type (like .NET) and this results
1204                         // in IsNested returning true for a generic type parameter
1205                         get { return this.DeclaringType != null; }
1206                 }
1207
1208                 public virtual bool __ContainsMissingType
1209                 {
1210                         get
1211                         {
1212                                 if (this.__IsMissing)
1213                                 {
1214                                         return true;
1215                                 }
1216                                 foreach (Type arg in this.GetGenericArguments())
1217                                 {
1218                                         if (arg.__ContainsMissingType)
1219                                         {
1220                                                 return true;
1221                                         }
1222                                 }
1223                                 return false;
1224                         }
1225                 }
1226
1227                 public Type MakeArrayType()
1228                 {
1229                         return ArrayType.Make(this, null, null);
1230                 }
1231
1232                 public Type __MakeArrayType(Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1233                 {
1234                         return ArrayType.Make(this, Util.Copy(requiredCustomModifiers), Util.Copy(optionalCustomModifiers));
1235                 }
1236
1237                 public Type MakeArrayType(int rank)
1238                 {
1239                         return MultiArrayType.Make(this, rank, Empty<int>.Array, new int[rank], null, null);
1240                 }
1241
1242                 public Type __MakeArrayType(int rank, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1243                 {
1244                         return MultiArrayType.Make(this, rank, Empty<int>.Array, new int[rank], Util.Copy(requiredCustomModifiers), Util.Copy(optionalCustomModifiers));
1245                 }
1246
1247                 public Type __MakeArrayType(int rank, int[] sizes, int[] lobounds, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1248                 {
1249                         return MultiArrayType.Make(this, rank, sizes ?? Empty<int>.Array, lobounds ?? Empty<int>.Array, Util.Copy(requiredCustomModifiers), Util.Copy(optionalCustomModifiers));
1250                 }
1251
1252                 public Type MakeByRefType()
1253                 {
1254                         return ByRefType.Make(this, null, null);
1255                 }
1256
1257                 public Type __MakeByRefType(Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1258                 {
1259                         return ByRefType.Make(this, Util.Copy(requiredCustomModifiers), Util.Copy(optionalCustomModifiers));
1260                 }
1261
1262                 public Type MakePointerType()
1263                 {
1264                         return PointerType.Make(this, null, null);
1265                 }
1266
1267                 public Type __MakePointerType(Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1268                 {
1269                         return PointerType.Make(this, Util.Copy(requiredCustomModifiers), Util.Copy(optionalCustomModifiers));
1270                 }
1271
1272                 public Type MakeGenericType(params Type[] typeArguments)
1273                 {
1274                         return __MakeGenericType(typeArguments, null, null);
1275                 }
1276
1277                 public Type __MakeGenericType(Type[] typeArguments, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
1278                 {
1279                         if (!this.__IsMissing && !this.IsGenericTypeDefinition)
1280                         {
1281                                 throw new InvalidOperationException();
1282                         }
1283                         return GenericTypeInstance.Make(this, Util.Copy(typeArguments), Util.Copy(requiredCustomModifiers), Util.Copy(optionalCustomModifiers));
1284                 }
1285
1286                 public static System.Type __GetSystemType(TypeCode typeCode)
1287                 {
1288                         switch (typeCode)
1289                         {
1290                                 case TypeCode.Boolean:
1291                                         return typeof(System.Boolean);
1292                                 case TypeCode.Byte:
1293                                         return typeof(System.Byte);
1294                                 case TypeCode.Char:
1295                                         return typeof(System.Char);
1296                                 case TypeCode.DBNull:
1297                                         return typeof(System.DBNull);
1298                                 case TypeCode.DateTime:
1299                                         return typeof(System.DateTime);
1300                                 case TypeCode.Decimal:
1301                                         return typeof(System.Decimal);
1302                                 case TypeCode.Double:
1303                                         return typeof(System.Double);
1304                                 case TypeCode.Empty:
1305                                         return null;
1306                                 case TypeCode.Int16:
1307                                         return typeof(System.Int16);
1308                                 case TypeCode.Int32:
1309                                         return typeof(System.Int32);
1310                                 case TypeCode.Int64:
1311                                         return typeof(System.Int64);
1312                                 case TypeCode.Object:
1313                                         return typeof(System.Object);
1314                                 case TypeCode.SByte:
1315                                         return typeof(System.SByte);
1316                                 case TypeCode.Single:
1317                                         return typeof(System.Single);
1318                                 case TypeCode.String:
1319                                         return typeof(System.String);
1320                                 case TypeCode.UInt16:
1321                                         return typeof(System.UInt16);
1322                                 case TypeCode.UInt32:
1323                                         return typeof(System.UInt32);
1324                                 case TypeCode.UInt64:
1325                                         return typeof(System.UInt64);
1326                                 default:
1327                                         throw new ArgumentOutOfRangeException();
1328                         }
1329                 }
1330
1331                 public static TypeCode GetTypeCode(Type type)
1332                 {
1333                         if (type == null)
1334                         {
1335                                 return TypeCode.Empty;
1336                         }
1337                         if (!type.__IsMissing && type.IsEnum)
1338                         {
1339                                 type = type.GetEnumUnderlyingType();
1340                         }
1341                         Universe u = type.Module.universe;
1342                         if (type == u.System_Boolean)
1343                         {
1344                                 return TypeCode.Boolean;
1345                         }
1346                         else if (type == u.System_Char)
1347                         {
1348                                 return TypeCode.Char;
1349                         }
1350                         else if (type == u.System_SByte)
1351                         {
1352                                 return TypeCode.SByte;
1353                         }
1354                         else if (type == u.System_Byte)
1355                         {
1356                                 return TypeCode.Byte;
1357                         }
1358                         else if (type == u.System_Int16)
1359                         {
1360                                 return TypeCode.Int16;
1361                         }
1362                         else if (type == u.System_UInt16)
1363                         {
1364                                 return TypeCode.UInt16;
1365                         }
1366                         else if (type == u.System_Int32)
1367                         {
1368                                 return TypeCode.Int32;
1369                         }
1370                         else if (type == u.System_UInt32)
1371                         {
1372                                 return TypeCode.UInt32;
1373                         }
1374                         else if (type == u.System_Int64)
1375                         {
1376                                 return TypeCode.Int64;
1377                         }
1378                         else if (type == u.System_UInt64)
1379                         {
1380                                 return TypeCode.UInt64;
1381                         }
1382                         else if (type == u.System_Single)
1383                         {
1384                                 return TypeCode.Single;
1385                         }
1386                         else if (type == u.System_Double)
1387                         {
1388                                 return TypeCode.Double;
1389                         }
1390                         else if (type == u.System_DateTime)
1391                         {
1392                                 return TypeCode.DateTime;
1393                         }
1394                         else if (type == u.System_DBNull)
1395                         {
1396                                 return TypeCode.DBNull;
1397                         }
1398                         else if (type == u.System_Decimal)
1399                         {
1400                                 return TypeCode.Decimal;
1401                         }
1402                         else if (type == u.System_String)
1403                         {
1404                                 return TypeCode.String;
1405                         }
1406                         else if (type.__IsMissing)
1407                         {
1408                                 throw new MissingMemberException(type);
1409                         }
1410                         else
1411                         {
1412                                 return TypeCode.Object;
1413                         }
1414                 }
1415
1416                 public Assembly Assembly
1417                 {
1418                         get { return Module.Assembly; }
1419                 }
1420
1421                 // note that interface/delegate co- and contravariance is not considered
1422                 public bool IsAssignableFrom(Type type)
1423                 {
1424                         if (this.Equals(type))
1425                         {
1426                                 return true;
1427                         }
1428                         else if (type == null)
1429                         {
1430                                 return false;
1431                         }
1432                         else if (this.IsArray && type.IsArray)
1433                         {
1434                                 if (this.GetArrayRank() != type.GetArrayRank())
1435                                 {
1436                                         return false;
1437                                 }
1438                                 else if (this.__IsVector && !type.__IsVector)
1439                                 {
1440                                         return false;
1441                                 }
1442                                 Type e1 = this.GetElementType();
1443                                 Type e2 = type.GetElementType();
1444                                 return e1.IsValueType == e2.IsValueType && e1.IsAssignableFrom(e2);
1445                         }
1446                         else if (this.IsSealed)
1447                         {
1448                                 return false;
1449                         }
1450                         else if (this.IsInterface)
1451                         {
1452                                 return Array.IndexOf(type.GetInterfaces(), this) != -1;
1453                         }
1454                         else if (type.IsInterface)
1455                         {
1456                                 return this == this.Module.universe.System_Object;
1457                         }
1458                         else if (type.IsPointer)
1459                         {
1460                                 return this == this.Module.universe.System_Object || this == this.Module.universe.System_ValueType;
1461                         }
1462                         else
1463                         {
1464                                 return type.IsSubclassOf(this);
1465                         }
1466                 }
1467
1468                 public bool IsSubclassOf(Type type)
1469                 {
1470                         Type thisType = this.BaseType;
1471                         while (thisType != null)
1472                         {
1473                                 if (thisType.Equals(type))
1474                                 {
1475                                         return true;
1476                                 }
1477                                 thisType = thisType.BaseType;
1478                         }
1479                         return false;
1480                 }
1481
1482                 // This returns true if this type directly (i.e. not inherited from the base class) implements the interface.
1483                 // Note that a complicating factor is that the interface itself can be implemented by an interface that extends it.
1484                 private bool IsDirectlyImplementedInterface(Type interfaceType)
1485                 {
1486                         foreach (Type iface in __GetDeclaredInterfaces())
1487                         {
1488                                 if (interfaceType.IsAssignableFrom(iface))
1489                                 {
1490                                         return true;
1491                                 }
1492                         }
1493                         return false;
1494                 }
1495
1496                 public InterfaceMapping GetInterfaceMap(Type interfaceType)
1497                 {
1498                         CheckBaked();
1499                         InterfaceMapping map = new InterfaceMapping();
1500                         if (!IsDirectlyImplementedInterface(interfaceType))
1501                         {
1502                                 Type baseType = this.BaseType;
1503                                 if (baseType == null)
1504                                 {
1505                                         throw new ArgumentException();
1506                                 }
1507                                 else
1508                                 {
1509                                         map = baseType.GetInterfaceMap(interfaceType);
1510                                 }
1511                         }
1512                         else
1513                         {
1514                                 map.InterfaceMethods = interfaceType.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
1515                                 map.InterfaceType = interfaceType;
1516                                 map.TargetMethods = new MethodInfo[map.InterfaceMethods.Length];
1517                                 FillInExplicitInterfaceMethods(map.InterfaceMethods, map.TargetMethods);
1518                                 MethodInfo[] methods = GetMethods(BindingFlags.Instance | BindingFlags.Public);
1519                                 for (int i = 0; i < map.TargetMethods.Length; i++)
1520                                 {
1521                                         if (map.TargetMethods[i] == null)
1522                                         {
1523                                                 // TODO use proper method resolution (also take into account that no implicit base class implementation is used across assembly boundaries)
1524                                                 for (int j = 0; j < methods.Length; j++)
1525                                                 {
1526                                                         if (methods[j].Name == map.InterfaceMethods[i].Name
1527                                                                 && methods[j].MethodSignature.Equals(map.InterfaceMethods[i].MethodSignature))
1528                                                         {
1529                                                                 map.TargetMethods[i] = methods[j];
1530                                                         }
1531                                                 }
1532                                         }
1533                                 }
1534                                 for (Type baseType = this.BaseType; baseType != null && interfaceType.IsAssignableFrom(baseType); baseType = baseType.BaseType)
1535                                 {
1536                                         baseType.FillInExplicitInterfaceMethods(map.InterfaceMethods, map.TargetMethods);
1537                                 }
1538                         }
1539                         map.TargetType = this;
1540                         return map;
1541                 }
1542
1543                 internal void FillInExplicitInterfaceMethods(MethodInfo[] interfaceMethods, MethodInfo[] targetMethods)
1544                 {
1545                         __MethodImplMap impl = __GetMethodImplMap();
1546                         for (int i = 0; i < impl.MethodDeclarations.Length; i++)
1547                         {
1548                                 for (int j = 0; j < impl.MethodDeclarations[i].Length; j++)
1549                                 {
1550                                         int index = Array.IndexOf(interfaceMethods, impl.MethodDeclarations[i][j]);
1551                                         if (index != -1 && targetMethods[index] == null)
1552                                         {
1553                                                 targetMethods[index] = impl.MethodBodies[i];
1554                                         }
1555                                 }
1556                         }
1557                 }
1558
1559                 Type IGenericContext.GetGenericTypeArgument(int index)
1560                 {
1561                         return GetGenericTypeArgument(index);
1562                 }
1563
1564                 Type IGenericContext.GetGenericMethodArgument(int index)
1565                 {
1566                         throw new BadImageFormatException();
1567                 }
1568
1569                 Type IGenericBinder.BindTypeParameter(Type type)
1570                 {
1571                         return GetGenericTypeArgument(type.GenericParameterPosition);
1572                 }
1573
1574                 Type IGenericBinder.BindMethodParameter(Type type)
1575                 {
1576                         throw new BadImageFormatException();
1577                 }
1578
1579                 internal virtual Type BindTypeParameters(IGenericBinder binder)
1580                 {
1581                         if (IsGenericTypeDefinition)
1582                         {
1583                                 Type[] args = GetGenericArguments();
1584                                 Type.InplaceBindTypeParameters(binder, args);
1585                                 return GenericTypeInstance.Make(this, args, null, null);
1586                         }
1587                         else
1588                         {
1589                                 return this;
1590                         }
1591                 }
1592
1593                 internal static void InplaceBindTypeParameters(IGenericBinder binder, Type[] types)
1594                 {
1595                         for (int i = 0; i < types.Length; i++)
1596                         {
1597                                 types[i] = types[i].BindTypeParameters(binder);
1598                         }
1599                 }
1600
1601                 internal virtual MethodBase FindMethod(string name, MethodSignature signature)
1602                 {
1603                         foreach (MethodBase method in __GetDeclaredMethods())
1604                         {
1605                                 if (method.Name == name && method.MethodSignature.Equals(signature))
1606                                 {
1607                                         return method;
1608                                 }
1609                         }
1610                         return null;
1611                 }
1612
1613                 internal virtual FieldInfo FindField(string name, FieldSignature signature)
1614                 {
1615                         foreach (FieldInfo field in __GetDeclaredFields())
1616                         {
1617                                 if (field.Name == name && field.FieldSignature.Equals(signature))
1618                                 {
1619                                         return field;
1620                                 }
1621                         }
1622                         return null;
1623                 }
1624
1625                 internal bool IsAllowMultipleCustomAttribute
1626                 {
1627                         get
1628                         {
1629                                 IList<CustomAttributeData> cad = GetCustomAttributesData(this.Module.universe.System_AttributeUsageAttribute);
1630                                 if (cad.Count == 1)
1631                                 {
1632                                         foreach (CustomAttributeNamedArgument arg in cad[0].NamedArguments)
1633                                         {
1634                                                 if (arg.MemberInfo.Name == "AllowMultiple")
1635                                                 {
1636                                                         return (bool)arg.TypedValue.Value;
1637                                                 }
1638                                         }
1639                                 }
1640                                 return false;
1641                         }
1642                 }
1643
1644                 internal bool IsPseudoCustomAttribute
1645                 {
1646                         get
1647                         {
1648                                 Universe u = this.Module.universe;
1649                                 return this == u.System_NonSerializedAttribute
1650                                         || this == u.System_SerializableAttribute
1651                                         || this == u.System_Runtime_InteropServices_DllImportAttribute
1652                                         || this == u.System_Runtime_InteropServices_FieldOffsetAttribute
1653                                         || this == u.System_Runtime_InteropServices_InAttribute
1654                                         || this == u.System_Runtime_InteropServices_MarshalAsAttribute
1655                                         || this == u.System_Runtime_InteropServices_OutAttribute
1656                                         || this == u.System_Runtime_InteropServices_StructLayoutAttribute
1657                                         || this == u.System_Runtime_InteropServices_OptionalAttribute
1658                                         || this == u.System_Runtime_InteropServices_PreserveSigAttribute
1659                                         || this == u.System_Runtime_InteropServices_ComImportAttribute
1660                                         || this == u.System_Runtime_CompilerServices_SpecialNameAttribute
1661                                         || this == u.System_Runtime_CompilerServices_MethodImplAttribute
1662                                         ;
1663                         }
1664                 }
1665
1666                 internal Type MarkNotValueType()
1667                 {
1668                         typeFlags |= TypeFlags.NotValueType;
1669                         return this;
1670                 }
1671
1672                 internal Type MarkValueType()
1673                 {
1674                         typeFlags |= TypeFlags.ValueType;
1675                         return this;
1676                 }
1677
1678                 internal ConstructorInfo GetPseudoCustomAttributeConstructor(params Type[] parameterTypes)
1679                 {
1680                         Universe u = this.Module.universe;
1681                         MethodSignature methodSig = MethodSignature.MakeFromBuilder(u.System_Void, parameterTypes, null, CallingConventions.Standard | CallingConventions.HasThis, 0);
1682                         MethodBase mb =
1683                                 FindMethod(".ctor", methodSig) ??
1684                                 u.GetMissingMethodOrThrow(this, ".ctor", methodSig);
1685                         return (ConstructorInfo)mb;
1686                 }
1687
1688                 public MethodBase __CreateMissingMethod(string name, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
1689                 {
1690                         MethodSignature sig = new MethodSignature(
1691                                 returnType ?? this.Module.universe.System_Void,
1692                                 Util.Copy(parameterTypes),
1693                                 PackedCustomModifiers.CreateFromExternal(returnTypeOptionalCustomModifiers, returnTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers, parameterTypeRequiredCustomModifiers, parameterTypes.Length),
1694                                 callingConvention,
1695                                 0);
1696                         MethodInfo method = new MissingMethod(this, name, sig);
1697                         if (name == ".ctor" || name == ".cctor")
1698                         {
1699                                 return new ConstructorInfoImpl(method);
1700                         }
1701                         return method;
1702                 }
1703
1704                 public FieldInfo __CreateMissingField(string name, Type fieldType, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1705                 {
1706                         return new MissingField(this, name, FieldSignature.Create(fieldType, optionalCustomModifiers, requiredCustomModifiers));
1707                 }
1708
1709                 internal virtual Type SetMetadataTokenForMissing(int token)
1710                 {
1711                         return this;
1712                 }
1713
1714                 protected void MarkEnumOrValueType(string typeNamespace, string typeName)
1715                 {
1716                         // we don't assume that mscorlib won't have nested types with these names,
1717                         // so we don't check that we're not a nested type
1718                         if (typeNamespace == "System"
1719                                 && (typeName == "Enum" || typeName == "ValueType")
1720                                 && this.Assembly.GetName().Name.Equals("mscorlib", StringComparison.OrdinalIgnoreCase))
1721                         {
1722                                 typeFlags |= TypeFlags.EnumOrValueType;
1723                         }
1724                 }
1725
1726                 internal virtual IList<CustomAttributeData> GetInterfaceImplCustomAttributes(Type interfaceType, Type attributeType)
1727                 {
1728                         throw new NotSupportedException();
1729                 }
1730         }
1731
1732         abstract class ElementHolderType : Type
1733         {
1734                 protected readonly Type elementType;
1735                 private int token;
1736                 private readonly Type[] requiredCustomModifiers;
1737                 private readonly Type[] optionalCustomModifiers;
1738
1739                 protected ElementHolderType(Type elementType, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1740                 {
1741                         this.elementType = elementType;
1742                         this.requiredCustomModifiers = requiredCustomModifiers;
1743                         this.optionalCustomModifiers = optionalCustomModifiers;
1744                 }
1745
1746                 protected bool EqualsHelper(ElementHolderType other)
1747                 {
1748                         return other != null
1749                                 && other.elementType.Equals(elementType)
1750                                 && Util.ArrayEquals(other.requiredCustomModifiers, requiredCustomModifiers)
1751                                 && Util.ArrayEquals(other.optionalCustomModifiers, optionalCustomModifiers);
1752                 }
1753
1754                 public override Type[] __GetRequiredCustomModifiers()
1755                 {
1756                         return Util.Copy(requiredCustomModifiers);
1757                 }
1758
1759                 public override Type[] __GetOptionalCustomModifiers()
1760                 {
1761                         return Util.Copy(optionalCustomModifiers);
1762                 }
1763
1764                 public sealed override string Name
1765                 {
1766                         get { return elementType.Name + GetSuffix(); }
1767                 }
1768
1769                 public sealed override string Namespace
1770                 {
1771                         get { return elementType.Namespace; }
1772                 }
1773
1774                 public sealed override string FullName
1775                 {
1776                         get { return elementType.FullName + GetSuffix(); }
1777                 }
1778
1779                 public sealed override string ToString()
1780                 {
1781                         return elementType.ToString() + GetSuffix();
1782                 }
1783
1784                 public sealed override Type GetElementType()
1785                 {
1786                         return elementType;
1787                 }
1788
1789                 public sealed override bool HasElementType
1790                 {
1791                         get { return true; }
1792                 }
1793
1794                 public sealed override Module Module
1795                 {
1796                         get { return elementType.Module; }
1797                 }
1798
1799                 internal sealed override int GetModuleBuilderToken()
1800                 {
1801                         if (token == 0)
1802                         {
1803                                 token = ((ModuleBuilder)elementType.Module).ImportType(this);
1804                         }
1805                         return token;
1806                 }
1807
1808                 public sealed override bool ContainsGenericParameters
1809                 {
1810                         get
1811                         {
1812                                 Type type = elementType;
1813                                 while (type.HasElementType)
1814                                 {
1815                                         type = type.GetElementType();
1816                                 }
1817                                 return type.ContainsGenericParameters;
1818                         }
1819                 }
1820
1821                 public sealed override bool __ContainsMissingType
1822                 {
1823                         get
1824                         {
1825                                 Type type = elementType;
1826                                 while (type.HasElementType)
1827                                 {
1828                                         type = type.GetElementType();
1829                                 }
1830                                 return type.__ContainsMissingType;
1831                         }
1832                 }
1833
1834                 internal sealed override Type BindTypeParameters(IGenericBinder binder)
1835                 {
1836                         Type type = elementType.BindTypeParameters(binder);
1837                         Type[] req = BindArray(requiredCustomModifiers, binder);
1838                         Type[] opt = BindArray(optionalCustomModifiers, binder);
1839                         if (ReferenceEquals(type, elementType)
1840                                 && ReferenceEquals(req, requiredCustomModifiers)
1841                                 && ReferenceEquals(opt, optionalCustomModifiers))
1842                         {
1843                                 return this;
1844                         }
1845                         return Wrap(type, req, opt);
1846                 }
1847
1848                 internal override void CheckBaked()
1849                 {
1850                         elementType.CheckBaked();
1851                 }
1852
1853                 private static Type[] BindArray(Type[] array, IGenericBinder binder)
1854                 {
1855                         if (array ==null || array.Length == 0)
1856                         {
1857                                 return array;
1858                         }
1859                         Type[] result = array;
1860                         for (int i = 0; i < array.Length; i++)
1861                         {
1862                                 Type type = array[i].BindTypeParameters(binder);
1863                                 if (!ReferenceEquals(type, array[i]))
1864                                 {
1865                                         if (result == array)
1866                                         {
1867                                                 result = (Type[])array.Clone();
1868                                         }
1869                                         result[i] = type;
1870                                 }
1871                         }
1872                         return result;
1873                 }
1874
1875                 internal sealed override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
1876                 {
1877                         return CustomAttributeData.EmptyList;
1878                 }
1879
1880                 internal abstract string GetSuffix();
1881
1882                 protected abstract Type Wrap(Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers);
1883         }
1884
1885         sealed class ArrayType : ElementHolderType
1886         {
1887                 internal static Type Make(Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1888                 {
1889                         return type.Module.CanonicalizeType(new ArrayType(type, requiredCustomModifiers, optionalCustomModifiers));
1890                 }
1891
1892                 private ArrayType(Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1893                         : base(type, requiredCustomModifiers, optionalCustomModifiers)
1894                 {
1895                 }
1896
1897                 public override Type BaseType
1898                 {
1899                         get { return elementType.Module.universe.System_Array; }
1900                 }
1901
1902                 public override Type[] __GetDeclaredInterfaces()
1903                 {
1904                         return new Type[] {
1905                                 this.Module.universe.Import(typeof(IList<>)).MakeGenericType(elementType),
1906                                 this.Module.universe.Import(typeof(ICollection<>)).MakeGenericType(elementType),
1907                                 this.Module.universe.Import(typeof(IEnumerable<>)).MakeGenericType(elementType)
1908                         };
1909                 }
1910
1911                 public override MethodBase[] __GetDeclaredMethods()
1912                 {
1913                         Type[] int32 = new Type[] { this.Module.universe.System_Int32 };
1914                         List<MethodBase> list = new List<MethodBase>();
1915                         list.Add(new BuiltinArrayMethod(this.Module, this, "Set", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, new Type[] { this.Module.universe.System_Int32, elementType }));
1916                         list.Add(new BuiltinArrayMethod(this.Module, this, "Address", CallingConventions.Standard | CallingConventions.HasThis, elementType.MakeByRefType(), int32));
1917                         list.Add(new BuiltinArrayMethod(this.Module, this, "Get", CallingConventions.Standard | CallingConventions.HasThis, elementType, int32));
1918                         list.Add(new ConstructorInfoImpl(new BuiltinArrayMethod(this.Module, this, ".ctor", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, int32)));
1919                         for (Type type = elementType; type.__IsVector; type = type.GetElementType())
1920                         {
1921                                 Array.Resize(ref int32, int32.Length + 1);
1922                                 int32[int32.Length - 1] = int32[0];
1923                                 list.Add(new ConstructorInfoImpl(new BuiltinArrayMethod(this.Module, this, ".ctor", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, int32)));
1924                         }
1925                         return list.ToArray();
1926                 }
1927
1928                 public override TypeAttributes Attributes
1929                 {
1930                         get { return TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Serializable; }
1931                 }
1932
1933                 public override bool IsArray
1934                 {
1935                         get { return true; }
1936                 }
1937
1938                 public override bool __IsVector
1939                 {
1940                         get { return true; }
1941                 }
1942
1943                 public override int GetArrayRank()
1944                 {
1945                         return 1;
1946                 }
1947
1948                 public override bool Equals(object o)
1949                 {
1950                         return EqualsHelper(o as ArrayType);
1951                 }
1952
1953                 public override int GetHashCode()
1954                 {
1955                         return elementType.GetHashCode() * 5;
1956                 }
1957
1958                 internal override string GetSuffix()
1959                 {
1960                         return "[]";
1961                 }
1962
1963                 protected override Type Wrap(Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1964                 {
1965                         return Make(type, requiredCustomModifiers, optionalCustomModifiers);
1966                 }
1967         }
1968
1969         sealed class MultiArrayType : ElementHolderType
1970         {
1971                 private readonly int rank;
1972                 private readonly int[] sizes;
1973                 private readonly int[] lobounds;
1974
1975                 internal static Type Make(Type type, int rank, int[] sizes, int[] lobounds, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1976                 {
1977                         return type.Module.CanonicalizeType(new MultiArrayType(type, rank, sizes, lobounds, requiredCustomModifiers, optionalCustomModifiers));
1978                 }
1979
1980                 private MultiArrayType(Type type, int rank, int[] sizes, int[] lobounds, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1981                         : base(type, requiredCustomModifiers, optionalCustomModifiers)
1982                 {
1983                         this.rank = rank;
1984                         this.sizes = sizes;
1985                         this.lobounds = lobounds;
1986                 }
1987
1988                 public override Type BaseType
1989                 {
1990                         get { return elementType.Module.universe.System_Array; }
1991                 }
1992
1993                 public override MethodBase[] __GetDeclaredMethods()
1994                 {
1995                         Type int32 = this.Module.universe.System_Int32;
1996                         Type[] setArgs = new Type[rank + 1];
1997                         Type[] getArgs = new Type[rank];
1998                         Type[] ctorArgs = new Type[rank * 2];
1999                         for (int i = 0; i < rank; i++)
2000                         {
2001                                 setArgs[i] = int32;
2002                                 getArgs[i] = int32;
2003                                 ctorArgs[i * 2 + 0] = int32;
2004                                 ctorArgs[i * 2 + 1] = int32;
2005                         }
2006                         setArgs[rank] = elementType;
2007                         return new MethodBase[] {
2008                                 new ConstructorInfoImpl(new BuiltinArrayMethod(this.Module, this, ".ctor", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, getArgs)),
2009                                 new ConstructorInfoImpl(new BuiltinArrayMethod(this.Module, this, ".ctor", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, ctorArgs)),
2010                                 new BuiltinArrayMethod(this.Module, this, "Set", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, setArgs),
2011                                 new BuiltinArrayMethod(this.Module, this, "Address", CallingConventions.Standard | CallingConventions.HasThis, elementType.MakeByRefType(), getArgs),
2012                                 new BuiltinArrayMethod(this.Module, this, "Get", CallingConventions.Standard | CallingConventions.HasThis, elementType, getArgs),
2013                         };
2014                 }
2015
2016                 public override TypeAttributes Attributes
2017                 {
2018                         get { return TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Serializable; }
2019                 }
2020
2021                 public override bool IsArray
2022                 {
2023                         get { return true; }
2024                 }
2025
2026                 public override int GetArrayRank()
2027                 {
2028                         return rank;
2029                 }
2030
2031                 public override int[] __GetArraySizes()
2032                 {
2033                         return Util.Copy(sizes);
2034                 }
2035
2036                 public override int[] __GetArrayLowerBounds()
2037                 {
2038                         return Util.Copy(lobounds);
2039                 }
2040
2041                 public override bool Equals(object o)
2042                 {
2043                         MultiArrayType at = o as MultiArrayType;
2044                         return EqualsHelper(at)
2045                                 && at.rank == rank
2046                                 && ArrayEquals(at.sizes, sizes)
2047                                 && ArrayEquals(at.lobounds, lobounds);
2048                 }
2049
2050                 private static bool ArrayEquals(int[] i1, int[] i2)
2051                 {
2052                         if (i1.Length == i2.Length)
2053                         {
2054                                 for (int i = 0; i < i1.Length; i++)
2055                                 {
2056                                         if (i1[i] != i2[i])
2057                                         {
2058                                                 return false;
2059                                         }
2060                                 }
2061                                 return true;
2062                         }
2063                         return false;
2064                 }
2065
2066                 public override int GetHashCode()
2067                 {
2068                         return elementType.GetHashCode() * 9 + rank;
2069                 }
2070
2071                 internal override string GetSuffix()
2072                 {
2073                         if (rank == 1)
2074                         {
2075                                 return "[*]";
2076                         }
2077                         else
2078                         {
2079                                 return "[" + new String(',', rank - 1) + "]";
2080                         }
2081                 }
2082
2083                 protected override Type Wrap(Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
2084                 {
2085                         return Make(type, rank, sizes, lobounds, requiredCustomModifiers, optionalCustomModifiers);
2086                 }
2087         }
2088
2089         sealed class BuiltinArrayMethod : ArrayMethod
2090         {
2091                 internal BuiltinArrayMethod(Module module, Type arrayClass, string methodName, CallingConventions callingConvention, Type returnType, Type[] parameterTypes)
2092                         : base(module, arrayClass, methodName, callingConvention, returnType, parameterTypes)
2093                 {
2094                 }
2095
2096                 public override MethodAttributes Attributes
2097                 {
2098                         get { return this.Name == ".ctor" ? MethodAttributes.RTSpecialName | MethodAttributes.Public : MethodAttributes.Public; }
2099                 }
2100
2101                 public override MethodImplAttributes GetMethodImplementationFlags()
2102                 {
2103                         return MethodImplAttributes.IL;
2104                 }
2105
2106                 public override int MetadataToken
2107                 {
2108                         get { return 0x06000000; }
2109                 }
2110
2111                 public override MethodBody GetMethodBody()
2112                 {
2113                         return null;
2114                 }
2115
2116                 public override ParameterInfo[] GetParameters()
2117                 {
2118                         ParameterInfo[] parameterInfos = new ParameterInfo[parameterTypes.Length];
2119                         for (int i = 0; i < parameterInfos.Length; i++)
2120                         {
2121                                 parameterInfos[i] = new ParameterInfoImpl(this, parameterTypes[i], i);
2122                         }
2123                         return parameterInfos;
2124                 }
2125
2126                 public override ParameterInfo ReturnParameter
2127                 {
2128                         get { return new ParameterInfoImpl(this, this.ReturnType, -1); }
2129                 }
2130
2131                 private sealed class ParameterInfoImpl : ParameterInfo
2132                 {
2133                         private readonly MethodInfo method;
2134                         private readonly Type type;
2135                         private readonly int pos;
2136
2137                         internal ParameterInfoImpl(MethodInfo method, Type type, int pos)
2138                         {
2139                                 this.method = method;
2140                                 this.type = type;
2141                                 this.pos = pos;
2142                         }
2143
2144                         public override Type ParameterType
2145                         {
2146                                 get { return type; }
2147                         }
2148
2149                         public override string Name
2150                         {
2151                                 get { return null; }
2152                         }
2153
2154                         public override ParameterAttributes Attributes
2155                         {
2156                                 get { return ParameterAttributes.None; }
2157                         }
2158
2159                         public override int Position
2160                         {
2161                                 get { return pos; }
2162                         }
2163
2164                         public override object RawDefaultValue
2165                         {
2166                                 get { return null; }
2167                         }
2168
2169                         public override Type[] GetOptionalCustomModifiers()
2170                         {
2171                                 return Empty<Type>.Array;
2172                         }
2173
2174                         public override Type[] GetRequiredCustomModifiers()
2175                         {
2176                                 return Empty<Type>.Array;
2177                         }
2178
2179                         public override MemberInfo Member
2180                         {
2181                                 get { return method.IsConstructor ? (MethodBase)new ConstructorInfoImpl(method) : method; }
2182                         }
2183
2184                         public override int MetadataToken
2185                         {
2186                                 get { return 0x8000000; }
2187                         }
2188
2189                         internal override Module Module
2190                         {
2191                                 get { return method.Module; }
2192                         }
2193                 }
2194         }
2195
2196         sealed class ByRefType : ElementHolderType
2197         {
2198                 internal static Type Make(Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
2199                 {
2200                         return type.Module.CanonicalizeType(new ByRefType(type, requiredCustomModifiers, optionalCustomModifiers));
2201                 }
2202
2203                 private ByRefType(Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
2204                         : base(type, requiredCustomModifiers, optionalCustomModifiers)
2205                 {
2206                 }
2207
2208                 public override bool Equals(object o)
2209                 {
2210                         return EqualsHelper(o as ByRefType);
2211                 }
2212
2213                 public override int GetHashCode()
2214                 {
2215                         return elementType.GetHashCode() * 3;
2216                 }
2217
2218                 public override Type BaseType
2219                 {
2220                         get { return null; }
2221                 }
2222
2223                 public override TypeAttributes Attributes
2224                 {
2225                         get { return 0; }
2226                 }
2227
2228                 public override bool IsByRef
2229                 {
2230                         get { return true; }
2231                 }
2232
2233                 internal override string GetSuffix()
2234                 {
2235                         return "&";
2236                 }
2237
2238                 protected override Type Wrap(Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
2239                 {
2240                         return Make(type, requiredCustomModifiers, optionalCustomModifiers);
2241                 }
2242         }
2243
2244         sealed class PointerType : ElementHolderType
2245         {
2246                 internal static Type Make(Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
2247                 {
2248                         return type.Module.CanonicalizeType(new PointerType(type, requiredCustomModifiers, optionalCustomModifiers));
2249                 }
2250
2251                 private PointerType(Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
2252                         : base(type, requiredCustomModifiers, optionalCustomModifiers)
2253                 {
2254                 }
2255
2256                 public override bool Equals(object o)
2257                 {
2258                         return EqualsHelper(o as PointerType);
2259                 }
2260
2261                 public override int GetHashCode()
2262                 {
2263                         return elementType.GetHashCode() * 7;
2264                 }
2265
2266                 public override Type BaseType
2267                 {
2268                         get { return null; }
2269                 }
2270
2271                 public override TypeAttributes Attributes
2272                 {
2273                         get { return 0; }
2274                 }
2275
2276                 public override bool IsPointer
2277                 {
2278                         get { return true; }
2279                 }
2280
2281                 internal override string GetSuffix()
2282                 {
2283                         return "*";
2284                 }
2285
2286                 protected override Type Wrap(Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
2287                 {
2288                         return Make(type, requiredCustomModifiers, optionalCustomModifiers);
2289                 }
2290         }
2291
2292         sealed class GenericTypeInstance : Type
2293         {
2294                 private readonly Type type;
2295                 private readonly Type[] args;
2296                 private readonly Type[][] requiredCustomModifiers;
2297                 private readonly Type[][] optionalCustomModifiers;
2298                 private Type baseType;
2299                 private int token;
2300
2301                 internal static Type Make(Type type, Type[] typeArguments, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
2302                 {
2303                         bool identity = true;
2304                         if (type is TypeBuilder || type is BakedType || type.__IsMissing)
2305                         {
2306                                 // a TypeBuiler identity must be instantiated
2307                                 identity = false;
2308                         }
2309                         else
2310                         {
2311                                 // we must not instantiate the identity instance, because typeof(Foo<>).MakeGenericType(typeof(Foo<>).GetGenericArguments()) == typeof(Foo<>)
2312                                 for (int i = 0; i < typeArguments.Length; i++)
2313                                 {
2314                                         if (typeArguments[i] != type.GetGenericTypeArgument(i)
2315                                                 || !IsEmpty(requiredCustomModifiers, i)
2316                                                 || !IsEmpty(optionalCustomModifiers, i))
2317                                         {
2318                                                 identity = false;
2319                                                 break;
2320                                         }
2321                                 }
2322                         }
2323                         if (identity)
2324                         {
2325                                 return type;
2326                         }
2327                         else
2328                         {
2329                                 return type.Module.CanonicalizeType(new GenericTypeInstance(type, typeArguments, requiredCustomModifiers, optionalCustomModifiers));
2330                         }
2331                 }
2332
2333                 private static bool IsEmpty(Type[][] mods, int i)
2334                 {
2335                         // we need to be extra careful, because mods doesn't not need to be in canonical format
2336                         // (Signature.ReadGenericInst() calls Make() directly, without copying the modifier arrays)
2337                         return mods == null || mods[i] == null || mods[i].Length == 0;
2338                 }
2339
2340                 private GenericTypeInstance(Type type, Type[] args, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
2341                 {
2342                         this.type = type;
2343                         this.args = args;
2344                         this.requiredCustomModifiers = requiredCustomModifiers;
2345                         this.optionalCustomModifiers = optionalCustomModifiers;
2346                 }
2347
2348                 public override bool Equals(object o)
2349                 {
2350                         GenericTypeInstance gt = o as GenericTypeInstance;
2351                         return gt != null && gt.type.Equals(type) && Util.ArrayEquals(gt.args, args)
2352                                 && Util.ArrayEquals(gt.requiredCustomModifiers, requiredCustomModifiers)
2353                                 && Util.ArrayEquals(gt.optionalCustomModifiers, optionalCustomModifiers);
2354                 }
2355
2356                 public override int GetHashCode()
2357                 {
2358                         return type.GetHashCode() * 3 ^ Util.GetHashCode(args);
2359                 }
2360
2361                 public override string AssemblyQualifiedName
2362                 {
2363                         get
2364                         {
2365                                 string fn = FullName;
2366                                 return fn == null ? null : fn + ", " + type.Assembly.FullName;
2367                         }
2368                 }
2369
2370                 public override Type BaseType
2371                 {
2372                         get
2373                         {
2374                                 if (baseType == null)
2375                                 {
2376                                         Type rawBaseType = type.BaseType;
2377                                         if (rawBaseType == null)
2378                                         {
2379                                                 baseType = rawBaseType;
2380                                         }
2381                                         else
2382                                         {
2383                                                 baseType = rawBaseType.BindTypeParameters(this);
2384                                         }
2385                                 }
2386                                 return baseType;
2387                         }
2388                 }
2389
2390                 public override bool IsValueType
2391                 {
2392                         get { return type.IsValueType; }
2393                 }
2394
2395                 public override bool IsVisible
2396                 {
2397                         get
2398                         {
2399                                 if (base.IsVisible)
2400                                 {
2401                                         foreach (Type arg in args)
2402                                         {
2403                                                 if (!arg.IsVisible)
2404                                                 {
2405                                                         return false;
2406                                                 }
2407                                         }
2408                                         return true;
2409                                 }
2410                                 return false;
2411                         }
2412                 }
2413
2414                 public override Type DeclaringType
2415                 {
2416                         get { return type.DeclaringType; }
2417                 }
2418
2419                 public override TypeAttributes Attributes
2420                 {
2421                         get { return type.Attributes; }
2422                 }
2423
2424                 internal override void CheckBaked()
2425                 {
2426                         type.CheckBaked();
2427                 }
2428
2429                 public override FieldInfo[] __GetDeclaredFields()
2430                 {
2431                         FieldInfo[] fields = type.__GetDeclaredFields();
2432                         for (int i = 0; i < fields.Length; i++)
2433                         {
2434                                 fields[i] = fields[i].BindTypeParameters(this);
2435                         }
2436                         return fields;
2437                 }
2438
2439                 public override Type[] __GetDeclaredInterfaces()
2440                 {
2441                         Type[] interfaces = type.__GetDeclaredInterfaces();
2442                         for (int i = 0; i < interfaces.Length; i++)
2443                         {
2444                                 interfaces[i] = interfaces[i].BindTypeParameters(this);
2445                         }
2446                         return interfaces;
2447                 }
2448
2449                 public override MethodBase[] __GetDeclaredMethods()
2450                 {
2451                         MethodBase[] methods = type.__GetDeclaredMethods();
2452                         for (int i = 0; i < methods.Length; i++)
2453                         {
2454                                 methods[i] = methods[i].BindTypeParameters(this);
2455                         }
2456                         return methods;
2457                 }
2458
2459                 public override Type[] __GetDeclaredTypes()
2460                 {
2461                         return type.__GetDeclaredTypes();
2462                 }
2463
2464                 public override EventInfo[] __GetDeclaredEvents()
2465                 {
2466                         EventInfo[] events = type.__GetDeclaredEvents();
2467                         for (int i = 0; i < events.Length; i++)
2468                         {
2469                                 events[i] = events[i].BindTypeParameters(this);
2470                         }
2471                         return events;
2472                 }
2473
2474                 public override PropertyInfo[] __GetDeclaredProperties()
2475                 {
2476                         PropertyInfo[] properties = type.__GetDeclaredProperties();
2477                         for (int i = 0; i < properties.Length; i++)
2478                         {
2479                                 properties[i] = properties[i].BindTypeParameters(this);
2480                         }
2481                         return properties;
2482                 }
2483
2484                 public override __MethodImplMap __GetMethodImplMap()
2485                 {
2486                         __MethodImplMap map = type.__GetMethodImplMap();
2487                         map.TargetType = this;
2488                         for (int i = 0; i < map.MethodBodies.Length; i++)
2489                         {
2490                                 map.MethodBodies[i] = (MethodInfo)map.MethodBodies[i].BindTypeParameters(this);
2491                                 for (int j = 0; j < map.MethodDeclarations[i].Length; j++)
2492                                 {
2493                                         Type interfaceType = map.MethodDeclarations[i][j].DeclaringType;
2494                                         if (interfaceType.IsGenericType)
2495                                         {
2496                                                 map.MethodDeclarations[i][j] = (MethodInfo)map.MethodDeclarations[i][j].BindTypeParameters(this);
2497                                         }
2498                                 }
2499                         }
2500                         return map;
2501                 }
2502
2503                 public override string Namespace
2504                 {
2505                         get { return type.Namespace; }
2506                 }
2507
2508                 public override string Name
2509                 {
2510                         get { return type.Name; }
2511                 }
2512
2513                 public override string FullName
2514                 {
2515                         get
2516                         {
2517                                 if (!this.__ContainsMissingType && this.ContainsGenericParameters)
2518                                 {
2519                                         return null;
2520                                 }
2521                                 StringBuilder sb = new StringBuilder(this.type.FullName);
2522                                 sb.Append('[');
2523                                 string sep = "";
2524                                 foreach (Type type in args)
2525                                 {
2526                                         sb.Append(sep).Append('[').Append(type.FullName).Append(", ").Append(type.Assembly.FullName.Replace("]", "\\]")).Append(']');
2527                                         sep = ",";
2528                                 }
2529                                 sb.Append(']');
2530                                 return sb.ToString();
2531                         }
2532                 }
2533
2534                 public override string ToString()
2535                 {
2536                         StringBuilder sb = new StringBuilder(type.FullName);
2537                         sb.Append('[');
2538                         string sep = "";
2539                         foreach (Type arg in args)
2540                         {
2541                                 sb.Append(sep);
2542                                 sb.Append(arg);
2543                                 sep = ",";
2544                         }
2545                         sb.Append(']');
2546                         return sb.ToString();
2547                 }
2548
2549                 public override Module Module
2550                 {
2551                         get { return type.Module; }
2552                 }
2553
2554                 public override bool IsGenericType
2555                 {
2556                         get { return true; }
2557                 }
2558
2559                 internal override bool IsGenericTypeInstance
2560                 {
2561                         get { return true; }
2562                 }
2563
2564                 public override Type GetGenericTypeDefinition()
2565                 {
2566                         return type;
2567                 }
2568
2569                 public override Type[] GetGenericArguments()
2570                 {
2571                         return Util.Copy(args);
2572                 }
2573
2574                 public override Type[][] __GetGenericArgumentsRequiredCustomModifiers()
2575                 {
2576                         return Util.Copy(requiredCustomModifiers ?? new Type[args.Length][]);
2577                 }
2578
2579                 public override Type[][] __GetGenericArgumentsOptionalCustomModifiers()
2580                 {
2581                         return Util.Copy(optionalCustomModifiers ?? new Type[args.Length][]);
2582                 }
2583
2584                 internal override Type GetGenericTypeArgument(int index)
2585                 {
2586                         return args[index];
2587                 }
2588
2589                 public override bool ContainsGenericParameters
2590                 {
2591                         get
2592                         {
2593                                 foreach (Type type in args)
2594                                 {
2595                                         if (type.ContainsGenericParameters)
2596                                         {
2597                                                 return true;
2598                                         }
2599                                 }
2600                                 return false;
2601                         }
2602                 }
2603
2604                 public override bool __ContainsMissingType
2605                 {
2606                         get
2607                         {
2608                                 foreach (Type type in args)
2609                                 {
2610                                         if (type.__ContainsMissingType)
2611                                         {
2612                                                 return true;
2613                                         }
2614                                 }
2615                                 return this.type.__IsMissing;
2616                         }
2617                 }
2618
2619                 public override StructLayoutAttribute StructLayoutAttribute
2620                 {
2621                         get { return type.StructLayoutAttribute; }
2622                 }
2623
2624                 internal override int GetModuleBuilderToken()
2625                 {
2626                         if (token == 0)
2627                         {
2628                                 token = ((ModuleBuilder)type.Module).ImportType(this);
2629                         }
2630                         return token;
2631                 }
2632
2633                 internal override Type BindTypeParameters(IGenericBinder binder)
2634                 {
2635                         for (int i = 0; i < args.Length; i++)
2636                         {
2637                                 Type xarg = args[i].BindTypeParameters(binder);
2638                                 if (!ReferenceEquals(xarg, args[i]))
2639                                 {
2640                                         Type[] xargs = new Type[args.Length];
2641                                         Array.Copy(args, xargs, i);
2642                                         xargs[i++] = xarg;
2643                                         for (; i < args.Length; i++)
2644                                         {
2645                                                 xargs[i] = args[i].BindTypeParameters(binder);
2646                                         }
2647                                         return Make(type, xargs, null, null);
2648                                 }
2649                         }
2650                         return this;
2651                 }
2652
2653                 internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
2654                 {
2655                         return type.GetCustomAttributesData(attributeType);
2656                 }
2657         }
2658 }