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