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