Merge branch 'bugfix-main-thread-root'
[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                 internal Type ResolveNestedType(TypeName typeName)
751                 {
752                         return FindNestedType(typeName) ?? Module.universe.GetMissingTypeOrThrow(Module, this, typeName);
753                 }
754
755                 // unlike the public API, this takes the namespace and name into account
756                 internal virtual Type FindNestedType(TypeName name)
757                 {
758                         foreach (Type type in __GetDeclaredTypes())
759                         {
760                                 if (type.__Namespace == name.Namespace && type.__Name == name.Name)
761                                 {
762                                         return type;
763                                 }
764                         }
765                         return null;
766                 }
767
768                 public Type GetNestedType(string name)
769                 {
770                         return GetNestedType(name, BindingFlags.Public);
771                 }
772
773                 public Type GetNestedType(string name, BindingFlags bindingAttr)
774                 {
775                         foreach (Type type in GetNestedTypes(bindingAttr))
776                         {
777                                 // FXBUG the namespace is ignored
778                                 if (type.__Name == name)
779                                 {
780                                         return type;
781                                 }
782                         }
783                         return null;
784                 }
785
786                 public Type[] GetNestedTypes()
787                 {
788                         return GetNestedTypes(BindingFlags.Public);
789                 }
790
791                 public Type[] GetNestedTypes(BindingFlags bindingAttr)
792                 {
793                         CheckBaked();
794                         List<Type> list = new List<Type>();
795                         foreach (Type type in __GetDeclaredTypes())
796                         {
797                                 if (BindingFlagsMatch(type.IsNestedPublic, bindingAttr, BindingFlags.Public, BindingFlags.NonPublic))
798                                 {
799                                         list.Add(type);
800                                 }
801                         }
802                         return list.ToArray();
803                 }
804
805                 public PropertyInfo[] GetProperties()
806                 {
807                         return GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
808                 }
809
810                 public PropertyInfo[] GetProperties(BindingFlags bindingAttr)
811                 {
812                         List<PropertyInfo> list = new List<PropertyInfo>();
813                         Type type = this;
814                         while (type != null)
815                         {
816                                 type.CheckBaked();
817                                 foreach (PropertyInfo property in type.__GetDeclaredProperties())
818                                 {
819                                         if (BindingFlagsMatch(property.IsPublic, bindingAttr, BindingFlags.Public, BindingFlags.NonPublic)
820                                                 && BindingFlagsMatch(property.IsStatic, bindingAttr, BindingFlags.Static, BindingFlags.Instance))
821                                         {
822                                                 list.Add(property);
823                                         }
824                                 }
825                                 if ((bindingAttr & BindingFlags.DeclaredOnly) == 0)
826                                 {
827                                         if ((bindingAttr & BindingFlags.FlattenHierarchy) == 0)
828                                         {
829                                                 bindingAttr &= ~BindingFlags.Static;
830                                         }
831                                         type = type.BaseType;
832                                 }
833                                 else
834                                 {
835                                         break;
836                                 }
837                         }
838                         return list.ToArray();
839                 }
840
841                 public PropertyInfo GetProperty(string name)
842                 {
843                         return GetProperty(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
844                 }
845
846                 public PropertyInfo GetProperty(string name, BindingFlags bindingAttr)
847                 {
848                         foreach (PropertyInfo prop in GetProperties(bindingAttr))
849                         {
850                                 if (prop.Name == name)
851                                 {
852                                         return prop;
853                                 }
854                         }
855                         return null;
856                 }
857
858                 public PropertyInfo GetProperty(string name, Type returnType)
859                 {
860                         PropertyInfo found = null;
861                         foreach (PropertyInfo prop in GetProperties())
862                         {
863                                 if (prop.Name == name && prop.PropertyType.Equals(returnType))
864                                 {
865                                         if (found != null)
866                                         {
867                                                 throw new AmbiguousMatchException();
868                                         }
869                                         found = prop;
870                                 }
871                         }
872                         return found;
873                 }
874
875                 public PropertyInfo GetProperty(string name, Type[] types)
876                 {
877                         PropertyInfo found = null;
878                         foreach (PropertyInfo prop in GetProperties())
879                         {
880                                 if (prop.Name == name && MatchParameterTypes(prop.GetIndexParameters(), types))
881                                 {
882                                         if (found != null)
883                                         {
884                                                 throw new AmbiguousMatchException();
885                                         }
886                                         found = prop;
887                                 }
888                         }
889                         return found;
890                 }
891
892                 private static bool MatchParameterTypes(ParameterInfo[] parameters, Type[] types)
893                 {
894                         if (parameters.Length == types.Length)
895                         {
896                                 for (int i = 0; i < parameters.Length; i++)
897                                 {
898                                         if (!parameters[i].ParameterType.Equals(types[i]))
899                                         {
900                                                 return false;
901                                         }
902                                 }
903                                 return true;
904                         }
905                         return false;
906                 }
907
908                 public PropertyInfo GetProperty(string name, Type returnType, Type[] types)
909                 {
910                         return GetProperty(name, returnType, types, null);
911                 }
912
913                 public PropertyInfo GetProperty(string name, Type returnType, Type[] types, ParameterModifier[] modifiers)
914                 {
915                         return GetProperty(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static, null, returnType, types, modifiers);
916                 }
917
918                 public PropertyInfo GetProperty(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
919                 {
920                         PropertyInfo found = null;
921                         foreach (PropertyInfo prop in GetProperties(bindingAttr))
922                         {
923                                 if (prop.Name == name && prop.PropertyType.Equals(returnType) && MatchParameterTypes(prop.GetIndexParameters(), types))
924                                 {
925                                         if (found != null)
926                                         {
927                                                 throw new AmbiguousMatchException();
928                                         }
929                                         found = prop;
930                                 }
931                         }
932                         return found;
933                 }
934
935                 public Type GetInterface(string name)
936                 {
937                         return GetInterface(name, false);
938                 }
939
940                 public Type GetInterface(string name, bool ignoreCase)
941                 {
942                         if (ignoreCase)
943                         {
944                                 throw new NotImplementedException();
945                         }
946                         foreach (Type type in GetInterfaces())
947                         {
948                                 if (type.FullName == name)
949                                 {
950                                         return type;
951                                 }
952                         }
953                         return null;
954                 }
955
956                 public Type[] FindInterfaces(TypeFilter filter, object filterCriteria)
957                 {
958                         List<Type> list = new List<Type>();
959                         foreach (Type type in GetInterfaces())
960                         {
961                                 if (filter(type, filterCriteria))
962                                 {
963                                         list.Add(type);
964                                 }
965                         }
966                         return list.ToArray();
967                 }
968
969                 public ConstructorInfo TypeInitializer
970                 {
971                         get { return GetConstructor(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); }
972                 }
973
974                 public bool IsPrimitive
975                 {
976                         get
977                         {
978                                 Universe u = this.Module.universe;
979                                 return this == u.System_Boolean
980                                         || this == u.System_Byte
981                                         || this == u.System_SByte
982                                         || this == u.System_Int16
983                                         || this == u.System_UInt16
984                                         || this == u.System_Int32
985                                         || this == u.System_UInt32
986                                         || this == u.System_Int64
987                                         || this == u.System_UInt64
988                                         || this == u.System_IntPtr
989                                         || this == u.System_UIntPtr
990                                         || this == u.System_Char
991                                         || this == u.System_Double
992                                         || this == u.System_Single
993                                         ;
994                         }
995                 }
996
997                 public bool IsEnum
998                 {
999                         get { return this.BaseType == this.Module.universe.System_Enum; }
1000                 }
1001
1002                 public bool IsSealed
1003                 {
1004                         get { return (Attributes & TypeAttributes.Sealed) != 0; }
1005                 }
1006
1007                 public bool IsAbstract
1008                 {
1009                         get { return (Attributes & TypeAttributes.Abstract) != 0; }
1010                 }
1011
1012                 private bool CheckVisibility(TypeAttributes access)
1013                 {
1014                         return (Attributes & TypeAttributes.VisibilityMask) == access;
1015                 }
1016
1017                 public bool IsPublic
1018                 {
1019                         get { return CheckVisibility(TypeAttributes.Public); }
1020                 }
1021
1022                 public bool IsNestedPublic
1023                 {
1024                         get { return CheckVisibility(TypeAttributes.NestedPublic); }
1025                 }
1026
1027                 public bool IsNestedPrivate
1028                 {
1029                         get { return CheckVisibility(TypeAttributes.NestedPrivate); }
1030                 }
1031
1032                 public bool IsNestedFamily
1033                 {
1034                         get { return CheckVisibility(TypeAttributes.NestedFamily); }
1035                 }
1036
1037                 public bool IsNestedAssembly
1038                 {
1039                         get { return CheckVisibility(TypeAttributes.NestedAssembly); }
1040                 }
1041
1042                 public bool IsNestedFamANDAssem
1043                 {
1044                         get { return CheckVisibility(TypeAttributes.NestedFamANDAssem); }
1045                 }
1046
1047                 public bool IsNestedFamORAssem
1048                 {
1049                         get { return CheckVisibility(TypeAttributes.NestedFamORAssem); }
1050                 }
1051
1052                 public bool IsNotPublic
1053                 {
1054                         get { return CheckVisibility(TypeAttributes.NotPublic); }
1055                 }
1056
1057                 public bool IsImport
1058                 {
1059                         get { return (Attributes & TypeAttributes.Import) != 0; }
1060                 }
1061
1062                 public bool IsCOMObject
1063                 {
1064                         get { return IsClass && IsImport; }
1065                 }
1066
1067                 public bool IsContextful
1068                 {
1069                         get { return IsSubclassOf(this.Module.universe.Import(typeof(ContextBoundObject))); }
1070                 }
1071
1072                 public bool IsMarshalByRef
1073                 {
1074                         get { return IsSubclassOf(this.Module.universe.Import(typeof(MarshalByRefObject))); }
1075                 }
1076
1077                 public virtual bool IsVisible
1078                 {
1079                         get { return IsPublic || (IsNestedPublic && this.DeclaringType.IsVisible); }
1080                 }
1081
1082                 public bool IsAnsiClass
1083                 {
1084                         get { return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AnsiClass; }
1085                 }
1086
1087                 public bool IsUnicodeClass
1088                 {
1089                         get { return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass; }
1090                 }
1091
1092                 public bool IsAutoClass
1093                 {
1094                         get { return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass; }
1095                 }
1096
1097                 public bool IsAutoLayout
1098                 {
1099                         get { return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout; }
1100                 }
1101
1102                 public bool IsLayoutSequential
1103                 {
1104                         get { return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout; }
1105                 }
1106
1107                 public bool IsExplicitLayout
1108                 {
1109                         get { return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout; }
1110                 }
1111
1112                 public bool IsSpecialName
1113                 {
1114                         get { return (Attributes & TypeAttributes.SpecialName) != 0; }
1115                 }
1116
1117                 public bool IsSerializable
1118                 {
1119                         get { return (Attributes & TypeAttributes.Serializable) != 0; }
1120                 }
1121
1122                 public bool IsClass
1123                 {
1124                         get { return !IsInterface && !IsValueType; }
1125                 }
1126
1127                 public bool IsInterface
1128                 {
1129                         get { return (Attributes & TypeAttributes.Interface) != 0; }
1130                 }
1131
1132                 public bool IsNested
1133                 {
1134                         // FXBUG we check the declaring type (like .NET) and this results
1135                         // in IsNested returning true for a generic type parameter
1136                         get { return this.DeclaringType != null; }
1137                 }
1138
1139                 public virtual bool __ContainsMissingType
1140                 {
1141                         get
1142                         {
1143                                 if (this.__IsMissing)
1144                                 {
1145                                         return true;
1146                                 }
1147                                 foreach (Type arg in this.GetGenericArguments())
1148                                 {
1149                                         if (arg.__ContainsMissingType)
1150                                         {
1151                                                 return true;
1152                                         }
1153                                 }
1154                                 return false;
1155                         }
1156                 }
1157
1158                 public Type MakeArrayType()
1159                 {
1160                         return ArrayType.Make(this, null, null);
1161                 }
1162
1163                 public Type __MakeArrayType(Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1164                 {
1165                         return ArrayType.Make(this, Util.Copy(requiredCustomModifiers), Util.Copy(optionalCustomModifiers));
1166                 }
1167
1168                 public Type MakeArrayType(int rank)
1169                 {
1170                         return MultiArrayType.Make(this, rank, null, null);
1171                 }
1172
1173                 public Type __MakeArrayType(int rank, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1174                 {
1175                         return MultiArrayType.Make(this, rank, Util.Copy(requiredCustomModifiers), Util.Copy(optionalCustomModifiers));
1176                 }
1177
1178                 public Type MakeByRefType()
1179                 {
1180                         return ByRefType.Make(this, null, null);
1181                 }
1182
1183                 public Type __MakeByRefType(Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1184                 {
1185                         return ByRefType.Make(this, Util.Copy(requiredCustomModifiers), Util.Copy(optionalCustomModifiers));
1186                 }
1187
1188                 public Type MakePointerType()
1189                 {
1190                         return PointerType.Make(this, null, null);
1191                 }
1192
1193                 public Type __MakePointerType(Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1194                 {
1195                         return PointerType.Make(this, Util.Copy(requiredCustomModifiers), Util.Copy(optionalCustomModifiers));
1196                 }
1197
1198                 public Type MakeGenericType(params Type[] typeArguments)
1199                 {
1200                         return __MakeGenericType(typeArguments, null, null);
1201                 }
1202
1203                 public Type __MakeGenericType(Type[] typeArguments, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
1204                 {
1205                         if (!this.IsGenericTypeDefinition)
1206                         {
1207                                 throw new InvalidOperationException();
1208                         }
1209                         return GenericTypeInstance.Make(this, Util.Copy(typeArguments), Util.Copy(requiredCustomModifiers), Util.Copy(optionalCustomModifiers));
1210                 }
1211
1212                 public static System.Type __GetSystemType(TypeCode typeCode)
1213                 {
1214                         switch (typeCode)
1215                         {
1216                                 case TypeCode.Boolean:
1217                                         return typeof(System.Boolean);
1218                                 case TypeCode.Byte:
1219                                         return typeof(System.Byte);
1220                                 case TypeCode.Char:
1221                                         return typeof(System.Char);
1222                                 case TypeCode.DBNull:
1223                                         return typeof(System.DBNull);
1224                                 case TypeCode.DateTime:
1225                                         return typeof(System.DateTime);
1226                                 case TypeCode.Decimal:
1227                                         return typeof(System.Decimal);
1228                                 case TypeCode.Double:
1229                                         return typeof(System.Double);
1230                                 case TypeCode.Empty:
1231                                         return null;
1232                                 case TypeCode.Int16:
1233                                         return typeof(System.Int16);
1234                                 case TypeCode.Int32:
1235                                         return typeof(System.Int32);
1236                                 case TypeCode.Int64:
1237                                         return typeof(System.Int64);
1238                                 case TypeCode.Object:
1239                                         return typeof(System.Object);
1240                                 case TypeCode.SByte:
1241                                         return typeof(System.SByte);
1242                                 case TypeCode.Single:
1243                                         return typeof(System.Single);
1244                                 case TypeCode.String:
1245                                         return typeof(System.String);
1246                                 case TypeCode.UInt16:
1247                                         return typeof(System.UInt16);
1248                                 case TypeCode.UInt32:
1249                                         return typeof(System.UInt32);
1250                                 case TypeCode.UInt64:
1251                                         return typeof(System.UInt64);
1252                                 default:
1253                                         throw new ArgumentOutOfRangeException();
1254                         }
1255                 }
1256
1257                 public static TypeCode GetTypeCode(Type type)
1258                 {
1259                         if (type == null)
1260                         {
1261                                 return TypeCode.Empty;
1262                         }
1263                         if (type.IsEnum)
1264                         {
1265                                 type = type.GetEnumUnderlyingType();
1266                         }
1267                         Universe u = type.Module.universe;
1268                         if (type == u.System_Boolean)
1269                         {
1270                                 return TypeCode.Boolean;
1271                         }
1272                         else if (type == u.System_Char)
1273                         {
1274                                 return TypeCode.Char;
1275                         }
1276                         else if (type == u.System_SByte)
1277                         {
1278                                 return TypeCode.SByte;
1279                         }
1280                         else if (type == u.System_Byte)
1281                         {
1282                                 return TypeCode.Byte;
1283                         }
1284                         else if (type == u.System_Int16)
1285                         {
1286                                 return TypeCode.Int16;
1287                         }
1288                         else if (type == u.System_UInt16)
1289                         {
1290                                 return TypeCode.UInt16;
1291                         }
1292                         else if (type == u.System_Int32)
1293                         {
1294                                 return TypeCode.Int32;
1295                         }
1296                         else if (type == u.System_UInt32)
1297                         {
1298                                 return TypeCode.UInt32;
1299                         }
1300                         else if (type == u.System_Int64)
1301                         {
1302                                 return TypeCode.Int64;
1303                         }
1304                         else if (type == u.System_UInt64)
1305                         {
1306                                 return TypeCode.UInt64;
1307                         }
1308                         else if (type == u.System_Single)
1309                         {
1310                                 return TypeCode.Single;
1311                         }
1312                         else if (type == u.System_Double)
1313                         {
1314                                 return TypeCode.Double;
1315                         }
1316                         else if (type == u.System_DateTime)
1317                         {
1318                                 return TypeCode.DateTime;
1319                         }
1320                         else if (type == u.System_DBNull)
1321                         {
1322                                 return TypeCode.DBNull;
1323                         }
1324                         else if (type == u.System_Decimal)
1325                         {
1326                                 return TypeCode.Decimal;
1327                         }
1328                         else if (type == u.System_String)
1329                         {
1330                                 return TypeCode.String;
1331                         }
1332                         else
1333                         {
1334                                 return TypeCode.Object;
1335                         }
1336                 }
1337
1338                 public Assembly Assembly
1339                 {
1340                         get { return Module.Assembly; }
1341                 }
1342
1343                 // note that interface/delegate co- and contravariance is not considered
1344                 public bool IsAssignableFrom(Type type)
1345                 {
1346                         if (this.Equals(type))
1347                         {
1348                                 return true;
1349                         }
1350                         else if (type == null)
1351                         {
1352                                 return false;
1353                         }
1354                         else if (this.IsArray && type.IsArray)
1355                         {
1356                                 if (this.GetArrayRank() != type.GetArrayRank())
1357                                 {
1358                                         return false;
1359                                 }
1360                                 else if (this.__IsVector && !type.__IsVector)
1361                                 {
1362                                         return false;
1363                                 }
1364                                 Type e1 = this.GetElementType();
1365                                 Type e2 = type.GetElementType();
1366                                 return e1.IsValueType == e2.IsValueType && e1.IsAssignableFrom(e2);
1367                         }
1368                         else if (this.IsSealed)
1369                         {
1370                                 return false;
1371                         }
1372                         else if (this.IsInterface)
1373                         {
1374                                 return Array.IndexOf(type.GetInterfaces(), this) != -1;
1375                         }
1376                         else if (type.IsInterface)
1377                         {
1378                                 return this == this.Module.universe.System_Object;
1379                         }
1380                         else if (type.IsPointer)
1381                         {
1382                                 return this == this.Module.universe.System_Object || this == this.Module.universe.System_ValueType;
1383                         }
1384                         else
1385                         {
1386                                 return type.IsSubclassOf(this);
1387                         }
1388                 }
1389
1390                 public bool IsSubclassOf(Type type)
1391                 {
1392                         Type thisType = this.BaseType;
1393                         while (thisType != null)
1394                         {
1395                                 if (thisType.Equals(type))
1396                                 {
1397                                         return true;
1398                                 }
1399                                 thisType = thisType.BaseType;
1400                         }
1401                         return false;
1402                 }
1403
1404                 // This returns true if this type directly (i.e. not inherited from the base class) implements the interface.
1405                 // Note that a complicating factor is that the interface itself can be implemented by an interface that extends it.
1406                 private bool IsDirectlyImplementedInterface(Type interfaceType)
1407                 {
1408                         foreach (Type iface in __GetDeclaredInterfaces())
1409                         {
1410                                 if (interfaceType.IsAssignableFrom(iface))
1411                                 {
1412                                         return true;
1413                                 }
1414                         }
1415                         return false;
1416                 }
1417
1418                 public InterfaceMapping GetInterfaceMap(Type interfaceType)
1419                 {
1420                         CheckBaked();
1421                         InterfaceMapping map = new InterfaceMapping();
1422                         if (!IsDirectlyImplementedInterface(interfaceType))
1423                         {
1424                                 Type baseType = this.BaseType;
1425                                 if (baseType == null)
1426                                 {
1427                                         throw new ArgumentException();
1428                                 }
1429                                 else
1430                                 {
1431                                         map = baseType.GetInterfaceMap(interfaceType);
1432                                 }
1433                         }
1434                         else
1435                         {
1436                                 map.InterfaceMethods = interfaceType.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
1437                                 map.InterfaceType = interfaceType;
1438                                 map.TargetMethods = new MethodInfo[map.InterfaceMethods.Length];
1439                                 FillInExplicitInterfaceMethods(map.InterfaceMethods, map.TargetMethods);
1440                                 MethodInfo[] methods = GetMethods(BindingFlags.Instance | BindingFlags.Public);
1441                                 for (int i = 0; i < map.TargetMethods.Length; i++)
1442                                 {
1443                                         if (map.TargetMethods[i] == null)
1444                                         {
1445                                                 // TODO use proper method resolution (also take into account that no implicit base class implementation is used across assembly boundaries)
1446                                                 for (int j = 0; j < methods.Length; j++)
1447                                                 {
1448                                                         if (methods[j].Name == map.InterfaceMethods[i].Name
1449                                                                 && methods[j].MethodSignature.Equals(map.InterfaceMethods[i].MethodSignature))
1450                                                         {
1451                                                                 map.TargetMethods[i] = methods[j];
1452                                                         }
1453                                                 }
1454                                         }
1455                                 }
1456                                 for (Type baseType = this.BaseType; baseType != null && interfaceType.IsAssignableFrom(baseType); baseType = baseType.BaseType)
1457                                 {
1458                                         baseType.FillInExplicitInterfaceMethods(map.InterfaceMethods, map.TargetMethods);
1459                                 }
1460                         }
1461                         map.TargetType = this;
1462                         return map;
1463                 }
1464
1465                 internal void FillInExplicitInterfaceMethods(MethodInfo[] interfaceMethods, MethodInfo[] targetMethods)
1466                 {
1467                         __MethodImplMap impl = __GetMethodImplMap();
1468                         for (int i = 0; i < impl.MethodDeclarations.Length; i++)
1469                         {
1470                                 for (int j = 0; j < impl.MethodDeclarations[i].Length; j++)
1471                                 {
1472                                         int index = Array.IndexOf(interfaceMethods, impl.MethodDeclarations[i][j]);
1473                                         if (index != -1 && targetMethods[index] == null)
1474                                         {
1475                                                 targetMethods[index] = impl.MethodBodies[i];
1476                                         }
1477                                 }
1478                         }
1479                 }
1480
1481                 Type IGenericContext.GetGenericTypeArgument(int index)
1482                 {
1483                         return GetGenericTypeArgument(index);
1484                 }
1485
1486                 Type IGenericContext.GetGenericMethodArgument(int index)
1487                 {
1488                         throw new BadImageFormatException();
1489                 }
1490
1491                 Type IGenericBinder.BindTypeParameter(Type type)
1492                 {
1493                         return GetGenericTypeArgument(type.GenericParameterPosition);
1494                 }
1495
1496                 Type IGenericBinder.BindMethodParameter(Type type)
1497                 {
1498                         throw new BadImageFormatException();
1499                 }
1500
1501                 internal virtual Type BindTypeParameters(IGenericBinder binder)
1502                 {
1503                         if (IsGenericTypeDefinition)
1504                         {
1505                                 Type[] args = GetGenericArguments();
1506                                 Type.InplaceBindTypeParameters(binder, args);
1507                                 return GenericTypeInstance.Make(this, args, null, null);
1508                         }
1509                         else
1510                         {
1511                                 return this;
1512                         }
1513                 }
1514
1515                 internal static void InplaceBindTypeParameters(IGenericBinder binder, Type[] types)
1516                 {
1517                         for (int i = 0; i < types.Length; i++)
1518                         {
1519                                 types[i] = types[i].BindTypeParameters(binder);
1520                         }
1521                 }
1522
1523                 internal virtual MethodBase FindMethod(string name, MethodSignature signature)
1524                 {
1525                         foreach (MethodBase method in __GetDeclaredMethods())
1526                         {
1527                                 if (method.Name == name && method.MethodSignature.Equals(signature))
1528                                 {
1529                                         return method;
1530                                 }
1531                         }
1532                         return null;
1533                 }
1534
1535                 internal FieldInfo FindField(string name, FieldSignature signature)
1536                 {
1537                         foreach (FieldInfo field in __GetDeclaredFields())
1538                         {
1539                                 if (field.Name == name && field.FieldSignature.Equals(signature))
1540                                 {
1541                                         return field;
1542                                 }
1543                         }
1544                         return null;
1545                 }
1546
1547                 internal bool IsAllowMultipleCustomAttribute
1548                 {
1549                         get
1550                         {
1551                                 IList<CustomAttributeData> cad = GetCustomAttributesData(this.Module.universe.System_AttributeUsageAttribute);
1552                                 if (cad.Count == 1)
1553                                 {
1554                                         foreach (CustomAttributeNamedArgument arg in cad[0].NamedArguments)
1555                                         {
1556                                                 if (arg.MemberInfo.Name == "AllowMultiple")
1557                                                 {
1558                                                         return (bool)arg.TypedValue.Value;
1559                                                 }
1560                                         }
1561                                 }
1562                                 return false;
1563                         }
1564                 }
1565
1566                 internal bool IsPseudoCustomAttribute
1567                 {
1568                         get
1569                         {
1570                                 Universe u = this.Module.universe;
1571                                 return this == u.System_NonSerializedAttribute
1572                                         || this == u.System_SerializableAttribute
1573                                         || this == u.System_Runtime_InteropServices_DllImportAttribute
1574                                         || this == u.System_Runtime_InteropServices_FieldOffsetAttribute
1575                                         || this == u.System_Runtime_InteropServices_InAttribute
1576                                         || this == u.System_Runtime_InteropServices_MarshalAsAttribute
1577                                         || this == u.System_Runtime_InteropServices_OutAttribute
1578                                         || this == u.System_Runtime_InteropServices_StructLayoutAttribute
1579                                         || this == u.System_Runtime_InteropServices_OptionalAttribute
1580                                         || this == u.System_Runtime_InteropServices_PreserveSigAttribute
1581                                         || this == u.System_Runtime_InteropServices_ComImportAttribute
1582                                         || this == u.System_Runtime_CompilerServices_SpecialNameAttribute
1583                                         || this == u.System_Runtime_CompilerServices_MethodImplAttribute
1584                                         ;
1585                         }
1586                 }
1587         }
1588
1589         abstract class ElementHolderType : Type
1590         {
1591                 protected readonly Type elementType;
1592                 private int token;
1593                 private readonly Type[] requiredCustomModifiers;
1594                 private readonly Type[] optionalCustomModifiers;
1595
1596                 protected ElementHolderType(Type elementType, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1597                 {
1598                         this.elementType = elementType;
1599                         this.requiredCustomModifiers = requiredCustomModifiers;
1600                         this.optionalCustomModifiers = optionalCustomModifiers;
1601                 }
1602
1603                 protected bool EqualsHelper(ElementHolderType other)
1604                 {
1605                         return other != null
1606                                 && other.elementType.Equals(elementType)
1607                                 && Util.ArrayEquals(other.requiredCustomModifiers, requiredCustomModifiers)
1608                                 && Util.ArrayEquals(other.optionalCustomModifiers, optionalCustomModifiers);
1609                 }
1610
1611                 public override Type[] __GetRequiredCustomModifiers()
1612                 {
1613                         return Util.Copy(requiredCustomModifiers);
1614                 }
1615
1616                 public override Type[] __GetOptionalCustomModifiers()
1617                 {
1618                         return Util.Copy(optionalCustomModifiers);
1619                 }
1620
1621                 public sealed override string Name
1622                 {
1623                         get { return elementType.Name + GetSuffix(); }
1624                 }
1625
1626                 public sealed override string Namespace
1627                 {
1628                         get { return elementType.Namespace; }
1629                 }
1630
1631                 public sealed override string FullName
1632                 {
1633                         get { return elementType.FullName + GetSuffix(); }
1634                 }
1635
1636                 public sealed override string ToString()
1637                 {
1638                         return elementType.ToString() + GetSuffix();
1639                 }
1640
1641                 public sealed override Type GetElementType()
1642                 {
1643                         return elementType;
1644                 }
1645
1646                 public sealed override bool HasElementType
1647                 {
1648                         get { return true; }
1649                 }
1650
1651                 public sealed override Module Module
1652                 {
1653                         get { return elementType.Module; }
1654                 }
1655
1656                 internal sealed override int GetModuleBuilderToken()
1657                 {
1658                         if (token == 0)
1659                         {
1660                                 token = ((ModuleBuilder)elementType.Module).ImportType(this);
1661                         }
1662                         return token;
1663                 }
1664
1665                 public sealed override bool ContainsGenericParameters
1666                 {
1667                         get
1668                         {
1669                                 Type type = elementType;
1670                                 while (type.HasElementType)
1671                                 {
1672                                         type = type.GetElementType();
1673                                 }
1674                                 return type.ContainsGenericParameters;
1675                         }
1676                 }
1677
1678                 public sealed override bool __ContainsMissingType
1679                 {
1680                         get
1681                         {
1682                                 Type type = elementType;
1683                                 while (type.HasElementType)
1684                                 {
1685                                         type = type.GetElementType();
1686                                 }
1687                                 return type.__ContainsMissingType;
1688                         }
1689                 }
1690
1691                 internal sealed override Type BindTypeParameters(IGenericBinder binder)
1692                 {
1693                         Type type = elementType.BindTypeParameters(binder);
1694                         Type[] req = BindArray(requiredCustomModifiers, binder);
1695                         Type[] opt = BindArray(optionalCustomModifiers, binder);
1696                         if (ReferenceEquals(type, elementType)
1697                                 && ReferenceEquals(req, requiredCustomModifiers)
1698                                 && ReferenceEquals(opt, optionalCustomModifiers))
1699                         {
1700                                 return this;
1701                         }
1702                         return Wrap(type, req, opt);
1703                 }
1704
1705                 internal override void CheckBaked()
1706                 {
1707                         elementType.CheckBaked();
1708                 }
1709
1710                 private static Type[] BindArray(Type[] array, IGenericBinder binder)
1711                 {
1712                         if (array ==null || array.Length == 0)
1713                         {
1714                                 return array;
1715                         }
1716                         Type[] result = array;
1717                         for (int i = 0; i < array.Length; i++)
1718                         {
1719                                 Type type = array[i].BindTypeParameters(binder);
1720                                 if (!ReferenceEquals(type, array[i]))
1721                                 {
1722                                         if (result == array)
1723                                         {
1724                                                 result = (Type[])array.Clone();
1725                                         }
1726                                         result[i] = type;
1727                                 }
1728                         }
1729                         return result;
1730                 }
1731
1732                 internal sealed override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
1733                 {
1734                         return CustomAttributeData.EmptyList;
1735                 }
1736
1737                 protected abstract string GetSuffix();
1738
1739                 protected abstract Type Wrap(Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers);
1740         }
1741
1742         sealed class ArrayType : ElementHolderType
1743         {
1744                 internal static Type Make(Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1745                 {
1746                         return type.Module.CanonicalizeType(new ArrayType(type, requiredCustomModifiers, optionalCustomModifiers));
1747                 }
1748
1749                 private ArrayType(Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1750                         : base(type, requiredCustomModifiers, optionalCustomModifiers)
1751                 {
1752                 }
1753
1754                 public override Type BaseType
1755                 {
1756                         get { return elementType.Module.universe.System_Array; }
1757                 }
1758
1759                 public override Type[] __GetDeclaredInterfaces()
1760                 {
1761                         return new Type[] {
1762                                 this.Module.universe.Import(typeof(IList<>)).MakeGenericType(elementType),
1763                                 this.Module.universe.Import(typeof(ICollection<>)).MakeGenericType(elementType),
1764                                 this.Module.universe.Import(typeof(IEnumerable<>)).MakeGenericType(elementType)
1765                         };
1766                 }
1767
1768                 public override MethodBase[] __GetDeclaredMethods()
1769                 {
1770                         Type[] int32 = new Type[] { this.Module.universe.System_Int32 };
1771                         List<MethodBase> list = new List<MethodBase>();
1772                         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 }));
1773                         list.Add(new BuiltinArrayMethod(this.Module, this, "Address", CallingConventions.Standard | CallingConventions.HasThis, elementType.MakeByRefType(), int32));
1774                         list.Add(new BuiltinArrayMethod(this.Module, this, "Get", CallingConventions.Standard | CallingConventions.HasThis, elementType, int32));
1775                         list.Add(new ConstructorInfoImpl(new BuiltinArrayMethod(this.Module, this, ".ctor", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, int32)));
1776                         for (Type type = elementType; type.__IsVector; type = type.GetElementType())
1777                         {
1778                                 Array.Resize(ref int32, int32.Length + 1);
1779                                 int32[int32.Length - 1] = int32[0];
1780                                 list.Add(new ConstructorInfoImpl(new BuiltinArrayMethod(this.Module, this, ".ctor", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, int32)));
1781                         }
1782                         return list.ToArray();
1783                 }
1784
1785                 public override TypeAttributes Attributes
1786                 {
1787                         get { return TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Serializable; }
1788                 }
1789
1790                 public override bool IsArray
1791                 {
1792                         get { return true; }
1793                 }
1794
1795                 public override bool __IsVector
1796                 {
1797                         get { return true; }
1798                 }
1799
1800                 public override int GetArrayRank()
1801                 {
1802                         return 1;
1803                 }
1804
1805                 public override bool Equals(object o)
1806                 {
1807                         return EqualsHelper(o as ArrayType);
1808                 }
1809
1810                 public override int GetHashCode()
1811                 {
1812                         return elementType.GetHashCode() * 5;
1813                 }
1814
1815                 protected override string GetSuffix()
1816                 {
1817                         return "[]";
1818                 }
1819
1820                 protected override Type Wrap(Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1821                 {
1822                         return Make(type, requiredCustomModifiers, optionalCustomModifiers);
1823                 }
1824         }
1825
1826         sealed class MultiArrayType : ElementHolderType
1827         {
1828                 private readonly int rank;
1829
1830                 internal static Type Make(Type type, int rank, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1831                 {
1832                         return type.Module.CanonicalizeType(new MultiArrayType(type, rank, requiredCustomModifiers, optionalCustomModifiers));
1833                 }
1834
1835                 private MultiArrayType(Type type, int rank, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1836                         : base(type, requiredCustomModifiers, optionalCustomModifiers)
1837                 {
1838                         this.rank = rank;
1839                 }
1840
1841                 public override Type BaseType
1842                 {
1843                         get { return elementType.Module.universe.System_Array; }
1844                 }
1845
1846                 public override MethodBase[] __GetDeclaredMethods()
1847                 {
1848                         Type int32 = this.Module.universe.System_Int32;
1849                         Type[] setArgs = new Type[rank + 1];
1850                         Type[] getArgs = new Type[rank];
1851                         Type[] ctorArgs = new Type[rank * 2];
1852                         for (int i = 0; i < rank; i++)
1853                         {
1854                                 setArgs[i] = int32;
1855                                 getArgs[i] = int32;
1856                                 ctorArgs[i * 2 + 0] = int32;
1857                                 ctorArgs[i * 2 + 1] = int32;
1858                         }
1859                         setArgs[rank] = elementType;
1860                         return new MethodBase[] {
1861                                 new ConstructorInfoImpl(new BuiltinArrayMethod(this.Module, this, ".ctor", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, getArgs)),
1862                                 new ConstructorInfoImpl(new BuiltinArrayMethod(this.Module, this, ".ctor", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, ctorArgs)),
1863                                 new BuiltinArrayMethod(this.Module, this, "Set", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, setArgs),
1864                                 new BuiltinArrayMethod(this.Module, this, "Address", CallingConventions.Standard | CallingConventions.HasThis, elementType.MakeByRefType(), getArgs),
1865                                 new BuiltinArrayMethod(this.Module, this, "Get", CallingConventions.Standard | CallingConventions.HasThis, elementType, getArgs),
1866                         };
1867                 }
1868
1869                 public override TypeAttributes Attributes
1870                 {
1871                         get { return TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Serializable; }
1872                 }
1873
1874                 public override bool IsArray
1875                 {
1876                         get { return true; }
1877                 }
1878
1879                 public override int GetArrayRank()
1880                 {
1881                         return rank;
1882                 }
1883
1884                 public override bool Equals(object o)
1885                 {
1886                         MultiArrayType at = o as MultiArrayType;
1887                         return EqualsHelper(at) && at.rank == rank;
1888                 }
1889
1890                 public override int GetHashCode()
1891                 {
1892                         return elementType.GetHashCode() * 9 + rank;
1893                 }
1894
1895                 protected override string GetSuffix()
1896                 {
1897                         if (rank == 1)
1898                         {
1899                                 return "[*]";
1900                         }
1901                         else
1902                         {
1903                                 return "[" + new String(',', rank - 1) + "]";
1904                         }
1905                 }
1906
1907                 protected override Type Wrap(Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1908                 {
1909                         return Make(type, rank, requiredCustomModifiers, optionalCustomModifiers);
1910                 }
1911         }
1912
1913         sealed class BuiltinArrayMethod : ArrayMethod
1914         {
1915                 internal BuiltinArrayMethod(Module module, Type arrayClass, string methodName, CallingConventions callingConvention, Type returnType, Type[] parameterTypes)
1916                         : base(module, arrayClass, methodName, callingConvention, returnType, parameterTypes)
1917                 {
1918                 }
1919
1920                 public override MethodAttributes Attributes
1921                 {
1922                         get { return this.Name == ".ctor" ? MethodAttributes.RTSpecialName | MethodAttributes.Public : MethodAttributes.Public; }
1923                 }
1924
1925                 public override MethodImplAttributes GetMethodImplementationFlags()
1926                 {
1927                         return MethodImplAttributes.IL;
1928                 }
1929
1930                 public override int MetadataToken
1931                 {
1932                         get { return 0x06000000; }
1933                 }
1934
1935                 public override MethodBody GetMethodBody()
1936                 {
1937                         return null;
1938                 }
1939
1940                 public override ParameterInfo[] GetParameters()
1941                 {
1942                         ParameterInfo[] parameterInfos = new ParameterInfo[parameterTypes.Length];
1943                         for (int i = 0; i < parameterInfos.Length; i++)
1944                         {
1945                                 parameterInfos[i] = new ParameterInfoImpl(this, parameterTypes[i], i);
1946                         }
1947                         return parameterInfos;
1948                 }
1949
1950                 public override ParameterInfo ReturnParameter
1951                 {
1952                         get { return new ParameterInfoImpl(this, this.ReturnType, -1); }
1953                 }
1954
1955                 private sealed class ParameterInfoImpl : ParameterInfo
1956                 {
1957                         private readonly MethodInfo method;
1958                         private readonly Type type;
1959                         private readonly int pos;
1960
1961                         internal ParameterInfoImpl(MethodInfo method, Type type, int pos)
1962                         {
1963                                 this.method = method;
1964                                 this.type = type;
1965                                 this.pos = pos;
1966                         }
1967
1968                         public override Type ParameterType
1969                         {
1970                                 get { return type; }
1971                         }
1972
1973                         public override string Name
1974                         {
1975                                 get { return null; }
1976                         }
1977
1978                         public override ParameterAttributes Attributes
1979                         {
1980                                 get { return ParameterAttributes.None; }
1981                         }
1982
1983                         public override int Position
1984                         {
1985                                 get { return pos; }
1986                         }
1987
1988                         public override object RawDefaultValue
1989                         {
1990                                 get { return null; }
1991                         }
1992
1993                         public override Type[] GetOptionalCustomModifiers()
1994                         {
1995                                 return Empty<Type>.Array;
1996                         }
1997
1998                         public override Type[] GetRequiredCustomModifiers()
1999                         {
2000                                 return Empty<Type>.Array;
2001                         }
2002
2003                         public override MemberInfo Member
2004                         {
2005                                 get { return method.IsConstructor ? (MethodBase)new ConstructorInfoImpl(method) : method; }
2006                         }
2007
2008                         public override int MetadataToken
2009                         {
2010                                 get { return 0x8000000; }
2011                         }
2012
2013                         internal override Module Module
2014                         {
2015                                 get { return method.Module; }
2016                         }
2017                 }
2018         }
2019
2020         sealed class ByRefType : ElementHolderType
2021         {
2022                 internal static Type Make(Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
2023                 {
2024                         return type.Module.CanonicalizeType(new ByRefType(type, requiredCustomModifiers, optionalCustomModifiers));
2025                 }
2026
2027                 private ByRefType(Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
2028                         : base(type, requiredCustomModifiers, optionalCustomModifiers)
2029                 {
2030                 }
2031
2032                 public override bool Equals(object o)
2033                 {
2034                         return EqualsHelper(o as ByRefType);
2035                 }
2036
2037                 public override int GetHashCode()
2038                 {
2039                         return elementType.GetHashCode() * 3;
2040                 }
2041
2042                 public override Type BaseType
2043                 {
2044                         get { return null; }
2045                 }
2046
2047                 public override TypeAttributes Attributes
2048                 {
2049                         get { return 0; }
2050                 }
2051
2052                 public override bool IsByRef
2053                 {
2054                         get { return true; }
2055                 }
2056
2057                 protected override string GetSuffix()
2058                 {
2059                         return "&";
2060                 }
2061
2062                 protected override Type Wrap(Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
2063                 {
2064                         return Make(type, requiredCustomModifiers, optionalCustomModifiers);
2065                 }
2066         }
2067
2068         sealed class PointerType : ElementHolderType
2069         {
2070                 internal static Type Make(Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
2071                 {
2072                         return type.Module.CanonicalizeType(new PointerType(type, requiredCustomModifiers, optionalCustomModifiers));
2073                 }
2074
2075                 private PointerType(Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
2076                         : base(type, requiredCustomModifiers, optionalCustomModifiers)
2077                 {
2078                 }
2079
2080                 public override bool Equals(object o)
2081                 {
2082                         return EqualsHelper(o as PointerType);
2083                 }
2084
2085                 public override int GetHashCode()
2086                 {
2087                         return elementType.GetHashCode() * 7;
2088                 }
2089
2090                 public override Type BaseType
2091                 {
2092                         get { return null; }
2093                 }
2094
2095                 public override TypeAttributes Attributes
2096                 {
2097                         get { return 0; }
2098                 }
2099
2100                 public override bool IsPointer
2101                 {
2102                         get { return true; }
2103                 }
2104
2105                 protected override string GetSuffix()
2106                 {
2107                         return "*";
2108                 }
2109
2110                 protected override Type Wrap(Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
2111                 {
2112                         return Make(type, requiredCustomModifiers, optionalCustomModifiers);
2113                 }
2114         }
2115
2116         sealed class GenericTypeInstance : Type
2117         {
2118                 private readonly Type type;
2119                 private readonly Type[] args;
2120                 private readonly Type[][] requiredCustomModifiers;
2121                 private readonly Type[][] optionalCustomModifiers;
2122                 private Type baseType;
2123                 private int token;
2124
2125                 internal static Type Make(Type type, Type[] typeArguments, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
2126                 {
2127                         bool identity = true;
2128                         if (type is TypeBuilder || type is BakedType || type.__IsMissing)
2129                         {
2130                                 // a TypeBuiler identity must be instantiated
2131                                 identity = false;
2132                         }
2133                         else
2134                         {
2135                                 // we must not instantiate the identity instance, because typeof(Foo<>).MakeGenericType(typeof(Foo<>).GetGenericArguments()) == typeof(Foo<>)
2136                                 for (int i = 0; i < typeArguments.Length; i++)
2137                                 {
2138                                         if (typeArguments[i] != type.GetGenericTypeArgument(i)
2139                                                 || !IsEmpty(requiredCustomModifiers, i)
2140                                                 || !IsEmpty(optionalCustomModifiers, i))
2141                                         {
2142                                                 identity = false;
2143                                                 break;
2144                                         }
2145                                 }
2146                         }
2147                         if (identity)
2148                         {
2149                                 return type;
2150                         }
2151                         else
2152                         {
2153                                 return type.Module.CanonicalizeType(new GenericTypeInstance(type, typeArguments, requiredCustomModifiers, optionalCustomModifiers));
2154                         }
2155                 }
2156
2157                 private static bool IsEmpty(Type[][] mods, int i)
2158                 {
2159                         // we need to be extra careful, because mods doesn't not need to be in canonical format
2160                         // (Signature.ReadGenericInst() calls Make() directly, without copying the modifier arrays)
2161                         return mods == null || mods[i] == null || mods[i].Length == 0;
2162                 }
2163
2164                 private GenericTypeInstance(Type type, Type[] args, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
2165                 {
2166                         this.type = type;
2167                         this.args = args;
2168                         this.requiredCustomModifiers = requiredCustomModifiers;
2169                         this.optionalCustomModifiers = optionalCustomModifiers;
2170                 }
2171
2172                 public override bool Equals(object o)
2173                 {
2174                         GenericTypeInstance gt = o as GenericTypeInstance;
2175                         return gt != null && gt.type.Equals(type) && Util.ArrayEquals(gt.args, args)
2176                                 && Util.ArrayEquals(gt.requiredCustomModifiers, requiredCustomModifiers)
2177                                 && Util.ArrayEquals(gt.optionalCustomModifiers, optionalCustomModifiers);
2178                 }
2179
2180                 public override int GetHashCode()
2181                 {
2182                         return type.GetHashCode() * 3 ^ Util.GetHashCode(args);
2183                 }
2184
2185                 public override string AssemblyQualifiedName
2186                 {
2187                         get
2188                         {
2189                                 string fn = FullName;
2190                                 return fn == null ? null : fn + ", " + type.Assembly.FullName;
2191                         }
2192                 }
2193
2194                 public override Type BaseType
2195                 {
2196                         get
2197                         {
2198                                 if (baseType == null)
2199                                 {
2200                                         Type rawBaseType = type.BaseType;
2201                                         if (rawBaseType == null)
2202                                         {
2203                                                 baseType = rawBaseType;
2204                                         }
2205                                         else
2206                                         {
2207                                                 baseType = rawBaseType.BindTypeParameters(this);
2208                                         }
2209                                 }
2210                                 return baseType;
2211                         }
2212                 }
2213
2214                 public override bool IsValueType
2215                 {
2216                         get { return type.IsValueType; }
2217                 }
2218
2219                 public override bool IsVisible
2220                 {
2221                         get
2222                         {
2223                                 if (base.IsVisible)
2224                                 {
2225                                         foreach (Type arg in args)
2226                                         {
2227                                                 if (!arg.IsVisible)
2228                                                 {
2229                                                         return false;
2230                                                 }
2231                                         }
2232                                         return true;
2233                                 }
2234                                 return false;
2235                         }
2236                 }
2237
2238                 public override Type DeclaringType
2239                 {
2240                         get { return type.DeclaringType; }
2241                 }
2242
2243                 public override TypeAttributes Attributes
2244                 {
2245                         get { return type.Attributes; }
2246                 }
2247
2248                 internal override void CheckBaked()
2249                 {
2250                         type.CheckBaked();
2251                 }
2252
2253                 public override FieldInfo[] __GetDeclaredFields()
2254                 {
2255                         FieldInfo[] fields = type.__GetDeclaredFields();
2256                         for (int i = 0; i < fields.Length; i++)
2257                         {
2258                                 fields[i] = fields[i].BindTypeParameters(this);
2259                         }
2260                         return fields;
2261                 }
2262
2263                 public override Type[] __GetDeclaredInterfaces()
2264                 {
2265                         Type[] interfaces = type.__GetDeclaredInterfaces();
2266                         for (int i = 0; i < interfaces.Length; i++)
2267                         {
2268                                 interfaces[i] = interfaces[i].BindTypeParameters(this);
2269                         }
2270                         return interfaces;
2271                 }
2272
2273                 public override MethodBase[] __GetDeclaredMethods()
2274                 {
2275                         MethodBase[] methods = type.__GetDeclaredMethods();
2276                         for (int i = 0; i < methods.Length; i++)
2277                         {
2278                                 methods[i] = methods[i].BindTypeParameters(this);
2279                         }
2280                         return methods;
2281                 }
2282
2283                 public override Type[] __GetDeclaredTypes()
2284                 {
2285                         return type.__GetDeclaredTypes();
2286                 }
2287
2288                 public override EventInfo[] __GetDeclaredEvents()
2289                 {
2290                         EventInfo[] events = type.__GetDeclaredEvents();
2291                         for (int i = 0; i < events.Length; i++)
2292                         {
2293                                 events[i] = events[i].BindTypeParameters(this);
2294                         }
2295                         return events;
2296                 }
2297
2298                 public override PropertyInfo[] __GetDeclaredProperties()
2299                 {
2300                         PropertyInfo[] properties = type.__GetDeclaredProperties();
2301                         for (int i = 0; i < properties.Length; i++)
2302                         {
2303                                 properties[i] = properties[i].BindTypeParameters(this);
2304                         }
2305                         return properties;
2306                 }
2307
2308                 public override __MethodImplMap __GetMethodImplMap()
2309                 {
2310                         __MethodImplMap map = type.__GetMethodImplMap();
2311                         map.TargetType = this;
2312                         for (int i = 0; i < map.MethodBodies.Length; i++)
2313                         {
2314                                 map.MethodBodies[i] = (MethodInfo)map.MethodBodies[i].BindTypeParameters(this);
2315                                 for (int j = 0; j < map.MethodDeclarations[i].Length; j++)
2316                                 {
2317                                         Type interfaceType = map.MethodDeclarations[i][j].DeclaringType;
2318                                         if (interfaceType.IsGenericType)
2319                                         {
2320                                                 map.MethodDeclarations[i][j] = (MethodInfo)map.MethodDeclarations[i][j].BindTypeParameters(this);
2321                                         }
2322                                 }
2323                         }
2324                         return map;
2325                 }
2326
2327                 public override string Namespace
2328                 {
2329                         get { return type.Namespace; }
2330                 }
2331
2332                 public override Type UnderlyingSystemType
2333                 {
2334                         get { return this; }
2335                 }
2336
2337                 public override string Name
2338                 {
2339                         get { return type.Name; }
2340                 }
2341
2342                 public override string FullName
2343                 {
2344                         get
2345                         {
2346                                 if (this.ContainsGenericParameters)
2347                                 {
2348                                         return null;
2349                                 }
2350                                 StringBuilder sb = new StringBuilder(this.type.FullName);
2351                                 sb.Append('[');
2352                                 foreach (Type type in args)
2353                                 {
2354                                         sb.Append('[').Append(type.AssemblyQualifiedName.Replace("]", "\\]")).Append(']');
2355                                 }
2356                                 sb.Append(']');
2357                                 return sb.ToString();
2358                         }
2359                 }
2360
2361                 public override string ToString()
2362                 {
2363                         StringBuilder sb = new StringBuilder(type.FullName);
2364                         sb.Append('[');
2365                         string sep = "";
2366                         foreach (Type arg in args)
2367                         {
2368                                 sb.Append(sep);
2369                                 sb.Append(arg);
2370                                 sep = ",";
2371                         }
2372                         sb.Append(']');
2373                         return sb.ToString();
2374                 }
2375
2376                 public override Module Module
2377                 {
2378                         get { return type.Module; }
2379                 }
2380
2381                 public override bool IsGenericType
2382                 {
2383                         get { return true; }
2384                 }
2385
2386                 public override Type GetGenericTypeDefinition()
2387                 {
2388                         return type;
2389                 }
2390
2391                 public override Type[] GetGenericArguments()
2392                 {
2393                         return Util.Copy(args);
2394                 }
2395
2396                 public override Type[][] __GetGenericArgumentsRequiredCustomModifiers()
2397                 {
2398                         return Util.Copy(requiredCustomModifiers ?? new Type[args.Length][]);
2399                 }
2400
2401                 public override Type[][] __GetGenericArgumentsOptionalCustomModifiers()
2402                 {
2403                         return Util.Copy(optionalCustomModifiers ?? new Type[args.Length][]);
2404                 }
2405
2406                 internal override Type GetGenericTypeArgument(int index)
2407                 {
2408                         return args[index];
2409                 }
2410
2411                 public override bool ContainsGenericParameters
2412                 {
2413                         get
2414                         {
2415                                 foreach (Type type in args)
2416                                 {
2417                                         if (type.ContainsGenericParameters)
2418                                         {
2419                                                 return true;
2420                                         }
2421                                 }
2422                                 return false;
2423                         }
2424                 }
2425
2426                 public override bool __ContainsMissingType
2427                 {
2428                         get
2429                         {
2430                                 foreach (Type type in args)
2431                                 {
2432                                         if (type.__ContainsMissingType)
2433                                         {
2434                                                 return true;
2435                                         }
2436                                 }
2437                                 return this.type.__IsMissing;
2438                         }
2439                 }
2440
2441                 public override StructLayoutAttribute StructLayoutAttribute
2442                 {
2443                         get { return type.StructLayoutAttribute; }
2444                 }
2445
2446                 internal override int GetModuleBuilderToken()
2447                 {
2448                         if (token == 0)
2449                         {
2450                                 token = ((ModuleBuilder)type.Module).ImportType(this);
2451                         }
2452                         return token;
2453                 }
2454
2455                 internal override Type BindTypeParameters(IGenericBinder binder)
2456                 {
2457                         for (int i = 0; i < args.Length; i++)
2458                         {
2459                                 Type xarg = args[i].BindTypeParameters(binder);
2460                                 if (!ReferenceEquals(xarg, args[i]))
2461                                 {
2462                                         Type[] xargs = new Type[args.Length];
2463                                         Array.Copy(args, xargs, i);
2464                                         xargs[i++] = xarg;
2465                                         for (; i < args.Length; i++)
2466                                         {
2467                                                 xargs[i] = args[i].BindTypeParameters(binder);
2468                                         }
2469                                         return Make(type, xargs, null, null);
2470                                 }
2471                         }
2472                         return this;
2473                 }
2474
2475                 internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
2476                 {
2477                         return type.GetCustomAttributesData(attributeType);
2478                 }
2479         }
2480 }