Merge pull request #238 from knocte/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 null; }
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 = delegate(MemberInfo member, object filterCriteria) { return member.Name.Equals(filterCriteria); };
525                         return FindMembers(type, bindingAttr, filter, name);
526                 }
527
528                 private static void AddMembers(List<MemberInfo> list, MemberFilter filter, object filterCriteria, MemberInfo[] members)
529                 {
530                         foreach (MemberInfo member in members)
531                         {
532                                 if (filter == null || filter(member, filterCriteria))
533                                 {
534                                         list.Add(member);
535                                 }
536                         }
537                 }
538
539                 public MemberInfo[] FindMembers(MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, object filterCriteria)
540                 {
541                         List<MemberInfo> members = new List<MemberInfo>();
542                         if ((memberType & MemberTypes.Constructor) != 0)
543                         {
544                                 AddMembers(members, filter, filterCriteria, GetConstructors(bindingAttr));
545                         }
546                         if ((memberType & MemberTypes.Method) != 0)
547                         {
548                                 AddMembers(members, filter, filterCriteria, GetMethods(bindingAttr));
549                         }
550                         if ((memberType & MemberTypes.Field) != 0)
551                         {
552                                 AddMembers(members, filter, filterCriteria, GetFields(bindingAttr));
553                         }
554                         if ((memberType & MemberTypes.Property) != 0)
555                         {
556                                 AddMembers(members, filter, filterCriteria, GetProperties(bindingAttr));
557                         }
558                         if ((memberType & MemberTypes.Event) != 0)
559                         {
560                                 AddMembers(members, filter, filterCriteria, GetEvents(bindingAttr));
561                         }
562                         if ((memberType & MemberTypes.NestedType) != 0)
563                         {
564                                 AddMembers(members, filter, filterCriteria, GetNestedTypes(bindingAttr));
565                         }
566                         return members.ToArray();
567                 }
568
569                 public EventInfo GetEvent(string name)
570                 {
571                         return GetEvent(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
572                 }
573
574                 public EventInfo GetEvent(string name, BindingFlags bindingAttr)
575                 {
576                         foreach (EventInfo evt in GetEvents(bindingAttr))
577                         {
578                                 if (evt.Name == name)
579                                 {
580                                         return evt;
581                                 }
582                         }
583                         return null;
584                 }
585
586                 public EventInfo[] GetEvents()
587                 {
588                         return GetEvents(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
589                 }
590
591                 public EventInfo[] GetEvents(BindingFlags bindingAttr)
592                 {
593                         List<EventInfo> list = new List<EventInfo>();
594                         Type type = this;
595                         while (type != null)
596                         {
597                                 type.CheckBaked();
598                                 foreach (EventInfo evt in type.__GetDeclaredEvents())
599                                 {
600                                         if (BindingFlagsMatch(evt.IsPublic, bindingAttr, BindingFlags.Public, BindingFlags.NonPublic)
601                                                 && BindingFlagsMatch(evt.IsStatic, bindingAttr, BindingFlags.Static, BindingFlags.Instance))
602                                         {
603                                                 list.Add(evt);
604                                         }
605                                 }
606                                 if ((bindingAttr & BindingFlags.DeclaredOnly) == 0)
607                                 {
608                                         if ((bindingAttr & BindingFlags.FlattenHierarchy) == 0)
609                                         {
610                                                 bindingAttr &= ~BindingFlags.Static;
611                                         }
612                                         type = type.BaseType;
613                                 }
614                                 else
615                                 {
616                                         break;
617                                 }
618                         }
619                         return list.ToArray();
620                 }
621
622                 public FieldInfo GetField(string name)
623                 {
624                         return GetField(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
625                 }
626
627                 public FieldInfo GetField(string name, BindingFlags bindingAttr)
628                 {
629                         foreach (FieldInfo field in GetFields(bindingAttr))
630                         {
631                                 if (field.Name == name)
632                                 {
633                                         return field;
634                                 }
635                         }
636                         return null;
637                 }
638
639                 public FieldInfo[] GetFields()
640                 {
641                         return GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
642                 }
643
644                 public FieldInfo[] GetFields(BindingFlags bindingAttr)
645                 {
646                         List<FieldInfo> list = new List<FieldInfo>();
647                         CheckBaked();
648                         foreach (FieldInfo field in __GetDeclaredFields())
649                         {
650                                 if (BindingFlagsMatch(field.IsPublic, bindingAttr, BindingFlags.Public, BindingFlags.NonPublic)
651                                         && BindingFlagsMatch(field.IsStatic, bindingAttr, BindingFlags.Static, BindingFlags.Instance))
652                                 {
653                                         list.Add(field);
654                                 }
655                         }
656                         if ((bindingAttr & BindingFlags.DeclaredOnly) == 0)
657                         {
658                                 for (Type type = this.BaseType; type != null; type = type.BaseType)
659                                 {
660                                         type.CheckBaked();
661                                         foreach (FieldInfo field in type.__GetDeclaredFields())
662                                         {
663                                                 if ((field.Attributes & FieldAttributes.FieldAccessMask) > FieldAttributes.Private
664                                                         && BindingFlagsMatch(field.IsStatic, bindingAttr, BindingFlags.Static | BindingFlags.FlattenHierarchy, BindingFlags.Instance))
665                                                 {
666                                                         list.Add(field);
667                                                 }
668                                         }
669                                 }
670                         }
671                         return list.ToArray();
672                 }
673
674                 public Type[] GetInterfaces()
675                 {
676                         List<Type> list = new List<Type>();
677                         for (Type type = this; type != null; type = type.BaseType)
678                         {
679                                 AddInterfaces(list, type);
680                         }
681                         return list.ToArray();
682                 }
683
684                 private static void AddInterfaces(List<Type> list, Type type)
685                 {
686                         type.CheckBaked();
687                         foreach (Type iface in type.__GetDeclaredInterfaces())
688                         {
689                                 if (!list.Contains(iface))
690                                 {
691                                         list.Add(iface);
692                                         AddInterfaces(list, iface);
693                                 }
694                         }
695                 }
696
697                 public MethodInfo[] GetMethods(BindingFlags bindingAttr)
698                 {
699                         CheckBaked();
700                         List<MethodInfo> list = new List<MethodInfo>();
701                         foreach (MethodBase mb in __GetDeclaredMethods())
702                         {
703                                 MethodInfo mi = mb as MethodInfo;
704                                 if (mi != null
705                                         && BindingFlagsMatch(mi.IsPublic, bindingAttr, BindingFlags.Public, BindingFlags.NonPublic)
706                                         && BindingFlagsMatch(mi.IsStatic, bindingAttr, BindingFlags.Static, BindingFlags.Instance))
707                                 {
708                                         list.Add(mi);
709                                 }
710                         }
711                         if ((bindingAttr & BindingFlags.DeclaredOnly) == 0)
712                         {
713                                 for (Type type = this.BaseType; type != null; type = type.BaseType)
714                                 {
715                                         type.CheckBaked();
716                                         foreach (MethodBase mb in type.__GetDeclaredMethods())
717                                         {
718                                                 MethodInfo mi = mb as MethodInfo;
719                                                 if (mi != null
720                                                         && (mi.Attributes & MethodAttributes.MemberAccessMask) > MethodAttributes.Private
721                                                         && BindingFlagsMatch(mi.IsPublic, bindingAttr, BindingFlags.Public, BindingFlags.NonPublic)
722                                                         && BindingFlagsMatch(mi.IsStatic, bindingAttr, BindingFlags.Static | BindingFlags.FlattenHierarchy, BindingFlags.Instance)
723                                                         && !FindMethod(list, mi))
724                                                 {
725                                                         list.Add(mi);
726                                                 }
727                                         }
728                                 }
729                         }
730                         return list.ToArray();
731                 }
732
733                 private static bool FindMethod(List<MethodInfo> methods, MethodInfo method)
734                 {
735                         foreach (MethodInfo m in methods)
736                         {
737                                 if (m.Name == method.Name && m.MethodSignature.Equals(method.MethodSignature))
738                                 {
739                                         return true;
740                                 }
741                         }
742                         return false;
743                 }
744
745                 public MethodInfo[] GetMethods()
746                 {
747                         return GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
748                 }
749
750                 public MethodInfo GetMethod(string name)
751                 {
752                         return GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
753                 }
754
755                 public MethodInfo GetMethod(string name, BindingFlags bindingAttr)
756                 {
757                         MethodInfo found = null;
758                         foreach (MethodInfo method in GetMethods(bindingAttr))
759                         {
760                                 if (method.Name == name)
761                                 {
762                                         if (found != null)
763                                         {
764                                                 throw new AmbiguousMatchException();
765                                         }
766                                         found = method;
767                                 }
768                         }
769                         return found;
770                 }
771
772                 public MethodInfo GetMethod(string name, Type[] types)
773                 {
774                         return GetMethod(name, types, null);
775                 }
776
777                 public MethodInfo GetMethod(string name, Type[] types, ParameterModifier[] modifiers)
778                 {
779                         return GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public, null, types, modifiers);
780                 }
781
782                 public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
783                 {
784                         MethodInfo found = null;
785                         foreach (MethodInfo method in GetMethods(bindingAttr))
786                         {
787                                 if (method.Name == name && method.MethodSignature.MatchParameterTypes(types))
788                                 {
789                                         if (found != null)
790                                         {
791                                                 throw new AmbiguousMatchException();
792                                         }
793                                         found = method;
794                                 }
795                         }
796                         return found;
797                 }
798
799                 public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
800                 {
801                         // FXBUG callConvention seems to be ignored
802                         return GetMethod(name, bindingAttr, binder, types, modifiers);
803                 }
804
805                 public ConstructorInfo[] GetConstructors()
806                 {
807                         return GetConstructors(BindingFlags.Public | BindingFlags.Instance);
808                 }
809
810                 public ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
811                 {
812                         CheckBaked();
813                         List<ConstructorInfo> list = new List<ConstructorInfo>();
814                         foreach (MethodBase mb in __GetDeclaredMethods())
815                         {
816                                 ConstructorInfo constructor = mb as ConstructorInfo;
817                                 if (constructor != null
818                                         && BindingFlagsMatch(constructor.IsPublic, bindingAttr, BindingFlags.Public, BindingFlags.NonPublic)
819                                         && BindingFlagsMatch(constructor.IsStatic, bindingAttr, BindingFlags.Static, BindingFlags.Instance))
820                                 {
821                                         list.Add(constructor);
822                                 }
823                         }
824                         return list.ToArray();
825                 }
826
827                 public ConstructorInfo GetConstructor(Type[] types)
828                 {
829                         return GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, CallingConventions.Standard, types, null);
830                 }
831
832                 public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
833                 {
834                         foreach (ConstructorInfo constructor in GetConstructors(bindingAttr))
835                         {
836                                 if (constructor.MethodSignature.MatchParameterTypes(types))
837                                 {
838                                         return constructor;
839                                 }
840                         }
841                         return null;
842                 }
843
844                 public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, CallingConventions callingConvention, Type[] types, ParameterModifier[] modifiers)
845                 {
846                         // FXBUG callConvention seems to be ignored
847                         return GetConstructor(bindingAttr, binder, types, modifiers);
848                 }
849
850                 internal Type ResolveNestedType(TypeName typeName)
851                 {
852                         return FindNestedType(typeName) ?? Module.universe.GetMissingTypeOrThrow(Module, this, typeName);
853                 }
854
855                 // unlike the public API, this takes the namespace and name into account
856                 internal virtual Type FindNestedType(TypeName name)
857                 {
858                         foreach (Type type in __GetDeclaredTypes())
859                         {
860                                 if (type.__Namespace == name.Namespace && type.__Name == name.Name)
861                                 {
862                                         return type;
863                                 }
864                         }
865                         return null;
866                 }
867
868                 public Type GetNestedType(string name)
869                 {
870                         return GetNestedType(name, BindingFlags.Public);
871                 }
872
873                 public Type GetNestedType(string name, BindingFlags bindingAttr)
874                 {
875                         foreach (Type type in GetNestedTypes(bindingAttr))
876                         {
877                                 // FXBUG the namespace is ignored
878                                 if (type.__Name == name)
879                                 {
880                                         return type;
881                                 }
882                         }
883                         return null;
884                 }
885
886                 public Type[] GetNestedTypes()
887                 {
888                         return GetNestedTypes(BindingFlags.Public);
889                 }
890
891                 public Type[] GetNestedTypes(BindingFlags bindingAttr)
892                 {
893                         CheckBaked();
894                         List<Type> list = new List<Type>();
895                         foreach (Type type in __GetDeclaredTypes())
896                         {
897                                 if (BindingFlagsMatch(type.IsNestedPublic, bindingAttr, BindingFlags.Public, BindingFlags.NonPublic))
898                                 {
899                                         list.Add(type);
900                                 }
901                         }
902                         return list.ToArray();
903                 }
904
905                 public PropertyInfo[] GetProperties()
906                 {
907                         return GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
908                 }
909
910                 public PropertyInfo[] GetProperties(BindingFlags bindingAttr)
911                 {
912                         List<PropertyInfo> list = new List<PropertyInfo>();
913                         Type type = this;
914                         while (type != null)
915                         {
916                                 type.CheckBaked();
917                                 foreach (PropertyInfo property in type.__GetDeclaredProperties())
918                                 {
919                                         if (BindingFlagsMatch(property.IsPublic, bindingAttr, BindingFlags.Public, BindingFlags.NonPublic)
920                                                 && BindingFlagsMatch(property.IsStatic, bindingAttr, BindingFlags.Static, BindingFlags.Instance))
921                                         {
922                                                 list.Add(property);
923                                         }
924                                 }
925                                 if ((bindingAttr & BindingFlags.DeclaredOnly) == 0)
926                                 {
927                                         if ((bindingAttr & BindingFlags.FlattenHierarchy) == 0)
928                                         {
929                                                 bindingAttr &= ~BindingFlags.Static;
930                                         }
931                                         type = type.BaseType;
932                                 }
933                                 else
934                                 {
935                                         break;
936                                 }
937                         }
938                         return list.ToArray();
939                 }
940
941                 public PropertyInfo GetProperty(string name)
942                 {
943                         return GetProperty(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
944                 }
945
946                 public PropertyInfo GetProperty(string name, BindingFlags bindingAttr)
947                 {
948                         foreach (PropertyInfo prop in GetProperties(bindingAttr))
949                         {
950                                 if (prop.Name == name)
951                                 {
952                                         return prop;
953                                 }
954                         }
955                         return null;
956                 }
957
958                 public PropertyInfo GetProperty(string name, Type returnType)
959                 {
960                         PropertyInfo found = null;
961                         foreach (PropertyInfo prop in GetProperties())
962                         {
963                                 if (prop.Name == name && prop.PropertyType.Equals(returnType))
964                                 {
965                                         if (found != null)
966                                         {
967                                                 throw new AmbiguousMatchException();
968                                         }
969                                         found = prop;
970                                 }
971                         }
972                         return found;
973                 }
974
975                 public PropertyInfo GetProperty(string name, Type[] types)
976                 {
977                         PropertyInfo found = null;
978                         foreach (PropertyInfo prop in GetProperties())
979                         {
980                                 if (prop.Name == name && MatchParameterTypes(prop.GetIndexParameters(), types))
981                                 {
982                                         if (found != null)
983                                         {
984                                                 throw new AmbiguousMatchException();
985                                         }
986                                         found = prop;
987                                 }
988                         }
989                         return found;
990                 }
991
992                 private static bool MatchParameterTypes(ParameterInfo[] parameters, Type[] types)
993                 {
994                         if (parameters.Length == types.Length)
995                         {
996                                 for (int i = 0; i < parameters.Length; i++)
997                                 {
998                                         if (!parameters[i].ParameterType.Equals(types[i]))
999                                         {
1000                                                 return false;
1001                                         }
1002                                 }
1003                                 return true;
1004                         }
1005                         return false;
1006                 }
1007
1008                 public PropertyInfo GetProperty(string name, Type returnType, Type[] types)
1009                 {
1010                         return GetProperty(name, returnType, types, null);
1011                 }
1012
1013                 public PropertyInfo GetProperty(string name, Type returnType, Type[] types, ParameterModifier[] modifiers)
1014                 {
1015                         return GetProperty(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static, null, returnType, types, modifiers);
1016                 }
1017
1018                 public PropertyInfo GetProperty(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
1019                 {
1020                         PropertyInfo found = null;
1021                         foreach (PropertyInfo prop in GetProperties(bindingAttr))
1022                         {
1023                                 if (prop.Name == name && prop.PropertyType.Equals(returnType) && MatchParameterTypes(prop.GetIndexParameters(), types))
1024                                 {
1025                                         if (found != null)
1026                                         {
1027                                                 throw new AmbiguousMatchException();
1028                                         }
1029                                         found = prop;
1030                                 }
1031                         }
1032                         return found;
1033                 }
1034
1035                 public Type GetInterface(string name)
1036                 {
1037                         return GetInterface(name, false);
1038                 }
1039
1040                 public Type GetInterface(string name, bool ignoreCase)
1041                 {
1042                         if (ignoreCase)
1043                         {
1044                                 throw new NotImplementedException();
1045                         }
1046                         foreach (Type type in GetInterfaces())
1047                         {
1048                                 if (type.FullName == name)
1049                                 {
1050                                         return type;
1051                                 }
1052                         }
1053                         return null;
1054                 }
1055
1056                 public Type[] FindInterfaces(TypeFilter filter, object filterCriteria)
1057                 {
1058                         List<Type> list = new List<Type>();
1059                         foreach (Type type in GetInterfaces())
1060                         {
1061                                 if (filter(type, filterCriteria))
1062                                 {
1063                                         list.Add(type);
1064                                 }
1065                         }
1066                         return list.ToArray();
1067                 }
1068
1069                 public ConstructorInfo TypeInitializer
1070                 {
1071                         get { return GetConstructor(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); }
1072                 }
1073
1074                 public bool IsPrimitive
1075                 {
1076                         get
1077                         {
1078                                 Universe u = this.Universe;
1079                                 return this == u.System_Boolean
1080                                         || this == u.System_Byte
1081                                         || this == u.System_SByte
1082                                         || this == u.System_Int16
1083                                         || this == u.System_UInt16
1084                                         || this == u.System_Int32
1085                                         || this == u.System_UInt32
1086                                         || this == u.System_Int64
1087                                         || this == u.System_UInt64
1088                                         || this == u.System_IntPtr
1089                                         || this == u.System_UIntPtr
1090                                         || this == u.System_Char
1091                                         || this == u.System_Double
1092                                         || this == u.System_Single
1093                                         ;
1094                         }
1095                 }
1096
1097                 public bool IsEnum
1098                 {
1099                         get
1100                         {
1101                                 Type baseType = this.BaseType;
1102                                 return baseType != null
1103                                         && baseType.IsEnumOrValueType
1104                                         && baseType.__Name[0] == 'E';
1105                         }
1106                 }
1107
1108                 public bool IsSealed
1109                 {
1110                         get { return (Attributes & TypeAttributes.Sealed) != 0; }
1111                 }
1112
1113                 public bool IsAbstract
1114                 {
1115                         get { return (Attributes & TypeAttributes.Abstract) != 0; }
1116                 }
1117
1118                 private bool CheckVisibility(TypeAttributes access)
1119                 {
1120                         return (Attributes & TypeAttributes.VisibilityMask) == access;
1121                 }
1122
1123                 public bool IsPublic
1124                 {
1125                         get { return CheckVisibility(TypeAttributes.Public); }
1126                 }
1127
1128                 public bool IsNestedPublic
1129                 {
1130                         get { return CheckVisibility(TypeAttributes.NestedPublic); }
1131                 }
1132
1133                 public bool IsNestedPrivate
1134                 {
1135                         get { return CheckVisibility(TypeAttributes.NestedPrivate); }
1136                 }
1137
1138                 public bool IsNestedFamily
1139                 {
1140                         get { return CheckVisibility(TypeAttributes.NestedFamily); }
1141                 }
1142
1143                 public bool IsNestedAssembly
1144                 {
1145                         get { return CheckVisibility(TypeAttributes.NestedAssembly); }
1146                 }
1147
1148                 public bool IsNestedFamANDAssem
1149                 {
1150                         get { return CheckVisibility(TypeAttributes.NestedFamANDAssem); }
1151                 }
1152
1153                 public bool IsNestedFamORAssem
1154                 {
1155                         get { return CheckVisibility(TypeAttributes.NestedFamORAssem); }
1156                 }
1157
1158                 public bool IsNotPublic
1159                 {
1160                         get { return CheckVisibility(TypeAttributes.NotPublic); }
1161                 }
1162
1163                 public bool IsImport
1164                 {
1165                         get { return (Attributes & TypeAttributes.Import) != 0; }
1166                 }
1167
1168                 public bool IsCOMObject
1169                 {
1170                         get { return IsClass && IsImport; }
1171                 }
1172
1173                 public bool IsContextful
1174                 {
1175                         get { return IsSubclassOf(this.Module.universe.Import(typeof(ContextBoundObject))); }
1176                 }
1177
1178                 public bool IsMarshalByRef
1179                 {
1180                         get { return IsSubclassOf(this.Module.universe.Import(typeof(MarshalByRefObject))); }
1181                 }
1182
1183                 public virtual bool IsVisible
1184                 {
1185                         get { return IsPublic || (IsNestedPublic && this.DeclaringType.IsVisible); }
1186                 }
1187
1188                 public bool IsAnsiClass
1189                 {
1190                         get { return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AnsiClass; }
1191                 }
1192
1193                 public bool IsUnicodeClass
1194                 {
1195                         get { return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass; }
1196                 }
1197
1198                 public bool IsAutoClass
1199                 {
1200                         get { return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass; }
1201                 }
1202
1203                 public bool IsAutoLayout
1204                 {
1205                         get { return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout; }
1206                 }
1207
1208                 public bool IsLayoutSequential
1209                 {
1210                         get { return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout; }
1211                 }
1212
1213                 public bool IsExplicitLayout
1214                 {
1215                         get { return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout; }
1216                 }
1217
1218                 public bool IsSpecialName
1219                 {
1220                         get { return (Attributes & TypeAttributes.SpecialName) != 0; }
1221                 }
1222
1223                 public bool IsSerializable
1224                 {
1225                         get { return (Attributes & TypeAttributes.Serializable) != 0; }
1226                 }
1227
1228                 public bool IsClass
1229                 {
1230                         get { return !IsInterface && !IsValueType; }
1231                 }
1232
1233                 public bool IsInterface
1234                 {
1235                         get { return (Attributes & TypeAttributes.Interface) != 0; }
1236                 }
1237
1238                 public bool IsNested
1239                 {
1240                         // FXBUG we check the declaring type (like .NET) and this results
1241                         // in IsNested returning true for a generic type parameter
1242                         get { return this.DeclaringType != null; }
1243                 }
1244
1245                 public virtual bool __ContainsMissingType
1246                 {
1247                         get
1248                         {
1249                                 if (this.__IsMissing)
1250                                 {
1251                                         return true;
1252                                 }
1253                                 foreach (Type arg in this.GetGenericArguments())
1254                                 {
1255                                         if (arg.__ContainsMissingType)
1256                                         {
1257                                                 return true;
1258                                         }
1259                                 }
1260                                 return false;
1261                         }
1262                 }
1263
1264                 public Type MakeArrayType()
1265                 {
1266                         return ArrayType.Make(this, new CustomModifiers());
1267                 }
1268
1269                 public Type __MakeArrayType(CustomModifiers customModifiers)
1270                 {
1271                         return ArrayType.Make(this, customModifiers);
1272                 }
1273
1274                 [Obsolete("Please use __MakeArrayType(CustomModifiers) instead.")]
1275                 public Type __MakeArrayType(Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1276                 {
1277                         return __MakeArrayType(CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers));
1278                 }
1279
1280                 public Type MakeArrayType(int rank)
1281                 {
1282                         return __MakeArrayType(rank, new CustomModifiers());
1283                 }
1284
1285                 public Type __MakeArrayType(int rank, CustomModifiers customModifiers)
1286                 {
1287                         return MultiArrayType.Make(this, rank, Empty<int>.Array, new int[rank], customModifiers);
1288                 }
1289
1290                 [Obsolete("Please use __MakeArrayType(int, CustomModifiers) instead.")]
1291                 public Type __MakeArrayType(int rank, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1292                 {
1293                         return __MakeArrayType(rank, CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers));
1294                 }
1295
1296                 public Type __MakeArrayType(int rank, int[] sizes, int[] lobounds, CustomModifiers customModifiers)
1297                 {
1298                         return MultiArrayType.Make(this, rank, sizes ?? Empty<int>.Array, lobounds ?? Empty<int>.Array, customModifiers);
1299                 }
1300
1301                 [Obsolete("Please use __MakeArrayType(int, int[], int[], CustomModifiers) instead.")]
1302                 public Type __MakeArrayType(int rank, int[] sizes, int[] lobounds, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1303                 {
1304                         return __MakeArrayType(rank, sizes, lobounds, CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers));
1305                 }
1306
1307                 public Type MakeByRefType()
1308                 {
1309                         return ByRefType.Make(this, new CustomModifiers());
1310                 }
1311
1312                 public Type __MakeByRefType(CustomModifiers customModifiers)
1313                 {
1314                         return ByRefType.Make(this, customModifiers);
1315                 }
1316
1317                 [Obsolete("Please use __MakeByRefType(CustomModifiers) instead.")]
1318                 public Type __MakeByRefType(Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1319                 {
1320                         return __MakeByRefType(CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers));
1321                 }
1322
1323                 public Type MakePointerType()
1324                 {
1325                         return PointerType.Make(this, new CustomModifiers());
1326                 }
1327
1328                 public Type __MakePointerType(CustomModifiers customModifiers)
1329                 {
1330                         return PointerType.Make(this, customModifiers);
1331                 }
1332
1333                 [Obsolete("Please use __MakeByRefType(CustomModifiers) instead.")]
1334                 public Type __MakePointerType(Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1335                 {
1336                         return __MakePointerType(CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers));
1337                 }
1338
1339                 public Type MakeGenericType(params Type[] typeArguments)
1340                 {
1341                         return __MakeGenericType(typeArguments, null);
1342                 }
1343
1344                 public Type __MakeGenericType(Type[] typeArguments, CustomModifiers[] customModifiers)
1345                 {
1346                         if (!this.__IsMissing && !this.IsGenericTypeDefinition)
1347                         {
1348                                 throw new InvalidOperationException();
1349                         }
1350                         return GenericTypeInstance.Make(this, Util.Copy(typeArguments), customModifiers == null ? null : (CustomModifiers[])customModifiers.Clone());
1351                 }
1352
1353                 [Obsolete("Please use __MakeGenericType(Type[], CustomModifiers[]) instead.")]
1354                 public Type __MakeGenericType(Type[] typeArguments, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
1355                 {
1356                         if (!this.__IsMissing && !this.IsGenericTypeDefinition)
1357                         {
1358                                 throw new InvalidOperationException();
1359                         }
1360                         CustomModifiers[] mods = null;
1361                         if (requiredCustomModifiers != null || optionalCustomModifiers != null)
1362                         {
1363                                 mods = new CustomModifiers[typeArguments.Length];
1364                                 for (int i = 0; i < mods.Length; i++)
1365                                 {
1366                                         mods[i] = CustomModifiers.FromReqOpt(Util.NullSafeElementAt(requiredCustomModifiers, i), Util.NullSafeElementAt(optionalCustomModifiers, i));
1367                                 }
1368                         }
1369                         return GenericTypeInstance.Make(this, Util.Copy(typeArguments), mods);
1370                 }
1371
1372                 public static System.Type __GetSystemType(TypeCode typeCode)
1373                 {
1374                         switch (typeCode)
1375                         {
1376                                 case TypeCode.Boolean:
1377                                         return typeof(System.Boolean);
1378                                 case TypeCode.Byte:
1379                                         return typeof(System.Byte);
1380                                 case TypeCode.Char:
1381                                         return typeof(System.Char);
1382                                 case TypeCode.DBNull:
1383                                         return typeof(System.DBNull);
1384                                 case TypeCode.DateTime:
1385                                         return typeof(System.DateTime);
1386                                 case TypeCode.Decimal:
1387                                         return typeof(System.Decimal);
1388                                 case TypeCode.Double:
1389                                         return typeof(System.Double);
1390                                 case TypeCode.Empty:
1391                                         return null;
1392                                 case TypeCode.Int16:
1393                                         return typeof(System.Int16);
1394                                 case TypeCode.Int32:
1395                                         return typeof(System.Int32);
1396                                 case TypeCode.Int64:
1397                                         return typeof(System.Int64);
1398                                 case TypeCode.Object:
1399                                         return typeof(System.Object);
1400                                 case TypeCode.SByte:
1401                                         return typeof(System.SByte);
1402                                 case TypeCode.Single:
1403                                         return typeof(System.Single);
1404                                 case TypeCode.String:
1405                                         return typeof(System.String);
1406                                 case TypeCode.UInt16:
1407                                         return typeof(System.UInt16);
1408                                 case TypeCode.UInt32:
1409                                         return typeof(System.UInt32);
1410                                 case TypeCode.UInt64:
1411                                         return typeof(System.UInt64);
1412                                 default:
1413                                         throw new ArgumentOutOfRangeException();
1414                         }
1415                 }
1416
1417                 public static TypeCode GetTypeCode(Type type)
1418                 {
1419                         if (type == null)
1420                         {
1421                                 return TypeCode.Empty;
1422                         }
1423                         if (!type.__IsMissing && type.IsEnum)
1424                         {
1425                                 type = type.GetEnumUnderlyingType();
1426                         }
1427                         Universe u = type.Module.universe;
1428                         if (type == u.System_Boolean)
1429                         {
1430                                 return TypeCode.Boolean;
1431                         }
1432                         else if (type == u.System_Char)
1433                         {
1434                                 return TypeCode.Char;
1435                         }
1436                         else if (type == u.System_SByte)
1437                         {
1438                                 return TypeCode.SByte;
1439                         }
1440                         else if (type == u.System_Byte)
1441                         {
1442                                 return TypeCode.Byte;
1443                         }
1444                         else if (type == u.System_Int16)
1445                         {
1446                                 return TypeCode.Int16;
1447                         }
1448                         else if (type == u.System_UInt16)
1449                         {
1450                                 return TypeCode.UInt16;
1451                         }
1452                         else if (type == u.System_Int32)
1453                         {
1454                                 return TypeCode.Int32;
1455                         }
1456                         else if (type == u.System_UInt32)
1457                         {
1458                                 return TypeCode.UInt32;
1459                         }
1460                         else if (type == u.System_Int64)
1461                         {
1462                                 return TypeCode.Int64;
1463                         }
1464                         else if (type == u.System_UInt64)
1465                         {
1466                                 return TypeCode.UInt64;
1467                         }
1468                         else if (type == u.System_Single)
1469                         {
1470                                 return TypeCode.Single;
1471                         }
1472                         else if (type == u.System_Double)
1473                         {
1474                                 return TypeCode.Double;
1475                         }
1476                         else if (type == u.System_DateTime)
1477                         {
1478                                 return TypeCode.DateTime;
1479                         }
1480                         else if (type == u.System_DBNull)
1481                         {
1482                                 return TypeCode.DBNull;
1483                         }
1484                         else if (type == u.System_Decimal)
1485                         {
1486                                 return TypeCode.Decimal;
1487                         }
1488                         else if (type == u.System_String)
1489                         {
1490                                 return TypeCode.String;
1491                         }
1492                         else if (type.__IsMissing)
1493                         {
1494                                 throw new MissingMemberException(type);
1495                         }
1496                         else
1497                         {
1498                                 return TypeCode.Object;
1499                         }
1500                 }
1501
1502                 public Assembly Assembly
1503                 {
1504                         get { return Module.Assembly; }
1505                 }
1506
1507                 // note that interface/delegate co- and contravariance is not considered
1508                 public bool IsAssignableFrom(Type type)
1509                 {
1510                         if (this.Equals(type))
1511                         {
1512                                 return true;
1513                         }
1514                         else if (type == null)
1515                         {
1516                                 return false;
1517                         }
1518                         else if (this.IsArray && type.IsArray)
1519                         {
1520                                 if (this.GetArrayRank() != type.GetArrayRank())
1521                                 {
1522                                         return false;
1523                                 }
1524                                 else if (this.__IsVector && !type.__IsVector)
1525                                 {
1526                                         return false;
1527                                 }
1528                                 Type e1 = this.GetElementType();
1529                                 Type e2 = type.GetElementType();
1530                                 return e1.IsValueType == e2.IsValueType && e1.IsAssignableFrom(e2);
1531                         }
1532                         else if (this.IsSealed)
1533                         {
1534                                 return false;
1535                         }
1536                         else if (this.IsInterface)
1537                         {
1538                                 return Array.IndexOf(type.GetInterfaces(), this) != -1;
1539                         }
1540                         else if (type.IsInterface)
1541                         {
1542                                 return this == this.Module.universe.System_Object;
1543                         }
1544                         else if (type.IsPointer)
1545                         {
1546                                 return this == this.Module.universe.System_Object || this == this.Module.universe.System_ValueType;
1547                         }
1548                         else
1549                         {
1550                                 return type.IsSubclassOf(this);
1551                         }
1552                 }
1553
1554                 public bool IsSubclassOf(Type type)
1555                 {
1556                         Type thisType = this.BaseType;
1557                         while (thisType != null)
1558                         {
1559                                 if (thisType.Equals(type))
1560                                 {
1561                                         return true;
1562                                 }
1563                                 thisType = thisType.BaseType;
1564                         }
1565                         return false;
1566                 }
1567
1568                 // This returns true if this type directly (i.e. not inherited from the base class) implements the interface.
1569                 // Note that a complicating factor is that the interface itself can be implemented by an interface that extends it.
1570                 private bool IsDirectlyImplementedInterface(Type interfaceType)
1571                 {
1572                         foreach (Type iface in __GetDeclaredInterfaces())
1573                         {
1574                                 if (interfaceType.IsAssignableFrom(iface))
1575                                 {
1576                                         return true;
1577                                 }
1578                         }
1579                         return false;
1580                 }
1581
1582                 public InterfaceMapping GetInterfaceMap(Type interfaceType)
1583                 {
1584                         CheckBaked();
1585                         InterfaceMapping map = new InterfaceMapping();
1586                         if (!IsDirectlyImplementedInterface(interfaceType))
1587                         {
1588                                 Type baseType = this.BaseType;
1589                                 if (baseType == null)
1590                                 {
1591                                         throw new ArgumentException();
1592                                 }
1593                                 else
1594                                 {
1595                                         map = baseType.GetInterfaceMap(interfaceType);
1596                                 }
1597                         }
1598                         else
1599                         {
1600                                 map.InterfaceMethods = interfaceType.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
1601                                 map.InterfaceType = interfaceType;
1602                                 map.TargetMethods = new MethodInfo[map.InterfaceMethods.Length];
1603                                 FillInExplicitInterfaceMethods(map.InterfaceMethods, map.TargetMethods);
1604                                 MethodInfo[] methods = GetMethods(BindingFlags.Instance | BindingFlags.Public);
1605                                 for (int i = 0; i < map.TargetMethods.Length; i++)
1606                                 {
1607                                         if (map.TargetMethods[i] == null)
1608                                         {
1609                                                 // TODO use proper method resolution (also take into account that no implicit base class implementation is used across assembly boundaries)
1610                                                 for (int j = 0; j < methods.Length; j++)
1611                                                 {
1612                                                         if (methods[j].Name == map.InterfaceMethods[i].Name
1613                                                                 && methods[j].MethodSignature.Equals(map.InterfaceMethods[i].MethodSignature))
1614                                                         {
1615                                                                 map.TargetMethods[i] = methods[j];
1616                                                         }
1617                                                 }
1618                                         }
1619                                 }
1620                                 for (Type baseType = this.BaseType; baseType != null && interfaceType.IsAssignableFrom(baseType); baseType = baseType.BaseType)
1621                                 {
1622                                         baseType.FillInExplicitInterfaceMethods(map.InterfaceMethods, map.TargetMethods);
1623                                 }
1624                         }
1625                         map.TargetType = this;
1626                         return map;
1627                 }
1628
1629                 internal void FillInExplicitInterfaceMethods(MethodInfo[] interfaceMethods, MethodInfo[] targetMethods)
1630                 {
1631                         __MethodImplMap impl = __GetMethodImplMap();
1632                         for (int i = 0; i < impl.MethodDeclarations.Length; i++)
1633                         {
1634                                 for (int j = 0; j < impl.MethodDeclarations[i].Length; j++)
1635                                 {
1636                                         int index = Array.IndexOf(interfaceMethods, impl.MethodDeclarations[i][j]);
1637                                         if (index != -1 && targetMethods[index] == null)
1638                                         {
1639                                                 targetMethods[index] = impl.MethodBodies[i];
1640                                         }
1641                                 }
1642                         }
1643                 }
1644
1645                 Type IGenericContext.GetGenericTypeArgument(int index)
1646                 {
1647                         return GetGenericTypeArgument(index);
1648                 }
1649
1650                 Type IGenericContext.GetGenericMethodArgument(int index)
1651                 {
1652                         throw new BadImageFormatException();
1653                 }
1654
1655                 Type IGenericBinder.BindTypeParameter(Type type)
1656                 {
1657                         return GetGenericTypeArgument(type.GenericParameterPosition);
1658                 }
1659
1660                 Type IGenericBinder.BindMethodParameter(Type type)
1661                 {
1662                         throw new BadImageFormatException();
1663                 }
1664
1665                 internal virtual Type BindTypeParameters(IGenericBinder binder)
1666                 {
1667                         if (IsGenericTypeDefinition)
1668                         {
1669                                 Type[] args = GetGenericArguments();
1670                                 Type.InplaceBindTypeParameters(binder, args);
1671                                 return GenericTypeInstance.Make(this, args, null);
1672                         }
1673                         else
1674                         {
1675                                 return this;
1676                         }
1677                 }
1678
1679                 private static void InplaceBindTypeParameters(IGenericBinder binder, Type[] types)
1680                 {
1681                         for (int i = 0; i < types.Length; i++)
1682                         {
1683                                 types[i] = types[i].BindTypeParameters(binder);
1684                         }
1685                 }
1686
1687                 internal virtual MethodBase FindMethod(string name, MethodSignature signature)
1688                 {
1689                         foreach (MethodBase method in __GetDeclaredMethods())
1690                         {
1691                                 if (method.Name == name && method.MethodSignature.Equals(signature))
1692                                 {
1693                                         return method;
1694                                 }
1695                         }
1696                         return null;
1697                 }
1698
1699                 internal virtual FieldInfo FindField(string name, FieldSignature signature)
1700                 {
1701                         foreach (FieldInfo field in __GetDeclaredFields())
1702                         {
1703                                 if (field.Name == name && field.FieldSignature.Equals(signature))
1704                                 {
1705                                         return field;
1706                                 }
1707                         }
1708                         return null;
1709                 }
1710
1711                 internal bool IsAllowMultipleCustomAttribute
1712                 {
1713                         get
1714                         {
1715                                 IList<CustomAttributeData> cad = GetCustomAttributesData(this.Module.universe.System_AttributeUsageAttribute);
1716                                 if (cad.Count == 1)
1717                                 {
1718                                         foreach (CustomAttributeNamedArgument arg in cad[0].NamedArguments)
1719                                         {
1720                                                 if (arg.MemberInfo.Name == "AllowMultiple")
1721                                                 {
1722                                                         return (bool)arg.TypedValue.Value;
1723                                                 }
1724                                         }
1725                                 }
1726                                 return false;
1727                         }
1728                 }
1729
1730                 internal bool IsPseudoCustomAttribute
1731                 {
1732                         get
1733                         {
1734                                 Universe u = this.Module.universe;
1735                                 return this == u.System_NonSerializedAttribute
1736                                         || this == u.System_SerializableAttribute
1737                                         || this == u.System_Runtime_InteropServices_DllImportAttribute
1738                                         || this == u.System_Runtime_InteropServices_FieldOffsetAttribute
1739                                         || this == u.System_Runtime_InteropServices_InAttribute
1740                                         || this == u.System_Runtime_InteropServices_MarshalAsAttribute
1741                                         || this == u.System_Runtime_InteropServices_OutAttribute
1742                                         || this == u.System_Runtime_InteropServices_StructLayoutAttribute
1743                                         || this == u.System_Runtime_InteropServices_OptionalAttribute
1744                                         || this == u.System_Runtime_InteropServices_PreserveSigAttribute
1745                                         || this == u.System_Runtime_InteropServices_ComImportAttribute
1746                                         || this == u.System_Runtime_CompilerServices_SpecialNameAttribute
1747                                         || this == u.System_Runtime_CompilerServices_MethodImplAttribute
1748                                         ;
1749                         }
1750                 }
1751
1752                 internal Type MarkNotValueType()
1753                 {
1754                         typeFlags |= TypeFlags.NotValueType;
1755                         return this;
1756                 }
1757
1758                 internal Type MarkValueType()
1759                 {
1760                         typeFlags |= TypeFlags.ValueType;
1761                         return this;
1762                 }
1763
1764                 internal ConstructorInfo GetPseudoCustomAttributeConstructor(params Type[] parameterTypes)
1765                 {
1766                         Universe u = this.Module.universe;
1767                         MethodSignature methodSig = MethodSignature.MakeFromBuilder(u.System_Void, parameterTypes, new PackedCustomModifiers(), CallingConventions.Standard | CallingConventions.HasThis, 0);
1768                         MethodBase mb =
1769                                 FindMethod(".ctor", methodSig) ??
1770                                 u.GetMissingMethodOrThrow(this, ".ctor", methodSig);
1771                         return (ConstructorInfo)mb;
1772                 }
1773
1774                 public MethodBase __CreateMissingMethod(string name, CallingConventions callingConvention, Type returnType, CustomModifiers returnTypeCustomModifiers, Type[] parameterTypes, CustomModifiers[] parameterTypeCustomModifiers)
1775                 {
1776                         return CreateMissingMethod(name, callingConvention, returnType, parameterTypes, PackedCustomModifiers.CreateFromExternal(returnTypeCustomModifiers, parameterTypeCustomModifiers, parameterTypes.Length));
1777                 }
1778
1779                 private MethodBase CreateMissingMethod(string name, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, PackedCustomModifiers customModifiers)
1780                 {
1781                         MethodSignature sig = new MethodSignature(
1782                                 returnType ?? this.Module.universe.System_Void,
1783                                 Util.Copy(parameterTypes),
1784                                 customModifiers,
1785                                 callingConvention,
1786                                 0);
1787                         MethodInfo method = new MissingMethod(this, name, sig);
1788                         if (name == ".ctor" || name == ".cctor")
1789                         {
1790                                 return new ConstructorInfoImpl(method);
1791                         }
1792                         return method;
1793                 }
1794
1795                 [Obsolete("Please use __CreateMissingMethod(string, CallingConventions, Type, CustomModifiers, Type[], CustomModifiers[]) instead")]
1796                 public MethodBase __CreateMissingMethod(string name, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
1797                 {
1798                         return CreateMissingMethod(name, callingConvention, returnType, parameterTypes, PackedCustomModifiers.CreateFromExternal(returnTypeOptionalCustomModifiers, returnTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers, parameterTypeRequiredCustomModifiers, parameterTypes.Length));
1799                 }
1800
1801                 public FieldInfo __CreateMissingField(string name, Type fieldType, CustomModifiers customModifiers)
1802                 {
1803                         return new MissingField(this, name, FieldSignature.Create(fieldType, customModifiers));
1804                 }
1805
1806                 [Obsolete("Please use __CreateMissingField(string, Type, CustomModifiers) instead")]
1807                 public FieldInfo __CreateMissingField(string name, Type fieldType, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
1808                 {
1809                         return __CreateMissingField(name, fieldType, CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers));
1810                 }
1811
1812                 internal virtual Type SetMetadataTokenForMissing(int token)
1813                 {
1814                         return this;
1815                 }
1816
1817                 protected void MarkEnumOrValueType(string typeNamespace, string typeName)
1818                 {
1819                         // we assume that mscorlib won't have nested types with these names,
1820                         // so we don't check that we're not a nested type
1821                         if (typeNamespace == "System"
1822                                 && (typeName == "Enum" || typeName == "ValueType"))
1823                         {
1824                                 typeFlags |= TypeFlags.PotentialEnumOrValueType;
1825                         }
1826                 }
1827
1828                 private bool ResolvePotentialEnumOrValueType()
1829                 {
1830                         if (this.Assembly == this.Universe.Mscorlib || this.Assembly.GetName().Name.Equals("mscorlib", StringComparison.OrdinalIgnoreCase))
1831                         {
1832                                 typeFlags = (typeFlags & ~TypeFlags.PotentialEnumOrValueType) | TypeFlags.EnumOrValueType;
1833                                 return true;
1834                         }
1835                         else
1836                         {
1837                                 typeFlags &= ~TypeFlags.PotentialEnumOrValueType;
1838                                 return false;
1839                         }
1840                 }
1841
1842                 private bool IsEnumOrValueType
1843                 {
1844                         get
1845                         {
1846                                 return (typeFlags & (TypeFlags.EnumOrValueType | TypeFlags.PotentialEnumOrValueType)) != 0
1847                                         && ((typeFlags & TypeFlags.EnumOrValueType) != 0 || ResolvePotentialEnumOrValueType());
1848                         }
1849                 }
1850
1851                 internal virtual IList<CustomAttributeData> GetInterfaceImplCustomAttributes(Type interfaceType, Type attributeType)
1852                 {
1853                         throw new NotSupportedException();
1854                 }
1855
1856                 internal virtual Universe Universe
1857                 {
1858                         get { return Module.universe; }
1859                 }
1860         }
1861
1862         abstract class ElementHolderType : Type
1863         {
1864                 protected readonly Type elementType;
1865                 private int token;
1866                 private readonly CustomModifiers mods;
1867
1868                 protected ElementHolderType(Type elementType, CustomModifiers mods)
1869                 {
1870                         this.elementType = elementType;
1871                         this.mods = mods;
1872                 }
1873
1874                 protected bool EqualsHelper(ElementHolderType other)
1875                 {
1876                         return other != null
1877                                 && other.elementType.Equals(elementType)
1878                                 && other.mods.Equals(mods);
1879                 }
1880
1881                 public override CustomModifiers __GetCustomModifiers()
1882                 {
1883                         return mods;
1884                 }
1885
1886                 public sealed override string Name
1887                 {
1888                         get { return elementType.Name + GetSuffix(); }
1889                 }
1890
1891                 public sealed override string Namespace
1892                 {
1893                         get { return elementType.Namespace; }
1894                 }
1895
1896                 public sealed override string FullName
1897                 {
1898                         get { return elementType.FullName + GetSuffix(); }
1899                 }
1900
1901                 public sealed override string ToString()
1902                 {
1903                         return elementType.ToString() + GetSuffix();
1904                 }
1905
1906                 public sealed override Type GetElementType()
1907                 {
1908                         return elementType;
1909                 }
1910
1911                 public sealed override bool HasElementType
1912                 {
1913                         get { return true; }
1914                 }
1915
1916                 public sealed override Module Module
1917                 {
1918                         get { return elementType.Module; }
1919                 }
1920
1921                 internal sealed override int GetModuleBuilderToken()
1922                 {
1923                         if (token == 0)
1924                         {
1925                                 token = ((ModuleBuilder)elementType.Module).ImportType(this);
1926                         }
1927                         return token;
1928                 }
1929
1930                 public sealed override bool ContainsGenericParameters
1931                 {
1932                         get
1933                         {
1934                                 Type type = elementType;
1935                                 while (type.HasElementType)
1936                                 {
1937                                         type = type.GetElementType();
1938                                 }
1939                                 return type.ContainsGenericParameters;
1940                         }
1941                 }
1942
1943                 public sealed override bool __ContainsMissingType
1944                 {
1945                         get
1946                         {
1947                                 Type type = elementType;
1948                                 while (type.HasElementType)
1949                                 {
1950                                         type = type.GetElementType();
1951                                 }
1952                                 return type.__ContainsMissingType;
1953                         }
1954                 }
1955
1956                 internal sealed override Type BindTypeParameters(IGenericBinder binder)
1957                 {
1958                         Type type = elementType.BindTypeParameters(binder);
1959                         CustomModifiers mods = this.mods.Bind(binder);
1960                         if (ReferenceEquals(type, elementType)
1961                                 && mods.Equals(this.mods))
1962                         {
1963                                 return this;
1964                         }
1965                         return Wrap(type, mods);
1966                 }
1967
1968                 internal override void CheckBaked()
1969                 {
1970                         elementType.CheckBaked();
1971                 }
1972
1973                 internal sealed override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
1974                 {
1975                         return CustomAttributeData.EmptyList;
1976                 }
1977
1978                 internal sealed override Universe Universe
1979                 {
1980                         get { return elementType.Universe; }
1981                 }
1982
1983                 internal abstract string GetSuffix();
1984
1985                 protected abstract Type Wrap(Type type, CustomModifiers mods);
1986         }
1987
1988         sealed class ArrayType : ElementHolderType
1989         {
1990                 internal static Type Make(Type type, CustomModifiers mods)
1991                 {
1992                         return type.Universe.CanonicalizeType(new ArrayType(type, mods));
1993                 }
1994
1995                 private ArrayType(Type type, CustomModifiers mods)
1996                         : base(type, mods)
1997                 {
1998                 }
1999
2000                 public override Type BaseType
2001                 {
2002                         get { return elementType.Module.universe.System_Array; }
2003                 }
2004
2005                 public override Type[] __GetDeclaredInterfaces()
2006                 {
2007                         return new Type[] {
2008                                 this.Module.universe.Import(typeof(IList<>)).MakeGenericType(elementType),
2009                                 this.Module.universe.Import(typeof(ICollection<>)).MakeGenericType(elementType),
2010                                 this.Module.universe.Import(typeof(IEnumerable<>)).MakeGenericType(elementType)
2011                         };
2012                 }
2013
2014                 public override MethodBase[] __GetDeclaredMethods()
2015                 {
2016                         Type[] int32 = new Type[] { this.Module.universe.System_Int32 };
2017                         List<MethodBase> list = new List<MethodBase>();
2018                         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 }));
2019                         list.Add(new BuiltinArrayMethod(this.Module, this, "Address", CallingConventions.Standard | CallingConventions.HasThis, elementType.MakeByRefType(), int32));
2020                         list.Add(new BuiltinArrayMethod(this.Module, this, "Get", CallingConventions.Standard | CallingConventions.HasThis, elementType, int32));
2021                         list.Add(new ConstructorInfoImpl(new BuiltinArrayMethod(this.Module, this, ".ctor", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, int32)));
2022                         for (Type type = elementType; type.__IsVector; type = type.GetElementType())
2023                         {
2024                                 Array.Resize(ref int32, int32.Length + 1);
2025                                 int32[int32.Length - 1] = int32[0];
2026                                 list.Add(new ConstructorInfoImpl(new BuiltinArrayMethod(this.Module, this, ".ctor", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, int32)));
2027                         }
2028                         return list.ToArray();
2029                 }
2030
2031                 public override TypeAttributes Attributes
2032                 {
2033                         get { return TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Serializable; }
2034                 }
2035
2036                 public override bool IsArray
2037                 {
2038                         get { return true; }
2039                 }
2040
2041                 public override bool __IsVector
2042                 {
2043                         get { return true; }
2044                 }
2045
2046                 public override int GetArrayRank()
2047                 {
2048                         return 1;
2049                 }
2050
2051                 public override bool Equals(object o)
2052                 {
2053                         return EqualsHelper(o as ArrayType);
2054                 }
2055
2056                 public override int GetHashCode()
2057                 {
2058                         return elementType.GetHashCode() * 5;
2059                 }
2060
2061                 internal override string GetSuffix()
2062                 {
2063                         return "[]";
2064                 }
2065
2066                 protected override Type Wrap(Type type, CustomModifiers mods)
2067                 {
2068                         return Make(type, mods);
2069                 }
2070         }
2071
2072         sealed class MultiArrayType : ElementHolderType
2073         {
2074                 private readonly int rank;
2075                 private readonly int[] sizes;
2076                 private readonly int[] lobounds;
2077
2078                 internal static Type Make(Type type, int rank, int[] sizes, int[] lobounds, CustomModifiers mods)
2079                 {
2080                         return type.Universe.CanonicalizeType(new MultiArrayType(type, rank, sizes, lobounds, mods));
2081                 }
2082
2083                 private MultiArrayType(Type type, int rank, int[] sizes, int[] lobounds, CustomModifiers mods)
2084                         : base(type, mods)
2085                 {
2086                         this.rank = rank;
2087                         this.sizes = sizes;
2088                         this.lobounds = lobounds;
2089                 }
2090
2091                 public override Type BaseType
2092                 {
2093                         get { return elementType.Module.universe.System_Array; }
2094                 }
2095
2096                 public override MethodBase[] __GetDeclaredMethods()
2097                 {
2098                         Type int32 = this.Module.universe.System_Int32;
2099                         Type[] setArgs = new Type[rank + 1];
2100                         Type[] getArgs = new Type[rank];
2101                         Type[] ctorArgs = new Type[rank * 2];
2102                         for (int i = 0; i < rank; i++)
2103                         {
2104                                 setArgs[i] = int32;
2105                                 getArgs[i] = int32;
2106                                 ctorArgs[i * 2 + 0] = int32;
2107                                 ctorArgs[i * 2 + 1] = int32;
2108                         }
2109                         setArgs[rank] = elementType;
2110                         return new MethodBase[] {
2111                                 new ConstructorInfoImpl(new BuiltinArrayMethod(this.Module, this, ".ctor", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, getArgs)),
2112                                 new ConstructorInfoImpl(new BuiltinArrayMethod(this.Module, this, ".ctor", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, ctorArgs)),
2113                                 new BuiltinArrayMethod(this.Module, this, "Set", CallingConventions.Standard | CallingConventions.HasThis, this.Module.universe.System_Void, setArgs),
2114                                 new BuiltinArrayMethod(this.Module, this, "Address", CallingConventions.Standard | CallingConventions.HasThis, elementType.MakeByRefType(), getArgs),
2115                                 new BuiltinArrayMethod(this.Module, this, "Get", CallingConventions.Standard | CallingConventions.HasThis, elementType, getArgs),
2116                         };
2117                 }
2118
2119                 public override TypeAttributes Attributes
2120                 {
2121                         get { return TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Serializable; }
2122                 }
2123
2124                 public override bool IsArray
2125                 {
2126                         get { return true; }
2127                 }
2128
2129                 public override int GetArrayRank()
2130                 {
2131                         return rank;
2132                 }
2133
2134                 public override int[] __GetArraySizes()
2135                 {
2136                         return Util.Copy(sizes);
2137                 }
2138
2139                 public override int[] __GetArrayLowerBounds()
2140                 {
2141                         return Util.Copy(lobounds);
2142                 }
2143
2144                 public override bool Equals(object o)
2145                 {
2146                         MultiArrayType at = o as MultiArrayType;
2147                         return EqualsHelper(at)
2148                                 && at.rank == rank
2149                                 && ArrayEquals(at.sizes, sizes)
2150                                 && ArrayEquals(at.lobounds, lobounds);
2151                 }
2152
2153                 private static bool ArrayEquals(int[] i1, int[] i2)
2154                 {
2155                         if (i1.Length == i2.Length)
2156                         {
2157                                 for (int i = 0; i < i1.Length; i++)
2158                                 {
2159                                         if (i1[i] != i2[i])
2160                                         {
2161                                                 return false;
2162                                         }
2163                                 }
2164                                 return true;
2165                         }
2166                         return false;
2167                 }
2168
2169                 public override int GetHashCode()
2170                 {
2171                         return elementType.GetHashCode() * 9 + rank;
2172                 }
2173
2174                 internal override string GetSuffix()
2175                 {
2176                         if (rank == 1)
2177                         {
2178                                 return "[*]";
2179                         }
2180                         else
2181                         {
2182                                 return "[" + new String(',', rank - 1) + "]";
2183                         }
2184                 }
2185
2186                 protected override Type Wrap(Type type, CustomModifiers mods)
2187                 {
2188                         return Make(type, rank, sizes, lobounds, mods);
2189                 }
2190         }
2191
2192         sealed class BuiltinArrayMethod : ArrayMethod
2193         {
2194                 internal BuiltinArrayMethod(Module module, Type arrayClass, string methodName, CallingConventions callingConvention, Type returnType, Type[] parameterTypes)
2195                         : base(module, arrayClass, methodName, callingConvention, returnType, parameterTypes)
2196                 {
2197                 }
2198
2199                 public override MethodAttributes Attributes
2200                 {
2201                         get { return this.Name == ".ctor" ? MethodAttributes.RTSpecialName | MethodAttributes.Public : MethodAttributes.Public; }
2202                 }
2203
2204                 public override MethodImplAttributes GetMethodImplementationFlags()
2205                 {
2206                         return MethodImplAttributes.IL;
2207                 }
2208
2209                 public override int MetadataToken
2210                 {
2211                         get { return 0x06000000; }
2212                 }
2213
2214                 public override MethodBody GetMethodBody()
2215                 {
2216                         return null;
2217                 }
2218
2219                 public override ParameterInfo[] GetParameters()
2220                 {
2221                         ParameterInfo[] parameterInfos = new ParameterInfo[parameterTypes.Length];
2222                         for (int i = 0; i < parameterInfos.Length; i++)
2223                         {
2224                                 parameterInfos[i] = new ParameterInfoImpl(this, parameterTypes[i], i);
2225                         }
2226                         return parameterInfos;
2227                 }
2228
2229                 public override ParameterInfo ReturnParameter
2230                 {
2231                         get { return new ParameterInfoImpl(this, this.ReturnType, -1); }
2232                 }
2233
2234                 private sealed class ParameterInfoImpl : ParameterInfo
2235                 {
2236                         private readonly MethodInfo method;
2237                         private readonly Type type;
2238                         private readonly int pos;
2239
2240                         internal ParameterInfoImpl(MethodInfo method, Type type, int pos)
2241                         {
2242                                 this.method = method;
2243                                 this.type = type;
2244                                 this.pos = pos;
2245                         }
2246
2247                         public override Type ParameterType
2248                         {
2249                                 get { return type; }
2250                         }
2251
2252                         public override string Name
2253                         {
2254                                 get { return null; }
2255                         }
2256
2257                         public override ParameterAttributes Attributes
2258                         {
2259                                 get { return ParameterAttributes.None; }
2260                         }
2261
2262                         public override int Position
2263                         {
2264                                 get { return pos; }
2265                         }
2266
2267                         public override object RawDefaultValue
2268                         {
2269                                 get { return null; }
2270                         }
2271
2272                         public override CustomModifiers __GetCustomModifiers()
2273                         {
2274                                 return new CustomModifiers();
2275                         }
2276
2277                         public override MemberInfo Member
2278                         {
2279                                 get { return method.IsConstructor ? (MethodBase)new ConstructorInfoImpl(method) : method; }
2280                         }
2281
2282                         public override int MetadataToken
2283                         {
2284                                 get { return 0x8000000; }
2285                         }
2286
2287                         internal override Module Module
2288                         {
2289                                 get { return method.Module; }
2290                         }
2291                 }
2292         }
2293
2294         sealed class ByRefType : ElementHolderType
2295         {
2296                 internal static Type Make(Type type, CustomModifiers mods)
2297                 {
2298                         return type.Universe.CanonicalizeType(new ByRefType(type, mods));
2299                 }
2300
2301                 private ByRefType(Type type, CustomModifiers mods)
2302                         : base(type, mods)
2303                 {
2304                 }
2305
2306                 public override bool Equals(object o)
2307                 {
2308                         return EqualsHelper(o as ByRefType);
2309                 }
2310
2311                 public override int GetHashCode()
2312                 {
2313                         return elementType.GetHashCode() * 3;
2314                 }
2315
2316                 public override Type BaseType
2317                 {
2318                         get { return null; }
2319                 }
2320
2321                 public override TypeAttributes Attributes
2322                 {
2323                         get { return 0; }
2324                 }
2325
2326                 public override bool IsByRef
2327                 {
2328                         get { return true; }
2329                 }
2330
2331                 internal override string GetSuffix()
2332                 {
2333                         return "&";
2334                 }
2335
2336                 protected override Type Wrap(Type type, CustomModifiers mods)
2337                 {
2338                         return Make(type, mods);
2339                 }
2340         }
2341
2342         sealed class PointerType : ElementHolderType
2343         {
2344                 internal static Type Make(Type type, CustomModifiers mods)
2345                 {
2346                         return type.Universe.CanonicalizeType(new PointerType(type, mods));
2347                 }
2348
2349                 private PointerType(Type type, CustomModifiers mods)
2350                         : base(type, mods)
2351                 {
2352                 }
2353
2354                 public override bool Equals(object o)
2355                 {
2356                         return EqualsHelper(o as PointerType);
2357                 }
2358
2359                 public override int GetHashCode()
2360                 {
2361                         return elementType.GetHashCode() * 7;
2362                 }
2363
2364                 public override Type BaseType
2365                 {
2366                         get { return null; }
2367                 }
2368
2369                 public override TypeAttributes Attributes
2370                 {
2371                         get { return 0; }
2372                 }
2373
2374                 public override bool IsPointer
2375                 {
2376                         get { return true; }
2377                 }
2378
2379                 internal override string GetSuffix()
2380                 {
2381                         return "*";
2382                 }
2383
2384                 protected override Type Wrap(Type type, CustomModifiers mods)
2385                 {
2386                         return Make(type, mods);
2387                 }
2388         }
2389
2390         sealed class GenericTypeInstance : Type
2391         {
2392                 private readonly Type type;
2393                 private readonly Type[] args;
2394                 private readonly CustomModifiers[] mods;
2395                 private Type baseType;
2396                 private int token;
2397
2398                 internal static Type Make(Type type, Type[] typeArguments, CustomModifiers[] mods)
2399                 {
2400                         bool identity = true;
2401                         if (type is TypeBuilder || type is BakedType || type.__IsMissing)
2402                         {
2403                                 // a TypeBuiler identity must be instantiated
2404                                 identity = false;
2405                         }
2406                         else
2407                         {
2408                                 // we must not instantiate the identity instance, because typeof(Foo<>).MakeGenericType(typeof(Foo<>).GetGenericArguments()) == typeof(Foo<>)
2409                                 for (int i = 0; i < typeArguments.Length; i++)
2410                                 {
2411                                         if (typeArguments[i] != type.GetGenericTypeArgument(i)
2412                                                 || !IsEmpty(mods, i))
2413                                         {
2414                                                 identity = false;
2415                                                 break;
2416                                         }
2417                                 }
2418                         }
2419                         if (identity)
2420                         {
2421                                 return type;
2422                         }
2423                         else
2424                         {
2425                                 return type.Universe.CanonicalizeType(new GenericTypeInstance(type, typeArguments, mods));
2426                         }
2427                 }
2428
2429                 private static bool IsEmpty(CustomModifiers[] mods, int i)
2430                 {
2431                         // we need to be extra careful, because mods doesn't not need to be in canonical format
2432                         // (Signature.ReadGenericInst() calls Make() directly, without copying the modifier arrays)
2433                         return mods == null || mods[i].IsEmpty;
2434                 }
2435
2436                 private GenericTypeInstance(Type type, Type[] args, CustomModifiers[] mods)
2437                 {
2438                         this.type = type;
2439                         this.args = args;
2440                         this.mods = mods;
2441                 }
2442
2443                 public override bool Equals(object o)
2444                 {
2445                         GenericTypeInstance gt = o as GenericTypeInstance;
2446                         return gt != null && gt.type.Equals(type) && Util.ArrayEquals(gt.args, args)
2447                                 && Util.ArrayEquals(gt.mods, mods);
2448                 }
2449
2450                 public override int GetHashCode()
2451                 {
2452                         return type.GetHashCode() * 3 ^ Util.GetHashCode(args);
2453                 }
2454
2455                 public override string AssemblyQualifiedName
2456                 {
2457                         get
2458                         {
2459                                 string fn = FullName;
2460                                 return fn == null ? null : fn + ", " + type.Assembly.FullName;
2461                         }
2462                 }
2463
2464                 public override Type BaseType
2465                 {
2466                         get
2467                         {
2468                                 if (baseType == null)
2469                                 {
2470                                         Type rawBaseType = type.BaseType;
2471                                         if (rawBaseType == null)
2472                                         {
2473                                                 baseType = rawBaseType;
2474                                         }
2475                                         else
2476                                         {
2477                                                 baseType = rawBaseType.BindTypeParameters(this);
2478                                         }
2479                                 }
2480                                 return baseType;
2481                         }
2482                 }
2483
2484                 public override bool IsValueType
2485                 {
2486                         get { return type.IsValueType; }
2487                 }
2488
2489                 public override bool IsVisible
2490                 {
2491                         get
2492                         {
2493                                 if (base.IsVisible)
2494                                 {
2495                                         foreach (Type arg in args)
2496                                         {
2497                                                 if (!arg.IsVisible)
2498                                                 {
2499                                                         return false;
2500                                                 }
2501                                         }
2502                                         return true;
2503                                 }
2504                                 return false;
2505                         }
2506                 }
2507
2508                 public override Type DeclaringType
2509                 {
2510                         get { return type.DeclaringType; }
2511                 }
2512
2513                 public override TypeAttributes Attributes
2514                 {
2515                         get { return type.Attributes; }
2516                 }
2517
2518                 internal override void CheckBaked()
2519                 {
2520                         type.CheckBaked();
2521                 }
2522
2523                 public override FieldInfo[] __GetDeclaredFields()
2524                 {
2525                         FieldInfo[] fields = type.__GetDeclaredFields();
2526                         for (int i = 0; i < fields.Length; i++)
2527                         {
2528                                 fields[i] = fields[i].BindTypeParameters(this);
2529                         }
2530                         return fields;
2531                 }
2532
2533                 public override Type[] __GetDeclaredInterfaces()
2534                 {
2535                         Type[] interfaces = type.__GetDeclaredInterfaces();
2536                         for (int i = 0; i < interfaces.Length; i++)
2537                         {
2538                                 interfaces[i] = interfaces[i].BindTypeParameters(this);
2539                         }
2540                         return interfaces;
2541                 }
2542
2543                 public override MethodBase[] __GetDeclaredMethods()
2544                 {
2545                         MethodBase[] methods = type.__GetDeclaredMethods();
2546                         for (int i = 0; i < methods.Length; i++)
2547                         {
2548                                 methods[i] = methods[i].BindTypeParameters(this);
2549                         }
2550                         return methods;
2551                 }
2552
2553                 public override Type[] __GetDeclaredTypes()
2554                 {
2555                         return type.__GetDeclaredTypes();
2556                 }
2557
2558                 public override EventInfo[] __GetDeclaredEvents()
2559                 {
2560                         EventInfo[] events = type.__GetDeclaredEvents();
2561                         for (int i = 0; i < events.Length; i++)
2562                         {
2563                                 events[i] = events[i].BindTypeParameters(this);
2564                         }
2565                         return events;
2566                 }
2567
2568                 public override PropertyInfo[] __GetDeclaredProperties()
2569                 {
2570                         PropertyInfo[] properties = type.__GetDeclaredProperties();
2571                         for (int i = 0; i < properties.Length; i++)
2572                         {
2573                                 properties[i] = properties[i].BindTypeParameters(this);
2574                         }
2575                         return properties;
2576                 }
2577
2578                 public override __MethodImplMap __GetMethodImplMap()
2579                 {
2580                         __MethodImplMap map = type.__GetMethodImplMap();
2581                         map.TargetType = this;
2582                         for (int i = 0; i < map.MethodBodies.Length; i++)
2583                         {
2584                                 map.MethodBodies[i] = (MethodInfo)map.MethodBodies[i].BindTypeParameters(this);
2585                                 for (int j = 0; j < map.MethodDeclarations[i].Length; j++)
2586                                 {
2587                                         Type interfaceType = map.MethodDeclarations[i][j].DeclaringType;
2588                                         if (interfaceType.IsGenericType)
2589                                         {
2590                                                 map.MethodDeclarations[i][j] = (MethodInfo)map.MethodDeclarations[i][j].BindTypeParameters(this);
2591                                         }
2592                                 }
2593                         }
2594                         return map;
2595                 }
2596
2597                 public override string Namespace
2598                 {
2599                         get { return type.Namespace; }
2600                 }
2601
2602                 public override string Name
2603                 {
2604                         get { return type.Name; }
2605                 }
2606
2607                 public override string FullName
2608                 {
2609                         get
2610                         {
2611                                 if (!this.__ContainsMissingType && this.ContainsGenericParameters)
2612                                 {
2613                                         return null;
2614                                 }
2615                                 StringBuilder sb = new StringBuilder(this.type.FullName);
2616                                 sb.Append('[');
2617                                 string sep = "";
2618                                 foreach (Type type in args)
2619                                 {
2620                                         sb.Append(sep).Append('[').Append(type.FullName).Append(", ").Append(type.Assembly.FullName.Replace("]", "\\]")).Append(']');
2621                                         sep = ",";
2622                                 }
2623                                 sb.Append(']');
2624                                 return sb.ToString();
2625                         }
2626                 }
2627
2628                 public override string ToString()
2629                 {
2630                         StringBuilder sb = new StringBuilder(type.FullName);
2631                         sb.Append('[');
2632                         string sep = "";
2633                         foreach (Type arg in args)
2634                         {
2635                                 sb.Append(sep);
2636                                 sb.Append(arg);
2637                                 sep = ",";
2638                         }
2639                         sb.Append(']');
2640                         return sb.ToString();
2641                 }
2642
2643                 public override Module Module
2644                 {
2645                         get { return type.Module; }
2646                 }
2647
2648                 public override bool IsGenericType
2649                 {
2650                         get { return true; }
2651                 }
2652
2653                 internal override bool IsGenericTypeInstance
2654                 {
2655                         get { return true; }
2656                 }
2657
2658                 public override Type GetGenericTypeDefinition()
2659                 {
2660                         return type;
2661                 }
2662
2663                 public override Type[] GetGenericArguments()
2664                 {
2665                         return Util.Copy(args);
2666                 }
2667
2668                 public override CustomModifiers[] __GetGenericArgumentsCustomModifiers()
2669                 {
2670                         return mods != null ? (CustomModifiers[])mods.Clone() : new CustomModifiers[args.Length];
2671                 }
2672
2673                 internal override Type GetGenericTypeArgument(int index)
2674                 {
2675                         return args[index];
2676                 }
2677
2678                 public override bool ContainsGenericParameters
2679                 {
2680                         get
2681                         {
2682                                 foreach (Type type in args)
2683                                 {
2684                                         if (type.ContainsGenericParameters)
2685                                         {
2686                                                 return true;
2687                                         }
2688                                 }
2689                                 return false;
2690                         }
2691                 }
2692
2693                 public override bool __ContainsMissingType
2694                 {
2695                         get
2696                         {
2697                                 foreach (Type type in args)
2698                                 {
2699                                         if (type.__ContainsMissingType)
2700                                         {
2701                                                 return true;
2702                                         }
2703                                 }
2704                                 return this.type.__IsMissing;
2705                         }
2706                 }
2707
2708                 public override StructLayoutAttribute StructLayoutAttribute
2709                 {
2710                         get { return type.StructLayoutAttribute; }
2711                 }
2712
2713                 internal override int GetModuleBuilderToken()
2714                 {
2715                         if (token == 0)
2716                         {
2717                                 token = ((ModuleBuilder)type.Module).ImportType(this);
2718                         }
2719                         return token;
2720                 }
2721
2722                 internal override Type BindTypeParameters(IGenericBinder binder)
2723                 {
2724                         for (int i = 0; i < args.Length; i++)
2725                         {
2726                                 Type xarg = args[i].BindTypeParameters(binder);
2727                                 if (!ReferenceEquals(xarg, args[i]))
2728                                 {
2729                                         Type[] xargs = new Type[args.Length];
2730                                         Array.Copy(args, xargs, i);
2731                                         xargs[i++] = xarg;
2732                                         for (; i < args.Length; i++)
2733                                         {
2734                                                 xargs[i] = args[i].BindTypeParameters(binder);
2735                                         }
2736                                         return Make(type, xargs, null);
2737                                 }
2738                         }
2739                         return this;
2740                 }
2741
2742                 internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
2743                 {
2744                         return type.GetCustomAttributesData(attributeType);
2745                 }
2746         }
2747
2748         sealed class FunctionPointerType : Type
2749         {
2750                 private readonly Universe universe;
2751                 private readonly __StandAloneMethodSig sig;
2752
2753                 internal static Type Make(Universe universe, __StandAloneMethodSig sig)
2754                 {
2755                         return universe.CanonicalizeType(new FunctionPointerType(universe, sig));
2756                 }
2757
2758                 private FunctionPointerType(Universe universe, __StandAloneMethodSig sig)
2759                 {
2760                         this.universe = universe;
2761                         this.sig = sig;
2762                 }
2763
2764                 public override bool Equals(object obj)
2765                 {
2766                         FunctionPointerType other = obj as FunctionPointerType;
2767                         return other != null
2768                                 && other.universe == universe
2769                                 && other.sig.Equals(sig);
2770                 }
2771
2772                 public override int GetHashCode()
2773                 {
2774                         return sig.GetHashCode();
2775                 }
2776
2777                 public override bool __IsFunctionPointer
2778                 {
2779                         get { return true; }
2780                 }
2781
2782                 public override __StandAloneMethodSig __MethodSignature
2783                 {
2784                         get { return sig; }
2785                 }
2786
2787                 public override Type BaseType
2788                 {
2789                         get { return null; }
2790                 }
2791
2792                 public override TypeAttributes Attributes
2793                 {
2794                         get { return 0; }
2795                 }
2796
2797                 public override string Name
2798                 {
2799                         get { throw new InvalidOperationException(); }
2800                 }
2801
2802                 public override string FullName
2803                 {
2804                         get { throw new InvalidOperationException(); }
2805                 }
2806
2807                 public override Module Module
2808                 {
2809                         get { throw new InvalidOperationException(); }
2810                 }
2811
2812                 internal override Universe Universe
2813                 {
2814                         get { return universe; }
2815                 }
2816
2817                 public override string ToString()
2818                 {
2819                         return "<FunctionPtr>";
2820                 }
2821         }
2822 }