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