Add [Category ("NotWorking")] to failing test.
[mono.git] / mcs / class / corlib / System / Type.cs
1 //
2 // System.Type.cs
3 //
4 // Authors:
5 //   Miguel de Icaza (miguel@ximian.com)
6 //   Marek Safar (marek.safar@gmail.com)
7 //
8 // (C) Ximian, Inc.  http://www.ximian.com
9 //
10
11 //
12 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33
34 using System.Diagnostics;
35 using System.Reflection;
36 #if !FULL_AOT_RUNTIME
37 using System.Reflection.Emit;
38 #endif
39 using System.Collections;
40 using System.Collections.Generic;
41 using System.Runtime.InteropServices;
42 using System.Runtime.CompilerServices;
43 using System.Threading;
44 using System.Globalization;
45
46 namespace System {
47
48         [Serializable]
49         [ClassInterface (ClassInterfaceType.None)]
50         [ComVisible (true)]
51         [ComDefaultInterface (typeof (_Type))]
52         [StructLayout (LayoutKind.Sequential)]
53 #if MOBILE
54         public abstract class Type : MemberInfo, IReflect {
55 #else
56         public abstract class Type : MemberInfo, IReflect, _Type {
57 #endif
58
59                 internal RuntimeTypeHandle _impl;
60
61                 public static readonly char Delimiter = '.';
62                 public static readonly Type[] EmptyTypes = {};
63                 public static readonly MemberFilter FilterAttribute = new MemberFilter (FilterAttribute_impl);
64                 public static readonly MemberFilter FilterName = new MemberFilter (FilterName_impl);
65                 public static readonly MemberFilter FilterNameIgnoreCase = new MemberFilter (FilterNameIgnoreCase_impl);
66                 public static readonly object Missing = System.Reflection.Missing.Value;
67
68                 internal const BindingFlags DefaultBindingFlags =
69                 BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance;
70
71                 /* implementation of the delegates for MemberFilter */
72                 static bool FilterName_impl (MemberInfo m, object filterCriteria)
73                 {
74                         string name = (string) filterCriteria;
75                         if (name == null || name.Length == 0 )
76                                 return false; // because m.Name cannot be null or empty
77                         
78                         if (name [name.Length - 1] == '*')
79                                 return m.Name.StartsWithOrdinalUnchecked (name.Substring (0, name.Length - 1));
80                         
81                         return m.Name == name;
82                 }
83
84                 static bool FilterNameIgnoreCase_impl (MemberInfo m, object filterCriteria)
85                 {
86                         string name = (string) filterCriteria;
87                         if (name == null || name.Length == 0 )
88                                 return false; // because m.Name cannot be null or empty
89                                 
90                         if (name [name.Length - 1] == '*')
91                                 return m.Name.StartsWithOrdinalCaseInsensitiveUnchecked (name.Substring (0, name.Length - 1));
92                         
93                         return string.CompareOrdinalCaseInsensitiveUnchecked (m.Name, name) == 0;
94                 }
95
96                 static bool FilterAttribute_impl (MemberInfo m, object filterCriteria)
97                 {
98                         if (!(filterCriteria is int))
99                                 throw new InvalidFilterCriteriaException ("Int32 value is expected for filter criteria");
100
101                         int flags = (int) filterCriteria;
102                         if (m is MethodInfo)
103                                 return ((int)((MethodInfo)m).Attributes & flags) != 0;
104                         if (m is FieldInfo)
105                                 return ((int)((FieldInfo)m).Attributes & flags) != 0;
106                         if (m is PropertyInfo)
107                                 return ((int)((PropertyInfo)m).Attributes & flags) != 0;
108                         if (m is EventInfo)
109                                 return ((int)((EventInfo)m).Attributes & flags) != 0;
110                         return false;
111                 }
112
113                 protected Type ()
114                 {
115                 }
116
117                 /// <summary>
118                 ///   The assembly where the type is defined.
119                 /// </summary>
120                 public abstract Assembly Assembly {
121                         get;
122                 }
123
124                 /// <summary>
125                 ///   Gets the fully qualified name for the type including the
126                 ///   assembly name where the type is defined.
127                 /// </summary>
128                 public abstract string AssemblyQualifiedName {
129                         get;
130                 }
131
132                 /// <summary>
133                 ///   Returns the Attributes associated with the type.
134                 /// </summary>
135                 public TypeAttributes Attributes {
136                         get {
137                                 return GetAttributeFlagsImpl ();
138                         }
139                 }
140
141                 /// <summary>
142                 ///   Returns the basetype for this type
143                 /// </summary>
144                 public abstract Type BaseType {
145                         get;
146                 }
147
148                 /// <summary>
149                 ///   Returns the class that declares the member.
150                 /// </summary>
151                 public override Type DeclaringType {
152                         get {
153                                 return null;
154                         }
155                 }
156
157                 /// <summary>
158                 ///
159                 /// </summary>
160                 public static Binder DefaultBinder {
161                         get {
162                                 return Binder.DefaultBinder;
163                         }
164                 }
165
166                 /// <summary>
167                 ///    The full name of the type including its namespace
168                 /// </summary>
169                 public abstract string FullName {
170                         get;
171                 }
172
173                 public abstract Guid GUID {
174                         get;
175                 }
176
177                 public bool HasElementType {
178                         get {
179                                 return HasElementTypeImpl ();
180                         }
181                 }
182
183                 public bool IsAbstract {
184                         get {
185                                 return (Attributes & TypeAttributes.Abstract) != 0;
186                         }
187                 }
188
189                 public bool IsAnsiClass {
190                         get {
191                                 return (Attributes & TypeAttributes.StringFormatMask)
192                                 == TypeAttributes.AnsiClass;
193                         }
194                 }
195
196                 public bool IsArray {
197                         get {
198                                 return IsArrayImpl ();
199                         }
200                 }
201
202                 public bool IsAutoClass {
203                         get {
204                                 return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass;
205                         }
206                 }
207
208                 public bool IsAutoLayout {
209                         get {
210                                 return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout;
211                         }
212                 }
213
214                 public bool IsByRef {
215                         get {
216                                 return IsByRefImpl ();
217                         }
218                 }
219
220                 public bool IsClass {
221                         get {
222                                 if (IsInterface)
223                                         return false;
224
225                                 return !IsValueType;
226                         }
227                 }
228
229                 public bool IsCOMObject {
230                         get {
231                                 return IsCOMObjectImpl ();
232                         }
233                 }
234                 
235 #if NET_4_5
236                 public virtual bool IsConstructedGenericType {
237                         get {
238                                 throw new NotImplementedException ();
239                         }
240                 }
241 #endif
242
243                 public bool IsContextful {
244                         get {
245                                 return IsContextfulImpl ();
246                         }
247                 }
248
249                 public
250 #if NET_4_0
251                 virtual
252 #endif
253                 bool IsEnum {
254                         get {
255                                 return IsSubclassOf (typeof (Enum));
256                         }
257                 }
258
259                 public bool IsExplicitLayout {
260                         get {
261                                 return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout;
262                         }
263                 }
264
265                 public bool IsImport {
266                         get {
267                                 return (Attributes & TypeAttributes.Import) != 0;
268                         }
269                 }
270
271                 public bool IsInterface {
272                         get {
273                                 return (Attributes & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface;
274                         }
275                 }
276
277                 public bool IsLayoutSequential {
278                         get {
279                                 return (Attributes & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout;
280                         }
281                 }
282
283                 public bool IsMarshalByRef {
284                         get {
285                                 return IsMarshalByRefImpl ();
286                         }
287                 }
288
289                 public bool IsNestedAssembly {
290                         get {
291                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly;
292                         }
293                 }
294
295                 public bool IsNestedFamANDAssem {
296                         get {
297                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem;
298                         }
299                 }
300
301                 public bool IsNestedFamily {
302                         get {
303                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily;
304                         }
305                 }
306
307                 public bool IsNestedFamORAssem {
308                         get {
309                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem;
310                         }
311                 }
312
313                 public bool IsNestedPrivate {
314                         get {
315                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate;
316                         }
317                 }
318
319                 public bool IsNestedPublic {
320                         get {
321                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic;
322                         }
323                 }
324
325                 public bool IsNotPublic {
326                         get {
327                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic;
328                         }
329                 }
330
331                 public bool IsPointer {
332                         get {
333                                 return IsPointerImpl ();
334                         }
335                 }
336
337                 public bool IsPrimitive {
338                         get {
339                                 return IsPrimitiveImpl ();
340                         }
341                 }
342
343                 public bool IsPublic {
344                         get {
345                                 return (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public;
346                         }
347                 }
348
349                 public bool IsSealed {
350                         get {
351                                 return (Attributes & TypeAttributes.Sealed) != 0;
352                         }
353                 }
354
355                 public
356 #if NET_4_0
357                 virtual
358 #endif
359                 bool IsSerializable {
360                         get {
361                                 if ((Attributes & TypeAttributes.Serializable) != 0)
362                                         return true;
363
364                                 // Enums and delegates are always serializable
365
366                                 Type type = UnderlyingSystemType;
367                                 if (type == null)
368                                         return false;
369
370                                 // Fast check for system types
371                                 if (type.IsSystemType)
372                                         return type_is_subtype_of (type, typeof (Enum), false) || type_is_subtype_of (type, typeof (Delegate), false);
373
374                                 // User defined types depend on this behavior
375                                 do {
376                                         if ((type == typeof (Enum)) || (type == typeof (Delegate)))
377                                                 return true;
378
379                                         type = type.BaseType;
380                                 } while (type != null);
381
382                                 return false;
383                         }
384                 }
385
386                 public bool IsSpecialName {
387                         get {
388                                 return (Attributes & TypeAttributes.SpecialName) != 0;
389                         }
390                 }
391
392                 public bool IsUnicodeClass {
393                         get {
394                                 return (Attributes & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass;
395                         }
396                 }
397
398                 public bool IsValueType {
399                         get {
400                                 return IsValueTypeImpl ();
401                         }
402                 }
403
404                 public override MemberTypes MemberType {
405                         get {
406                                 return MemberTypes.TypeInfo;
407                         }
408                 }
409
410                 public abstract override Module Module {
411                         get;
412                 }
413         
414                 public abstract string Namespace {get;}
415
416                 public override Type ReflectedType {
417                         get {
418                                 return null;
419                         }
420                 }
421
422                 public virtual RuntimeTypeHandle TypeHandle {
423                         get { throw new ArgumentException ("Derived class must provide implementation."); }
424                 }
425
426                 [ComVisible (true)]
427                 public ConstructorInfo TypeInitializer {
428                         get {
429                                 return GetConstructorImpl (
430                                         BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static,
431                                         null,
432                                         CallingConventions.Any,
433                                         EmptyTypes,
434                                         null);
435                         }
436                 }
437
438                 /*
439                  * This has NOTHING to do with getting the base type of an enum. Use
440                  * Enum.GetUnderlyingType () for that.
441                  */
442                 public abstract Type UnderlyingSystemType {get;}
443
444                 public override bool Equals (object o)
445                 {
446 #if NET_4_0
447                         return Equals (o as Type);
448 #else
449                         if (o == this)
450                                 return true;
451
452                         Type me = UnderlyingSystemType;
453                         if (me == null)
454                                 return false;
455                         return me.EqualsInternal (o as Type);
456 #endif
457                 }
458
459 #if NET_4_0
460                 public virtual bool Equals (Type o)
461                 {
462                         if ((object)o == (object)this)
463                                 return true;
464                         if ((object)o == null)
465                                 return false;
466                         Type me = UnderlyingSystemType;
467                         if ((object)me == null)
468                                 return false;
469
470                         o = o.UnderlyingSystemType;
471                         if ((object)o == null)
472                                 return false;
473                         if ((object)o == (object)this)
474                                 return true;
475                         return me.EqualsInternal (o);
476                 }               
477 #else
478                 public bool Equals (Type o)
479                 {
480
481                         if (o == this)
482                                 return true;
483                         if (o == null)
484                                 return false;
485                         Type me = UnderlyingSystemType;
486                         if (me == null)
487                                 return false;
488                         return me.EqualsInternal (o.UnderlyingSystemType);
489                 }
490 #endif
491 #if NET_4_0
492                 [MonoTODO ("Implement it properly once 4.0 impl details are known.")]
493                 public static bool operator == (Type left, Type right)
494                 {
495                         return Object.ReferenceEquals (left, right);
496                 }
497
498                 [MonoTODO ("Implement it properly once 4.0 impl details are known.")]
499                 public static bool operator != (Type left, Type right)
500                 {
501                         return !Object.ReferenceEquals (left, right);
502                 }
503
504                 [MonoInternalNote ("Reimplement this in MonoType for bonus speed")]
505                 public virtual Type GetEnumUnderlyingType () {
506                         if (!IsEnum)
507                                 throw new ArgumentException ("Type is not an enumeration", "enumType");
508
509                         var fields = GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
510
511                         if (fields == null || fields.Length != 1)
512                                 throw new ArgumentException ("An enum must have exactly one instance field", "enumType");
513
514                         return fields [0].FieldType;
515                 }
516
517                 [MonoInternalNote ("Reimplement this in MonoType for bonus speed")]
518                 public virtual string[] GetEnumNames () {
519                         if (!IsEnum)
520                                 throw new ArgumentException ("Type is not an enumeration", "enumType");
521
522                         var fields = GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
523
524                         string [] names = new string [fields.Length];
525                         if (0 != names.Length) {
526                                 for (int i = 0; i < fields.Length; ++i)
527                                         names [i] = fields [i].Name;
528                                         
529                                 var et = GetEnumUnderlyingType ();
530                                 var values = Array.CreateInstance (et, names.Length);
531                                 for (int i = 0; i < fields.Length; ++i)
532                                         values.SetValue (fields [i].GetValue (null), i);
533                                 MonoEnumInfo.SortEnums (et, values, names);
534                         }
535
536                         return names;
537                 }
538
539                 static NotImplementedException CreateNIE () {
540                         return new NotImplementedException ();
541                 }
542
543                 public virtual Array GetEnumValues () {
544                         if (!IsEnum)
545                                 throw new ArgumentException ("Type is not an enumeration", "enumType");
546
547                         throw CreateNIE ();
548                 }
549
550                 bool IsValidEnumType (Type type) {
551                         return (type.IsPrimitive && type != typeof (bool) && type != typeof (double) && type != typeof (float)) || type.IsEnum;
552                 }
553
554                 [MonoInternalNote ("Reimplement this in MonoType for bonus speed")]
555                 public virtual string GetEnumName (object value) {
556                         if (value == null)
557                                 throw new ArgumentException ("Value is null", "value");
558                         if (!IsValidEnumType (value.GetType ()))
559                                 throw new ArgumentException ("Value is not the enum or a valid enum underlying type", "value");
560                         if (!IsEnum)
561                                 throw new ArgumentException ("Type is not an enumeration", "enumType");
562
563                         object obj = null;
564                         var fields = GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
565                         
566                         for (int i = 0; i < fields.Length; ++i) {
567                                 var fv = fields [i].GetValue (null);
568                                 if (obj == null) {
569                                         try {
570                                                 //XXX we can't use 'this' as argument as it might be an UserType
571                                                 obj = Enum.ToObject (fv.GetType (), value);
572                                         } catch (OverflowException) {
573                                                 return null;
574                                         } catch (InvalidCastException) {
575                                                 throw new ArgumentException ("Value is not valid", "value");
576                                         }
577                                 }
578                                 if (fv.Equals (obj))
579                                         return fields [i].Name;
580                         }
581
582                         return null;
583                 }
584
585                 [MonoInternalNote ("Reimplement this in MonoType for bonus speed")]
586                 public virtual bool IsEnumDefined (object value) {
587                         if (value == null)
588                                 throw new ArgumentException ("Value is null", "value");
589                         if (!IsEnum)
590                                 throw new ArgumentException ("Type is not an enumeration", "enumType");
591
592                         Type vt = value.GetType ();
593                         if (!IsValidEnumType (vt) && vt != typeof (string))
594                                 throw new InvalidOperationException ("Value is not the enum or a valid enum underlying type");
595
596                         var fields = GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
597
598                         if (value is string) {
599                                 for (int i = 0; i < fields.Length; ++i) {
600                                         if (fields [i].Name.Equals (value))
601                                                 return true;
602                                 }
603                         } else {
604                                 if (vt != this && vt != GetEnumUnderlyingType ())
605                                         throw new ArgumentException ("Value is not the enum or a valid enum underlying type", "value");
606
607                                 object obj = null;
608                                 for (int i = 0; i < fields.Length; ++i) {
609                                         var fv = fields [i].GetValue (null);
610                                         if (obj == null) {
611                                                 try {
612                                                         //XXX we can't use 'this' as argument as it might be an UserType
613                                                         obj = Enum.ToObject (fv.GetType (), value);
614                                                 } catch (OverflowException) {
615                                                         return false;
616                                                 } catch (InvalidCastException) {
617                                                         throw new ArgumentException ("Value is not valid", "value");
618                                                 }
619                                         }
620                                         if (fv.Equals (obj))
621                                                 return true;
622                                 }
623                         }
624                         return false;
625                 }
626         
627                 public static Type GetType (string typeName, Func<AssemblyName,Assembly> assemblyResolver, Func<Assembly,string,bool,Type> typeResolver)
628                 {
629                         return GetType (typeName, assemblyResolver, typeResolver, false, false);
630                 }
631         
632                 public static Type GetType (string typeName, Func<AssemblyName,Assembly> assemblyResolver, Func<Assembly,string,bool,Type> typeResolver, bool throwOnError)
633                 {
634                         return GetType (typeName, assemblyResolver, typeResolver, throwOnError, false);
635                 }
636         
637                 public static Type GetType (string typeName, Func<AssemblyName,Assembly> assemblyResolver, Func<Assembly,string,bool,Type> typeResolver, bool throwOnError, bool ignoreCase)
638                 {
639                         TypeSpec spec = TypeSpec.Parse (typeName);
640                         return spec.Resolve (assemblyResolver, typeResolver, throwOnError, ignoreCase);
641                 }
642
643                 public virtual bool IsSecurityTransparent
644                 {
645                         get { throw CreateNIE (); }
646                 }
647
648                 public virtual bool IsSecurityCritical
649                 {
650                         get { throw CreateNIE (); }
651                 }
652
653                 public virtual bool IsSecuritySafeCritical
654                 {
655                         get { throw CreateNIE (); }
656                 }
657 #endif
658                 
659                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
660                 internal extern bool EqualsInternal (Type type);
661                 
662                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
663                 private static extern Type internal_from_handle (IntPtr handle);
664                 
665                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
666                 private static extern Type internal_from_name (string name, bool throwOnError, bool ignoreCase);
667
668                 public static Type GetType(string typeName)
669                 {
670                         if (typeName == null)
671                                 throw new ArgumentNullException ("TypeName");
672
673                         return internal_from_name (typeName, false, false);
674                 }
675
676                 public static Type GetType(string typeName, bool throwOnError)
677                 {
678                         if (typeName == null)
679                                 throw new ArgumentNullException ("TypeName");
680
681                         Type type = internal_from_name (typeName, throwOnError, false);
682                         if (throwOnError && type == null)
683                                 throw new TypeLoadException ("Error loading '" + typeName + "'");
684
685                         return type;
686                 }
687
688                 public static Type GetType(string typeName, bool throwOnError, bool ignoreCase)
689                 {
690                         if (typeName == null)
691                                 throw new ArgumentNullException ("TypeName");
692
693                         Type t = internal_from_name (typeName, throwOnError, ignoreCase);
694                         if (throwOnError && t == null)
695                                 throw new TypeLoadException ("Error loading '" + typeName + "'");
696
697                         return t;
698                 }
699
700                 public static Type[] GetTypeArray (object[] args) {
701                         if (args == null)
702                                 throw new ArgumentNullException ("args");
703
704                         Type[] ret;
705                         ret = new Type [args.Length];
706                         for (int i = 0; i < args.Length; ++i)
707                                 ret [i] = args[i].GetType ();
708                         return ret;
709                 }
710
711                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
712                 internal extern static TypeCode GetTypeCodeInternal (Type type);
713
714 #if NET_4_0
715                 protected virtual
716 #endif
717                 TypeCode GetTypeCodeImpl () {
718                         Type type = this;
719                         if (type is MonoType)
720                                 return GetTypeCodeInternal (type);
721 #if !FULL_AOT_RUNTIME
722                         if (type is TypeBuilder)
723                                 return ((TypeBuilder)type).GetTypeCodeInternal ();
724 #endif
725
726                         type = type.UnderlyingSystemType;
727
728                         if (!type.IsSystemType)
729                                 return TypeCode.Object;
730                         else
731                                 return GetTypeCodeInternal (type);
732                 }
733
734                 public static TypeCode GetTypeCode (Type type) {
735                         if (type == null)
736                                 /* MS.NET returns this */
737                                 return TypeCode.Empty;
738                         return type.GetTypeCodeImpl ();
739                 }
740
741 #if !FULL_AOT_RUNTIME
742                 private static Dictionary<Guid, Type> clsid_types;
743                 private static AssemblyBuilder clsid_assemblybuilder;
744 #endif
745
746                 [MonoTODO("COM servers only work on Windows")]
747                 public static Type GetTypeFromCLSID (Guid clsid)
748                 {
749                         return GetTypeFromCLSID (clsid, null, true);
750                 }
751
752                 [MonoTODO("COM servers only work on Windows")]
753                 public static Type GetTypeFromCLSID (Guid clsid, bool throwOnError)
754                 {
755                         return GetTypeFromCLSID (clsid, null, throwOnError);
756                 }
757
758                 [MonoTODO("COM servers only work on Windows")]
759                 public static Type GetTypeFromCLSID (Guid clsid, string server)
760                 {
761                         return GetTypeFromCLSID (clsid, server, true);
762                 }
763
764                 [MonoTODO("COM servers only work on Windows")]
765                 public static Type GetTypeFromCLSID (Guid clsid, string server, bool throwOnError)
766                 {
767 #if !FULL_AOT_RUNTIME
768                         Type result;
769
770                         if (clsid_types == null)
771                         {
772                                 Dictionary<Guid, Type> new_clsid_types = new Dictionary<Guid, Type> ();
773                                 Interlocked.CompareExchange<Dictionary<Guid, Type>>(
774                                         ref clsid_types, new_clsid_types, null);
775                         }
776
777                         lock (clsid_types) {
778                                 if (clsid_types.TryGetValue(clsid, out result))
779                                         return result;
780
781                                 if (clsid_assemblybuilder == null)
782                                 {
783                                         AssemblyName assemblyname = new AssemblyName ();
784                                         assemblyname.Name = "GetTypeFromCLSIDDummyAssembly";
785                                         clsid_assemblybuilder = AppDomain.CurrentDomain.DefineDynamicAssembly (
786                                                 assemblyname, AssemblyBuilderAccess.Run);
787                                 }
788                                 ModuleBuilder modulebuilder = clsid_assemblybuilder.DefineDynamicModule (
789                                         clsid.ToString ());
790
791                                 TypeBuilder typebuilder = modulebuilder.DefineType ("System.__ComObject",
792                                         TypeAttributes.Public | TypeAttributes.Class, typeof(System.__ComObject));
793
794                                 Type[] guidattrtypes = new Type[] { typeof(string) };
795
796                                 CustomAttributeBuilder customattr = new CustomAttributeBuilder (
797                                         typeof(GuidAttribute).GetConstructor (guidattrtypes),
798                                         new object[] { clsid.ToString () });
799
800                                 typebuilder.SetCustomAttribute (customattr);
801
802                                 customattr = new CustomAttributeBuilder (
803                                         typeof(ComImportAttribute).GetConstructor (EmptyTypes),
804                                         new object[0] {});
805
806                                 typebuilder.SetCustomAttribute (customattr);
807
808                                 result = typebuilder.CreateType ();
809
810                                 clsid_types.Add(clsid, result);
811
812                                 return result;
813                         }
814 #else
815                         throw new NotImplementedException ();
816 #endif
817                 }
818
819                 public static Type GetTypeFromHandle (RuntimeTypeHandle handle)
820                 {
821                         if (handle.Value == IntPtr.Zero)
822                                 // This is not consistent with the other GetXXXFromHandle methods, but
823                                 // MS.NET seems to do this
824                                 return null;
825
826                         return internal_from_handle (handle.Value);
827                 }
828
829                 [MonoTODO("Mono does not support COM")]
830                 public static Type GetTypeFromProgID (string progID)
831                 {
832                         throw new NotImplementedException ();
833                 }
834
835                 [MonoTODO("Mono does not support COM")]
836                 public static Type GetTypeFromProgID (string progID, bool throwOnError)
837                 {
838                         throw new NotImplementedException ();
839                 }
840
841                 [MonoTODO("Mono does not support COM")]
842                 public static Type GetTypeFromProgID (string progID, string server)
843                 {
844                         throw new NotImplementedException ();
845                 }
846
847                 [MonoTODO("Mono does not support COM")]
848                 public static Type GetTypeFromProgID (string progID, string server, bool throwOnError)
849                 {
850                         throw new NotImplementedException ();
851                 }
852
853                 public static RuntimeTypeHandle GetTypeHandle (object o)
854                 {
855                         if (o == null)
856                                 throw new ArgumentNullException ();
857
858                         return o.GetType().TypeHandle;
859                 }
860
861                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
862                 internal static extern bool type_is_subtype_of (Type a, Type b, bool check_interfaces);
863
864                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
865                 internal static extern bool type_is_assignable_from (Type a, Type b);
866
867                 public new Type GetType ()
868                 {
869                         return base.GetType ();
870                 }
871
872                 [ComVisible (true)]
873                 public virtual bool IsSubclassOf (Type c)
874                 {
875                         if (c == null || c == this)
876                                 return false;
877
878                         // Fast check for system types
879                         if (IsSystemType)
880                                 return c.IsSystemType && type_is_subtype_of (this, c, false);
881
882                         // User defined types depend on this behavior
883                         for (Type type = BaseType; type != null; type = type.BaseType)
884                                 if (type == c)
885                                         return true;
886
887                         return false;
888                 }
889
890                 public virtual Type[] FindInterfaces (TypeFilter filter, object filterCriteria)
891                 {
892                         if (filter == null)
893                                 throw new ArgumentNullException ("filter");
894
895                         var ifaces = new List<Type> ();
896                         foreach (Type iface in GetInterfaces ()) {
897                                 if (filter (iface, filterCriteria))
898                                         ifaces.Add (iface);
899                         }
900
901                         return ifaces.ToArray ();
902                 }
903                 
904                 public Type GetInterface (string name) {
905                         return GetInterface (name, false);
906                 }
907
908                 public abstract Type GetInterface (string name, bool ignoreCase);
909
910                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
911                 internal static extern void GetInterfaceMapData (Type t, Type iface, out MethodInfo[] targets, out MethodInfo[] methods);
912
913                 [ComVisible (true)]
914                 public virtual InterfaceMapping GetInterfaceMap (Type interfaceType) {
915                         if (!IsSystemType)
916                                 throw new NotSupportedException ("Derived classes must provide an implementation.");
917                         if (interfaceType == null)
918                                 throw new ArgumentNullException ("interfaceType");
919                         if (!interfaceType.IsSystemType)
920                                 throw new ArgumentException ("interfaceType", "Type is an user type");
921                         InterfaceMapping res;
922                         if (!interfaceType.IsInterface)
923                                 throw new ArgumentException (Locale.GetText ("Argument must be an interface."), "interfaceType");
924                         if (IsInterface)
925                                 throw new ArgumentException ("'this' type cannot be an interface itself");
926                         res.TargetType = this;
927                         res.InterfaceType = interfaceType;
928                         GetInterfaceMapData (this, interfaceType, out res.TargetMethods, out res.InterfaceMethods);
929                         if (res.TargetMethods == null)
930                                 throw new ArgumentException (Locale.GetText ("Interface not found"), "interfaceType");
931
932                         return res;
933                 }
934
935                 public abstract Type[] GetInterfaces ();
936
937                 public virtual bool IsAssignableFrom (Type c)
938                 {
939                         if (c == null)
940                                 return false;
941
942                         if (Equals (c))
943                                 return true;
944
945 #if !FULL_AOT_RUNTIME
946                         if (c is TypeBuilder)
947                                 return ((TypeBuilder)c).IsAssignableTo (this);
948 #endif
949
950                         /* Handle user defined type classes */
951                         if (!IsSystemType) {
952                                 Type systemType = UnderlyingSystemType;
953                                 if (!systemType.IsSystemType)
954                                         return false;
955
956                                 Type other = c.UnderlyingSystemType;
957                                 if (!other.IsSystemType)
958                                         return false;
959
960                                 return systemType.IsAssignableFrom (other);
961                         }
962
963                         if (!c.IsSystemType) {
964                                 Type underlyingType = c.UnderlyingSystemType;
965                                 if (!underlyingType.IsSystemType)
966                                         return false;
967                                 return IsAssignableFrom (underlyingType);
968                         }
969
970                         return type_is_assignable_from (this, c);
971                 }
972
973                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
974                 extern static bool IsInstanceOfType (Type type, object o);
975
976                 public virtual bool IsInstanceOfType (object o)
977                 {
978                         Type type = UnderlyingSystemType;
979                         if (!type.IsSystemType)
980                                 return false;
981                         return IsInstanceOfType (type, o);
982                 }
983
984                 public virtual int GetArrayRank ()
985                 {
986                         throw new NotSupportedException ();     // according to MSDN
987                 }
988
989                 public abstract Type GetElementType ();
990
991                 public EventInfo GetEvent (string name)
992                 {
993                         return GetEvent (name, DefaultBindingFlags);
994                 }
995
996                 public abstract EventInfo GetEvent (string name, BindingFlags bindingAttr);
997
998                 public virtual EventInfo[] GetEvents ()
999                 {
1000                         return GetEvents (DefaultBindingFlags);
1001                 }
1002
1003                 public abstract EventInfo[] GetEvents (BindingFlags bindingAttr);
1004
1005                 public FieldInfo GetField( string name)
1006                 {
1007                         return GetField (name, DefaultBindingFlags);
1008                 }
1009
1010                 public abstract FieldInfo GetField( string name, BindingFlags bindingAttr);
1011
1012                 public FieldInfo[] GetFields ()
1013                 {
1014                         return GetFields (DefaultBindingFlags);
1015                 }
1016
1017                 public abstract FieldInfo[] GetFields (BindingFlags bindingAttr);
1018                 
1019                 public override int GetHashCode()
1020                 {
1021                         Type t = UnderlyingSystemType;
1022                         if (t != null && t != this)
1023                                 return t.GetHashCode ();
1024                         return (int)_impl.Value;
1025                 }
1026
1027                 public MemberInfo[] GetMember (string name)
1028                 {
1029                         return GetMember (name, MemberTypes.All, DefaultBindingFlags);
1030                 }
1031                 
1032                 public virtual MemberInfo[] GetMember (string name, BindingFlags bindingAttr)
1033                 {
1034                         return GetMember (name, MemberTypes.All, bindingAttr);
1035                 }
1036
1037                 public virtual MemberInfo[] GetMember (string name, MemberTypes type, BindingFlags bindingAttr)
1038                 {
1039                         if (name == null)
1040                                 throw new ArgumentNullException ("name");
1041                         if ((bindingAttr & BindingFlags.IgnoreCase) != 0)
1042                                 return FindMembers (type, bindingAttr, FilterNameIgnoreCase, name);
1043                         else
1044                                 return FindMembers (type, bindingAttr, FilterName, name);
1045                 }
1046
1047                 public MemberInfo[] GetMembers ()
1048                 {
1049                         return GetMembers (DefaultBindingFlags);
1050                 }
1051
1052                 public abstract MemberInfo[] GetMembers (BindingFlags bindingAttr);
1053
1054                 public MethodInfo GetMethod (string name)
1055                 {
1056                         if (name == null)
1057                                 throw new ArgumentNullException ("name");
1058                         return GetMethodImpl (name, DefaultBindingFlags, null, CallingConventions.Any, null, null);
1059                 }
1060
1061                 public MethodInfo GetMethod (string name, BindingFlags bindingAttr)
1062                 {
1063                         if (name == null)
1064                                 throw new ArgumentNullException ("name");
1065                         
1066                         return GetMethodImpl (name, bindingAttr, null, CallingConventions.Any, null, null);
1067                 }
1068                 
1069                 public MethodInfo GetMethod (string name, Type[] types)
1070                 {
1071                         return GetMethod (name, DefaultBindingFlags, null, CallingConventions.Any, types, null);
1072                 }
1073
1074                 public MethodInfo GetMethod (string name, Type[] types, ParameterModifier[] modifiers)
1075                 {
1076                         return GetMethod (name, DefaultBindingFlags, null, CallingConventions.Any, types, modifiers);
1077                 }
1078
1079                 public MethodInfo GetMethod (string name, BindingFlags bindingAttr, Binder binder,
1080                                              Type[] types, ParameterModifier[] modifiers)
1081                 {
1082                         return GetMethod (name, bindingAttr, binder, CallingConventions.Any, types, modifiers);
1083                 }
1084
1085                 public MethodInfo GetMethod (string name, BindingFlags bindingAttr, Binder binder,
1086                                              CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
1087                 {
1088                         if (name == null)
1089                                 throw new ArgumentNullException ("name");
1090                         if (types == null)
1091                                 throw new ArgumentNullException ("types");
1092
1093                         for (int i = 0; i < types.Length; i++) 
1094                                 if (types[i] == null)
1095                                         throw new ArgumentNullException ("types");
1096
1097                         return GetMethodImpl (name, bindingAttr, binder, callConvention, types, modifiers);
1098                 }
1099
1100                 protected abstract MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr, Binder binder,
1101                                                              CallingConventions callConvention, Type[] types,
1102                                                              ParameterModifier[] modifiers);
1103
1104                 internal MethodInfo GetMethodImplInternal (string name, BindingFlags bindingAttr, Binder binder,
1105                                                                                                                         CallingConventions callConvention, Type[] types,
1106                                                                                                                         ParameterModifier[] modifiers)
1107                 {
1108                         return GetMethodImpl (name, bindingAttr, binder, callConvention, types, modifiers);
1109                 }
1110
1111                 internal virtual MethodInfo GetMethod (MethodInfo fromNoninstanciated)
1112                 {
1113                         throw new System.InvalidOperationException ("can only be called in generic type");
1114                 }
1115
1116                 internal virtual ConstructorInfo GetConstructor (ConstructorInfo fromNoninstanciated)
1117                 {
1118                         throw new System.InvalidOperationException ("can only be called in generic type");
1119                 }
1120
1121                 internal virtual FieldInfo GetField (FieldInfo fromNoninstanciated)
1122                 {
1123                         throw new System.InvalidOperationException ("can only be called in generic type");
1124                 }
1125
1126                 
1127                 public MethodInfo[] GetMethods ()
1128                 {
1129                         return GetMethods (DefaultBindingFlags);
1130                 }
1131
1132                 public abstract MethodInfo[] GetMethods (BindingFlags bindingAttr);
1133
1134                 public Type GetNestedType (string name)
1135                 {
1136                         return GetNestedType (name, DefaultBindingFlags);
1137                 }
1138
1139                 public abstract Type GetNestedType (string name, BindingFlags bindingAttr);
1140
1141                 public Type[] GetNestedTypes ()
1142                 {
1143                         return GetNestedTypes (DefaultBindingFlags);
1144                 }
1145
1146                 public abstract Type[] GetNestedTypes (BindingFlags bindingAttr);
1147
1148
1149                 public PropertyInfo[] GetProperties ()
1150                 {
1151                         return GetProperties (DefaultBindingFlags);
1152                 }
1153
1154                 public abstract PropertyInfo[] GetProperties (BindingFlags bindingAttr);
1155
1156
1157                 public PropertyInfo GetProperty (string name)
1158                 {
1159                         if (name == null)
1160                                 throw new ArgumentNullException ("name");
1161
1162                         return GetPropertyImpl (name, DefaultBindingFlags, null, null, null, null);
1163                 }
1164
1165                 public PropertyInfo GetProperty (string name, BindingFlags bindingAttr)
1166                 {
1167                         if (name == null)
1168                                 throw new ArgumentNullException ("name");
1169                         return GetPropertyImpl (name, bindingAttr, null, null, null, null);
1170                 }
1171
1172                 public PropertyInfo GetProperty (string name, Type returnType)
1173                 {
1174                         if (name == null)
1175                                 throw new ArgumentNullException ("name");
1176                         return GetPropertyImpl (name, DefaultBindingFlags, null, returnType, null, null);
1177                 }
1178
1179                 public PropertyInfo GetProperty (string name, Type[] types)
1180                 {
1181                         return GetProperty (name, DefaultBindingFlags, null, null, types, null);
1182                 }
1183
1184                 public PropertyInfo GetProperty (string name, Type returnType, Type[] types)
1185                 {
1186                         return GetProperty (name, DefaultBindingFlags, null, returnType, types, null);
1187                 }
1188
1189                 public PropertyInfo GetProperty( string name, Type returnType, Type[] types, ParameterModifier[] modifiers)
1190                 {
1191                         return GetProperty (name, DefaultBindingFlags, null, returnType, types, modifiers);
1192                 }
1193
1194                 public PropertyInfo GetProperty (string name, BindingFlags bindingAttr, Binder binder, Type returnType,
1195                                                  Type[] types, ParameterModifier[] modifiers)
1196                 {
1197                         if (name == null)
1198                                 throw new ArgumentNullException ("name");
1199                         if (types == null)
1200                                 throw new ArgumentNullException ("types");
1201
1202                         foreach (Type t in types) {
1203                                 if (t == null)
1204                                         throw new ArgumentNullException ("types");
1205                         }
1206
1207                         return GetPropertyImpl (name, bindingAttr, binder, returnType, types, modifiers);
1208                 }
1209
1210                 protected abstract PropertyInfo GetPropertyImpl (string name, BindingFlags bindingAttr, Binder binder,
1211                                                                  Type returnType, Type[] types, ParameterModifier[] modifiers);
1212
1213                 internal PropertyInfo GetPropertyImplInternal (string name, BindingFlags bindingAttr, Binder binder,
1214                                                                                                            Type returnType, Type[] types, ParameterModifier[] modifiers)
1215                 {
1216                         return GetPropertyImpl (name, bindingAttr, binder, returnType, types, modifiers);
1217                 }
1218
1219                 protected abstract ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr,
1220                                                                        Binder binder,
1221                                                                        CallingConventions callConvention,
1222                                                                        Type[] types,
1223                                                                        ParameterModifier[] modifiers);
1224
1225                 protected abstract TypeAttributes GetAttributeFlagsImpl ();
1226                 protected abstract bool HasElementTypeImpl ();
1227                 protected abstract bool IsArrayImpl ();
1228                 protected abstract bool IsByRefImpl ();
1229                 protected abstract bool IsCOMObjectImpl ();
1230                 protected abstract bool IsPointerImpl ();
1231                 protected abstract bool IsPrimitiveImpl ();
1232                 
1233                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1234                 internal static extern bool IsArrayImpl (Type type);
1235
1236                 protected virtual bool IsValueTypeImpl ()
1237                 {
1238                         if (this == typeof (ValueType) || this == typeof (Enum))
1239                                 return false;
1240
1241                         return IsSubclassOf (typeof (ValueType));
1242                 }
1243                 
1244                 protected virtual bool IsContextfulImpl ()
1245                 {
1246                         return typeof (ContextBoundObject).IsAssignableFrom (this);
1247                 }
1248
1249                 protected virtual bool IsMarshalByRefImpl ()
1250                 {
1251                         return typeof (MarshalByRefObject).IsAssignableFrom (this);
1252                 }
1253
1254                 [ComVisible (true)]
1255                 public ConstructorInfo GetConstructor (Type[] types)
1256                 {
1257                         return GetConstructor (BindingFlags.Public|BindingFlags.Instance, null, CallingConventions.Any, types, null);
1258                 }
1259
1260                 [ComVisible (true)]
1261                 public ConstructorInfo GetConstructor (BindingFlags bindingAttr, Binder binder,
1262                                                        Type[] types, ParameterModifier[] modifiers)
1263                 {
1264                         return GetConstructor (bindingAttr, binder, CallingConventions.Any, types, modifiers);
1265                 }
1266
1267                 [ComVisible (true)]
1268                 public ConstructorInfo GetConstructor (BindingFlags bindingAttr, Binder binder,
1269                                                        CallingConventions callConvention,
1270                                                        Type[] types, ParameterModifier[] modifiers)
1271                 {
1272                         if (types == null)
1273                                 throw new ArgumentNullException ("types");
1274
1275                         foreach (Type t in types) {
1276                                 if (t == null)
1277                                         throw new ArgumentNullException ("types");
1278                         }
1279
1280                         return GetConstructorImpl (bindingAttr, binder, callConvention, types, modifiers);
1281                 }
1282
1283                 [ComVisible (true)]
1284                 public ConstructorInfo[] GetConstructors ()
1285                 {
1286                         return GetConstructors (BindingFlags.Public | BindingFlags.Instance);
1287                 }
1288
1289                 [ComVisible (true)]
1290                 public abstract ConstructorInfo[] GetConstructors (BindingFlags bindingAttr);
1291
1292                 public virtual MemberInfo[] GetDefaultMembers ()
1293                 {
1294                         object [] att = GetCustomAttributes (typeof (DefaultMemberAttribute), true);
1295                         if (att.Length == 0)
1296                                 return EmptyArray<MemberInfo>.Value;
1297
1298                         MemberInfo [] member = GetMember (((DefaultMemberAttribute) att [0]).MemberName);
1299                         return (member != null) ? member : EmptyArray<MemberInfo>.Value;
1300                 }
1301
1302                 public virtual MemberInfo[] FindMembers (MemberTypes memberType, BindingFlags bindingAttr,
1303                                                          MemberFilter filter, object filterCriteria)
1304                 {
1305                         MemberInfo[] result;
1306                         ArrayList l = new ArrayList ();
1307
1308                         // Console.WriteLine ("FindMembers for {0} (Type: {1}): {2}",
1309                         // this.FullName, this.GetType().FullName, this.obj_address());
1310                         if ((memberType & MemberTypes.Method) != 0) {
1311                                 MethodInfo[] c = GetMethods (bindingAttr);
1312                                 if (filter != null) {
1313                                         foreach (MemberInfo m in c) {
1314                                                 if (filter (m, filterCriteria))
1315                                                         l.Add (m);
1316                                         }
1317                                 } else {
1318                                         l.AddRange (c);
1319                                 }
1320                         }
1321                         if ((memberType & MemberTypes.Constructor) != 0) {
1322                                 ConstructorInfo[] c = GetConstructors (bindingAttr);
1323                                 if (filter != null) {
1324                                         foreach (MemberInfo m in c) {
1325                                                 if (filter (m, filterCriteria))
1326                                                         l.Add (m);
1327                                         }
1328                                 } else {
1329                                         l.AddRange (c);
1330                                 }
1331                         }
1332                         if ((memberType & MemberTypes.Property) != 0) {
1333                                 PropertyInfo[] c = GetProperties (bindingAttr);
1334
1335
1336                                 if (filter != null) {
1337                                         foreach (MemberInfo m in c) {
1338                                                 if (filter (m, filterCriteria))
1339                                                         l.Add (m);
1340                                         }
1341                                 } else {
1342                                         l.AddRange (c);
1343                                 }
1344
1345                         }
1346                         if ((memberType & MemberTypes.Event) != 0) {
1347                                 EventInfo[] c = GetEvents (bindingAttr);
1348                                 if (filter != null) {
1349                                         foreach (MemberInfo m in c) {
1350                                                 if (filter (m, filterCriteria))
1351                                                         l.Add (m);
1352                                         }
1353                                 } else {
1354                                         l.AddRange (c);
1355                                 }
1356                         }
1357                         if ((memberType & MemberTypes.Field) != 0) {
1358                                 FieldInfo[] c = GetFields (bindingAttr);
1359                                 if (filter != null) {
1360                                         foreach (MemberInfo m in c) {
1361                                                 if (filter (m, filterCriteria))
1362                                                         l.Add (m);
1363                                         }
1364                                 } else {
1365                                         l.AddRange (c);
1366                                 }
1367                         }
1368                         if ((memberType & MemberTypes.NestedType) != 0) {
1369                                 Type[] c = GetNestedTypes (bindingAttr);
1370                                 if (filter != null) {
1371                                         foreach (MemberInfo m in c) {
1372                                                 if (filter (m, filterCriteria)) {
1373                                                         l.Add (m);
1374                                                 }
1375                                         }
1376                                 } else {
1377                                         l.AddRange (c);
1378                                 }
1379                         }
1380
1381                         switch (memberType) {
1382                         case MemberTypes.Constructor :
1383                                 result = new ConstructorInfo [l.Count];
1384                                 break;
1385                         case MemberTypes.Event :
1386                                 result = new EventInfo [l.Count];
1387                                 break;
1388                         case MemberTypes.Field :
1389                                 result = new FieldInfo [l.Count];
1390                                 break;
1391                         case MemberTypes.Method :
1392                                 result = new MethodInfo [l.Count];
1393                                 break;
1394                         case MemberTypes.NestedType :
1395                         case MemberTypes.TypeInfo :
1396                                 result = new Type [l.Count];
1397                                 break;
1398                         case MemberTypes.Property :
1399                                 result = new PropertyInfo [l.Count];
1400                                 break;
1401                         default :
1402                                 result = new MemberInfo [l.Count];
1403                                 break;
1404                         }
1405                         l.CopyTo (result);
1406                         return result;
1407                 }
1408
1409                 [DebuggerHidden]
1410                 [DebuggerStepThrough] 
1411                 public object InvokeMember (string name, BindingFlags invokeAttr, Binder binder, object target, object[] args)
1412                 {
1413                         return InvokeMember (name, invokeAttr, binder, target, args, null, null, null);
1414                 }
1415
1416                 [DebuggerHidden]
1417                 [DebuggerStepThrough] 
1418                 public object InvokeMember (string name, BindingFlags invokeAttr, Binder binder,
1419                                             object target, object[] args, CultureInfo culture)
1420                 {
1421                         return InvokeMember (name, invokeAttr, binder, target, args, null, culture, null);
1422                 }
1423
1424                 public abstract object InvokeMember (string name, BindingFlags invokeAttr,
1425                                                      Binder binder, object target, object[] args,
1426                                                      ParameterModifier[] modifiers,
1427                                                      CultureInfo culture, string[] namedParameters);
1428
1429                 public override string ToString()
1430                 {
1431                         return FullName;
1432                 }
1433
1434                 internal static bool ShouldPrintFullName (Type type)
1435                 {
1436                         return type.IsGenericType || (type.IsClass && (!type.IsPointer ||
1437                                 (!type.GetElementType ().IsPrimitive && !type.GetElementType ().IsNested)));
1438                 }
1439
1440                 internal virtual Type InternalResolve ()
1441                 {
1442                         return UnderlyingSystemType;
1443                 }
1444
1445                 internal bool IsSystemType {
1446                         get {
1447                                 return _impl.Value != IntPtr.Zero;
1448                         }
1449                 }
1450                 
1451 #if NET_4_5
1452                 public virtual Type[] GenericTypeArguments {
1453                         get {
1454                                 return IsGenericType ? GetGenericArguments () : EmptyTypes;
1455                         }
1456                 }
1457 #endif
1458
1459                 public virtual Type[] GetGenericArguments ()
1460                 {
1461                         throw new NotSupportedException ();
1462                 }
1463
1464                 public virtual bool ContainsGenericParameters {
1465                         get { return false; }
1466                 }
1467
1468                 public virtual extern bool IsGenericTypeDefinition {
1469                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1470                         get;
1471                 }
1472
1473                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1474                 internal extern Type GetGenericTypeDefinition_impl ();
1475
1476                 public virtual Type GetGenericTypeDefinition ()
1477                 {
1478                         throw new NotSupportedException ("Derived classes must provide an implementation.");
1479                 }
1480
1481                 public virtual extern bool IsGenericType {
1482                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1483                         get;
1484                 }
1485                 
1486                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1487                 static extern Type MakeGenericType (Type gt, Type [] types);
1488
1489                 public virtual Type MakeGenericType (params Type[] typeArguments)
1490                 {
1491                         if (IsUserType)
1492                                 throw new NotSupportedException ();
1493                         if (!IsGenericTypeDefinition)
1494                                 throw new InvalidOperationException ("not a generic type definition");
1495                         if (typeArguments == null)
1496                                 throw new ArgumentNullException ("typeArguments");
1497                         if (GetGenericArguments().Length != typeArguments.Length)
1498                                 throw new ArgumentException (String.Format ("The type or method has {0} generic parameter(s) but {1} generic argument(s) where provided. A generic argument must be provided for each generic parameter.", GetGenericArguments ().Length, typeArguments.Length), "typeArguments");
1499
1500                         bool hasUserType = false;
1501
1502                         Type[] systemTypes = new Type[typeArguments.Length];
1503                         for (int i = 0; i < typeArguments.Length; ++i) {
1504                                 Type t = typeArguments [i];
1505                                 if (t == null)
1506                                         throw new ArgumentNullException ("typeArguments");
1507
1508                                 if (!(t is MonoType))
1509                                         hasUserType = true;
1510                                 systemTypes [i] = t;
1511                         }
1512
1513                         if (hasUserType) {
1514 #if FULL_AOT_RUNTIME
1515                                 throw new NotSupportedException ("User types are not supported under full aot");
1516 #else
1517                                 return new MonoGenericClass (this, typeArguments);
1518 #endif
1519                         }
1520
1521                         Type res = MakeGenericType (this, systemTypes);
1522                         if (res == null)
1523                                 throw new TypeLoadException ();
1524                         return res;
1525                 }
1526
1527                 public virtual bool IsGenericParameter {
1528                         get {
1529                                 return false;
1530                         }
1531                 }
1532
1533                 public bool IsNested {
1534                         get {
1535                                 return DeclaringType != null;
1536                         }
1537                 }
1538
1539                 public bool IsVisible {
1540                         get {
1541                                 if (IsNestedPublic)
1542                                         return DeclaringType.IsVisible;
1543
1544                                 return IsPublic;
1545                         }
1546                 }
1547
1548                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1549                 extern int GetGenericParameterPosition ();
1550                 
1551                 public virtual int GenericParameterPosition {
1552                         get {
1553                                 int res = GetGenericParameterPosition ();
1554                                 if (res < 0)
1555                                         throw new InvalidOperationException ();
1556                                 return res;
1557                         }
1558                 }
1559
1560                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1561                 extern GenericParameterAttributes GetGenericParameterAttributes ();
1562
1563                 public virtual GenericParameterAttributes GenericParameterAttributes {
1564                         get {
1565                                 if (!IsSystemType)
1566                                         throw new NotSupportedException ("Derived classes must provide an implementation.");
1567
1568                                 if (!IsGenericParameter)
1569                                         throw new InvalidOperationException ();
1570
1571                                 return GetGenericParameterAttributes ();
1572                         }
1573                 }
1574
1575                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1576                 extern Type[] GetGenericParameterConstraints_impl ();
1577
1578                 public virtual Type[] GetGenericParameterConstraints ()
1579                 {
1580                         if (!IsSystemType)
1581                                 throw new InvalidOperationException ();
1582
1583                         if (!IsGenericParameter)
1584                                 throw new InvalidOperationException ();
1585
1586                         return GetGenericParameterConstraints_impl ();
1587                 }
1588
1589                 public virtual MethodBase DeclaringMethod {
1590                         get {
1591                                 return null;
1592                         }
1593                 }
1594
1595                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1596                 extern Type make_array_type (int rank);
1597
1598                 public virtual Type MakeArrayType ()
1599                 {
1600                         if (!IsSystemType)
1601                                 throw new NotSupportedException ("Derived classes must provide an implementation.");
1602                         return make_array_type (0);
1603                 }
1604
1605                 public virtual Type MakeArrayType (int rank)
1606                 {
1607                         if (!IsSystemType)
1608                                 throw new NotSupportedException ("Derived classes must provide an implementation.");
1609                         if (rank < 1 || rank > 255)
1610                                 throw new IndexOutOfRangeException ();
1611                         return make_array_type (rank);
1612                 }
1613
1614                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1615                 extern Type make_byref_type ();
1616
1617                 public virtual Type MakeByRefType ()
1618                 {
1619                         if (!IsSystemType)
1620                                 throw new NotSupportedException ("Derived classes must provide an implementation.");
1621                         if (IsByRef)
1622                                 throw new TypeLoadException ("Can not call MakeByRefType on a ByRef type");
1623                         return make_byref_type ();
1624                 }
1625
1626                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1627                 static extern Type MakePointerType (Type type);
1628
1629                 public virtual Type MakePointerType ()
1630                 {
1631                         if (!IsSystemType)
1632                                 throw new NotSupportedException ("Derived classes must provide an implementation.");
1633                         return MakePointerType (this);
1634                 }
1635
1636                 public static Type ReflectionOnlyGetType (string typeName, 
1637                                                           bool throwIfNotFound, 
1638                                                           bool ignoreCase)
1639                 {
1640                         if (typeName == null)
1641                                 throw new ArgumentNullException ("typeName");
1642                         int idx = typeName.IndexOf (',');
1643                         if (idx < 0 || idx == 0 || idx == typeName.Length - 1)
1644                                 throw new ArgumentException ("Assembly qualifed type name is required", "typeName");
1645                         string an = typeName.Substring (idx + 1);
1646                         Assembly a;
1647                         try {
1648                                 a = Assembly.ReflectionOnlyLoad (an);
1649                         } catch {
1650                                 if (throwIfNotFound)
1651                                         throw;
1652                                 return null;
1653                         }
1654                         return a.GetType (typeName.Substring (0, idx), throwIfNotFound, ignoreCase);
1655                 }
1656
1657                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1658                 extern void GetPacking (out int packing, out int size);         
1659
1660                 public virtual StructLayoutAttribute StructLayoutAttribute {
1661                         get {
1662 #if NET_4_0
1663                                 throw new NotSupportedException ();
1664 #else
1665                                 return GetStructLayoutAttribute ();
1666 #endif
1667                         }
1668                 }
1669                 
1670                 internal StructLayoutAttribute GetStructLayoutAttribute ()
1671                 {
1672                         LayoutKind kind;
1673
1674                         if (IsLayoutSequential)
1675                                 kind = LayoutKind.Sequential;
1676                         else if (IsExplicitLayout)
1677                                 kind = LayoutKind.Explicit;
1678                         else
1679                                 kind = LayoutKind.Auto;
1680
1681                         StructLayoutAttribute attr = new StructLayoutAttribute (kind);
1682
1683                         if (IsUnicodeClass)
1684                                 attr.CharSet = CharSet.Unicode;
1685                         else if (IsAnsiClass)
1686                                 attr.CharSet = CharSet.Ansi;
1687                         else
1688                                 attr.CharSet = CharSet.Auto;
1689
1690                         if (kind != LayoutKind.Auto) {
1691                                 int packing;
1692                                 GetPacking (out packing, out attr.Size);
1693                                 // 0 means no data provided, we end up with default value
1694                                 if (packing != 0)
1695                                         attr.Pack = packing;
1696                         }
1697
1698                         return attr;
1699                 }
1700
1701                 internal object[] GetPseudoCustomAttributes ()
1702                 {
1703                         int count = 0;
1704
1705                         /* IsSerializable returns true for delegates/enums as well */
1706                         if ((Attributes & TypeAttributes.Serializable) != 0)
1707                                 count ++;
1708                         if ((Attributes & TypeAttributes.Import) != 0)
1709                                 count ++;
1710
1711                         if (count == 0)
1712                                 return null;
1713                         object[] attrs = new object [count];
1714                         count = 0;
1715
1716                         if ((Attributes & TypeAttributes.Serializable) != 0)
1717                                 attrs [count ++] = new SerializableAttribute ();
1718                         if ((Attributes & TypeAttributes.Import) != 0)
1719                                 attrs [count ++] = new ComImportAttribute ();
1720
1721                         return attrs;
1722                 }                       
1723
1724
1725 #if NET_4_0
1726                 public virtual bool IsEquivalentTo (Type other)
1727                 {
1728                         return this == other;
1729                 }
1730 #endif
1731
1732                 /* 
1733                  * Return whenever this object is an instance of a user defined subclass
1734                  * of System.Type or an instance of TypeDelegator.
1735                  * A user defined type is not simply the opposite of a system type.
1736                  * It's any class that's neither a SRE or runtime baked type.
1737                  */
1738                 internal virtual bool IsUserType {
1739                         get {
1740                                 return true;
1741                         }
1742                 }
1743
1744 #if !MOBILE
1745                 void _Type.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
1746                 {
1747                         throw new NotImplementedException ();
1748                 }
1749
1750                 void _Type.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
1751                 {
1752                         throw new NotImplementedException ();
1753                 }
1754
1755                 void _Type.GetTypeInfoCount (out uint pcTInfo)
1756                 {
1757                         throw new NotImplementedException ();
1758                 }
1759
1760                 void _Type.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
1761                 {
1762                         throw new NotImplementedException ();
1763                 }
1764 #endif
1765         }
1766 }