Switch to compiler-tester
[mono.git] / mcs / class / corlib / System / Type.cs
index 2a7619c0b4f833c6f955fc8a2bdebd81468abf49..286b6b4b7929c23ba8d4de72ba0cdac2e12c0359 100644 (file)
@@ -32,6 +32,7 @@
 
 using System.Diagnostics;
 using System.Reflection;
+using System.Reflection.Emit;
 using System.Collections;
 using System.Runtime.InteropServices;
 using System.Runtime.CompilerServices;
@@ -40,8 +41,12 @@ using System.Globalization;
 namespace System {
 
        [Serializable]
-       [ClassInterface (ClassInterfaceType.AutoDual)]
-       public abstract class Type : MemberInfo, IReflect {
+       [ClassInterface (ClassInterfaceType.None)]
+#if NET_2_0
+       [ComVisible (true)]
+       [ComDefaultInterface (typeof (_Type))]
+#endif
+       public abstract class Type : MemberInfo, IReflect, _Type, _MemberInfo {
                
                internal RuntimeTypeHandle _impl;
 
@@ -52,23 +57,32 @@ namespace System {
                public static readonly MemberFilter FilterNameIgnoreCase = new MemberFilter (FilterNameIgnoreCase_impl);
                public static readonly object Missing;
 
-               protected const BindingFlags DefaultBindingFlags =
+               internal const BindingFlags DefaultBindingFlags =
                BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance;
 
                /* implementation of the delegates for MemberFilter */
                static bool FilterName_impl (MemberInfo m, object filterCriteria)
                {
                        string name = (string) filterCriteria;
-                       return name.Equals (m.Name);
+               if (name == null || name.Length == 0 )
+                               return false; // because m.Name cannot be null or empty
+                               
+                       if (name [name.Length-1] == '*')
+                               return string.Compare (name, 0, m.Name, 0, name.Length-1, false, CultureInfo.InvariantCulture) == 0;
+
+               return name.Equals (m.Name);                    
                }
 
                static bool FilterNameIgnoreCase_impl (MemberInfo m, object filterCriteria)
                {
                        string name = (string) filterCriteria;
-                       if (name.Length != m.Name.Length)
-                               return false;
+               if (name == null || name.Length == 0 )
+                               return false; // because m.Name cannot be null or empty
+                               
+                       if (name [name.Length-1] == '*')
+                               return string.Compare (name, 0, m.Name, 0, name.Length-1, true, CultureInfo.InvariantCulture) == 0;
 
-                       return String.Compare (name, m.Name, true, CultureInfo.InvariantCulture) == 0;
+                       return String.Compare (name, m.Name, true, CultureInfo.InvariantCulture) == 0;                          
                }
 
                static bool FilterAttribute_impl (MemberInfo m, object filterCriteria)
@@ -202,7 +216,7 @@ namespace System {
                                        return true;
                                if (IsInterface)
                                        return false;
-                               return !type_is_subtype_of (this, typeof (System.ValueType), false);
+                               return !is_subtype_of (this, typeof (System.ValueType), false);
                        }
                }
 
@@ -220,7 +234,11 @@ namespace System {
 
                public bool IsEnum {
                        get {
-                               return type_is_subtype_of (this, typeof (System.Enum), false) &&
+                               // This hack is needed because EnumBuilder's UnderlyingSystemType returns the enum's basetype
+                               if (this is EnumBuilder)
+                                       return true;
+
+                               return is_subtype_of (this, typeof (System.Enum), false) &&
                                        this != typeof (System.Enum);
                        }
                }
@@ -325,7 +343,7 @@ namespace System {
                        get {
                                // Enums and delegates are always serializable
                                return (Attributes & TypeAttributes.Serializable) != 0 || IsEnum || 
-                                       type_is_subtype_of (this, typeof (System.Delegate), false);
+                                       is_subtype_of (this, typeof (System.Delegate), false);
                        }
                }
 
@@ -366,6 +384,9 @@ namespace System {
 
                public abstract RuntimeTypeHandle TypeHandle {get;}
 
+#if NET_2_0
+               [ComVisible (true)]
+#endif
                public ConstructorInfo TypeInitializer {
                        get {
                                return GetConstructorImpl (
@@ -444,7 +465,16 @@ namespace System {
                }
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               public extern static TypeCode GetTypeCode (Type type);
+               internal extern static TypeCode GetTypeCodeInternal (Type type);
+
+               public static TypeCode GetTypeCode (Type type) {
+                       type = type.UnderlyingSystemType;
+
+                       if (!type.IsSystemType)
+                               return Type.GetTypeCode (typeof (object));
+                       else
+                               return GetTypeCodeInternal (type);
+               }
 
                [MonoTODO]
                public static Type GetTypeFromCLSID (Guid clsid)
@@ -509,13 +539,27 @@ namespace System {
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                internal static extern bool type_is_assignable_from (Type a, Type b);
-               
+
+               internal static bool is_subtype_of (Type a, Type b, bool check_interfaces)
+               {
+                       a = a.UnderlyingSystemType;
+                       b = b.UnderlyingSystemType;
+
+                       if (!a.IsSystemType || !b.IsSystemType)
+                               return false;
+                       else
+                               return type_is_subtype_of (a, b, check_interfaces);
+               }
+
+#if NET_2_0
+               [ComVisible (true)]
+#endif
                public virtual bool IsSubclassOf (Type c)
                {
                        if (c == null)
                                return false;
 
-                       return (this != c) && type_is_subtype_of (this, c, false);
+                       return (this != c) && is_subtype_of (this, c, false);
                }
 
                public virtual Type[] FindInterfaces (TypeFilter filter, object filterCriteria)
@@ -540,7 +584,10 @@ namespace System {
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                internal static extern void GetInterfaceMapData (Type t, Type iface, out MethodInfo[] targets, out MethodInfo[] methods);
-               
+
+#if NET_2_0
+               [ComVisible (true)]
+#endif         
                public virtual InterfaceMapping GetInterfaceMap (Type interfaceType) {
                        InterfaceMapping res;
                        if (interfaceType == null)
@@ -566,6 +613,24 @@ namespace System {
                        if (Equals (c))
                                return true;
 
+                       if (c is TypeBuilder)
+                               return ((TypeBuilder)c).IsAssignableTo (this);
+
+                       /* Handle user defined type classes */
+                       if (!IsSystemType) {
+                               Type systemType = UnderlyingSystemType;
+                               if (!systemType.IsSystemType)
+                                       return false;
+                               return systemType.IsAssignableFrom (c);
+                       }
+
+                       if (!c.IsSystemType) {
+                               Type underlyingType = c.UnderlyingSystemType;
+                               if (!underlyingType.IsSystemType)
+                                       return false;
+                               return IsAssignableFrom (underlyingType);
+                       }
+
                        return type_is_assignable_from (this, c);
                }
 
@@ -688,6 +753,29 @@ namespace System {
                                                             CallingConventions callConvention, Type[] types,
                                                             ParameterModifier[] modifiers);
 
+               internal MethodInfo GetMethodImplInternal (string name, BindingFlags bindingAttr, Binder binder,
+                                                                                                                       CallingConventions callConvention, Type[] types,
+                                                                                                                       ParameterModifier[] modifiers)
+               {
+                       return GetMethodImpl (name, bindingAttr, binder, callConvention, types, modifiers);
+               }
+
+               internal virtual MethodInfo GetMethod (MethodInfo fromNoninstanciated)
+                {
+                       throw new System.InvalidOperationException ("can only be called in generic type");
+                }
+
+               internal virtual ConstructorInfo GetConstructor (ConstructorInfo fromNoninstanciated)
+                {
+                       throw new System.InvalidOperationException ("can only be called in generic type");
+                }
+
+               internal virtual FieldInfo GetField (FieldInfo fromNoninstanciated)
+                {
+                       throw new System.InvalidOperationException ("can only be called in generic type");
+                }
+
+               
                public MethodInfo[] GetMethods ()
                {
                        return GetMethods (DefaultBindingFlags);
@@ -723,21 +811,21 @@ namespace System {
                        if (name == null)
                                throw new ArgumentNullException ("name");
 
-                       return GetPropertyImpl (name, DefaultBindingFlags, null, null, new Type[0], null);
+                       return GetPropertyImpl (name, DefaultBindingFlags, null, null, null, null);
                }
 
                public PropertyInfo GetProperty (string name, BindingFlags bindingAttr)
                {
                        if (name == null)
                                throw new ArgumentNullException ("name");
-                       return GetPropertyImpl (name, bindingAttr, null, null, new Type[0], null);
+                       return GetPropertyImpl (name, bindingAttr, null, null, null, null);
                }
 
                public PropertyInfo GetProperty (string name, Type returnType)
                {
                        if (name == null)
                                throw new ArgumentNullException ("name");
-                       return GetPropertyImpl (name, DefaultBindingFlags, null, returnType, new Type[0], null);
+                       return GetPropertyImpl (name, DefaultBindingFlags, null, returnType, null, null);
                }
 
                public PropertyInfo GetProperty (string name, Type[] types)
@@ -769,6 +857,12 @@ namespace System {
                protected abstract PropertyInfo GetPropertyImpl (string name, BindingFlags bindingAttr, Binder binder,
                                                                 Type returnType, Type[] types, ParameterModifier[] modifiers);
 
+               internal PropertyInfo GetPropertyImplInternal (string name, BindingFlags bindingAttr, Binder binder,
+                                                                                                          Type returnType, Type[] types, ParameterModifier[] modifiers)
+               {
+                       return GetPropertyImpl (name, bindingAttr, binder, returnType, types, modifiers);
+               }
+
                protected abstract ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr,
                                                                       Binder binder,
                                                                       CallingConventions callConvention,
@@ -804,12 +898,18 @@ namespace System {
                        return typeof (MarshalByRefObject).IsAssignableFrom (this);
                }
 
+#if NET_2_0
+               [ComVisible (true)]
+#endif
                public ConstructorInfo GetConstructor (Type[] types)
                {
                        return GetConstructorImpl (
                                DefaultBindingFlags, null, CallingConventions.Any, types, null);
                }
 
+#if NET_2_0
+               [ComVisible (true)]
+#endif
                public ConstructorInfo GetConstructor (BindingFlags bindingAttr, Binder binder,
                                                       Type[] types, ParameterModifier[] modifiers)
                {
@@ -817,6 +917,9 @@ namespace System {
                                bindingAttr, binder, CallingConventions.Any, types, modifiers);
                }
 
+#if NET_2_0
+               [ComVisible (true)]
+#endif
                public ConstructorInfo GetConstructor (BindingFlags bindingAttr, Binder binder,
                                                       CallingConventions callConvention,
                                                       Type[] types, ParameterModifier[] modifiers)
@@ -827,11 +930,17 @@ namespace System {
                        return GetConstructorImpl (bindingAttr, binder, callConvention, types, modifiers);
                }
 
+#if NET_2_0
+               [ComVisible (true)]
+#endif
                public ConstructorInfo[] GetConstructors ()
                {
                        return GetConstructors (BindingFlags.Public | BindingFlags.Instance);
                }
-               
+
+#if NET_2_0
+               [ComVisible (true)]
+#endif         
                public abstract ConstructorInfo[] GetConstructors (BindingFlags bindingAttr);
 
                public virtual MemberInfo[] GetDefaultMembers ()
@@ -958,23 +1067,10 @@ namespace System {
                        return FullName;
                }
 
-               internal object[] GetPseudoCustomAttributes () {
-                       int count = 0;
-
-                       /* StructLayoutAttribute is not returned by MS.NET */
-
-                       if (IsSerializable)
-                               count ++;
-
-                       if (count == 0)
-                               return null;
-                       object[] attrs = new object [count];
-                       count = 0;
-
-                       if (IsSerializable)
-                               attrs [count ++] = new SerializableAttribute ();
-
-                       return attrs;
+               internal bool IsSystemType {
+                       get {
+                               return _impl.Value != IntPtr.Zero;
+                       }
                }
 
 #if NET_2_0 || BOOTSTRAP_NET_2_0
@@ -1012,7 +1108,10 @@ namespace System {
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                static extern Type BindGenericParameters (Type gt, Type [] types);
-               
+
+#if NET_2_0
+               [ComVisible (true)]
+#endif         
                public Type BindGenericParameters (Type [] types)
                {
                        if (types == null)
@@ -1027,6 +1126,11 @@ namespace System {
                        return res;
                }
 
+                public Type MakeGenericType (Type[] types)
+                {
+                       return BindGenericParameters (types);
+                }
+
                public abstract bool IsGenericParameter {
                        get;
                }
@@ -1133,6 +1237,24 @@ namespace System {
                                return attr;
                        }
                }
+
+               internal object[] GetPseudoCustomAttributes () {
+                       int count = 0;
+
+                       if (IsSerializable)
+                               count ++;
+
+                       if (count == 0)
+                               return null;
+                       object[] attrs = new object [count];
+                       count = 0;
+
+                       if (IsSerializable)
+                               attrs [count ++] = new SerializableAttribute ();
+
+                       return attrs;
+               }                       
+
 #endif
        }
 }