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