2008-07-24 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mcs / class / corlib / System / Type.cs
index d67c1f21d0f2ad8f08b0aa6077b474036b4c6113..fcf8986ef0bb59da56d50cc99d7a2f4fc1ea6517 100644 (file)
@@ -64,7 +64,7 @@ namespace System {
                static bool FilterName_impl (MemberInfo m, object filterCriteria)
                {
                        string name = (string) filterCriteria;
-               if (name == null || name.Length == 0 )
+                       if (name == null || name.Length == 0 )
                                return false; // because m.Name cannot be null or empty
                                
                        if (name [name.Length-1] == '*')
@@ -76,7 +76,7 @@ namespace System {
                static bool FilterNameIgnoreCase_impl (MemberInfo m, object filterCriteria)
                {
                        string name = (string) filterCriteria;
-               if (name == null || name.Length == 0 )
+                       if (name == null || name.Length == 0 )
                                return false; // because m.Name cannot be null or empty
                                
                        if (name [name.Length-1] == '*')
@@ -391,7 +391,13 @@ namespace System {
                        }
                }
 
+#if NET_2_0
+               public virtual RuntimeTypeHandle TypeHandle {
+                       get { return default (RuntimeTypeHandle); }
+               }
+#else
                public abstract RuntimeTypeHandle TypeHandle {get;}
+#endif
 
 #if NET_2_0
                [ComVisible (true)]
@@ -407,6 +413,10 @@ namespace System {
                        }
                }
 
+               /*
+                * This has NOTHING to do with getting the base type of an enum. Use
+                * Enum.GetUnderlyingType () for that.
+                */
                public abstract Type UnderlyingSystemType {get;}
 
                public override bool Equals (object o)
@@ -414,15 +424,20 @@ namespace System {
                        if (o == null)
                                return false;
                        
-                       // TODO: return UnderlyingSystemType == o.UnderlyingSystemType;
                        Type cmp = o as Type;
                        if (cmp == null)
                                return false;
                        return Equals (cmp);
                }
 
+               public bool Equals (Type o) {
+                       if (o == null)
+                               return false;
+                       return UnderlyingSystemType.EqualsInternal (o.UnderlyingSystemType);
+               }
+
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               public extern bool Equals (Type type);
+               internal extern bool EqualsInternal (Type type);
                
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                private static extern Type internal_from_handle (IntPtr handle);
@@ -433,7 +448,11 @@ namespace System {
                public static Type GetType(string typeName)
                {
                        if (typeName == null)
-                               throw new ArgumentNullException ("typeName");
+#if NET_2_0
+                               throw new ArgumentNullException ("TypeName");
+#else
+                               throw new ArgumentNullException ("className");
+#endif
 
                        return internal_from_name (typeName, false, false);
                }
@@ -441,7 +460,11 @@ namespace System {
                public static Type GetType(string typeName, bool throwOnError)
                {
                        if (typeName == null)
-                               throw new ArgumentNullException ("typeName");
+#if NET_2_0
+                               throw new ArgumentNullException ("TypeName");
+#else
+                               throw new ArgumentNullException ("className");
+#endif
 
                        Type type = internal_from_name (typeName, throwOnError, false);
                        if (throwOnError && type == null)
@@ -453,7 +476,11 @@ namespace System {
                public static Type GetType(string typeName, bool throwOnError, bool ignoreCase)
                {
                        if (typeName == null)
-                               throw new ArgumentNullException ("typeName");
+#if NET_2_0
+                               throw new ArgumentNullException ("TypeName");
+#else
+                               throw new ArgumentNullException ("className");
+#endif
 
                        Type t = internal_from_name (typeName, throwOnError, ignoreCase);
                        if (throwOnError && t == null)
@@ -477,6 +504,8 @@ namespace System {
                internal extern static TypeCode GetTypeCodeInternal (Type type);
 
                public static TypeCode GetTypeCode (Type type) {
+                       if (type is MonoType)
+                               return GetTypeCodeInternal (type);
                        if (type == null)
                                /* MS.NET returns this */
                                return TypeCode.Empty;
@@ -484,59 +513,68 @@ namespace System {
                        type = type.UnderlyingSystemType;
 
                        if (!type.IsSystemType)
-                               return Type.GetTypeCode (typeof (object));
+                               return TypeCode.Object;
                        else
                                return GetTypeCodeInternal (type);
                }
 
-               [MonoTODO]
+               [MonoTODO("Mono does not support COM")]
                public static Type GetTypeFromCLSID (Guid clsid)
                {
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
+               [MonoTODO("Mono does not support COM")]
                public static Type GetTypeFromCLSID (Guid clsid, bool throwOnError)
                {
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
+               [MonoTODO("Mono does not support COM")]
                public static Type GetTypeFromCLSID (Guid clsid, string server)
                {
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
+               [MonoTODO("Mono does not support COM")]
                public static Type GetTypeFromCLSID (Guid clsid, string server, bool throwOnError)
                {
                        throw new NotImplementedException ();
                }
 
                public static Type GetTypeFromHandle (RuntimeTypeHandle handle)
-               { 
+               {
+                       if (handle.Value == IntPtr.Zero)
+#if NET_2_0
+                               // This is not consistent with the other GetXXXFromHandle methods, but
+                               // MS.NET seems to do this
+                               return null;
+#else
+                               throw new ArgumentException ("The handle is invalid.");
+#endif
+
                        return internal_from_handle (handle.Value);
                }
 
-               [MonoTODO]
+               [MonoTODO("Mono does not support COM")]
                public static Type GetTypeFromProgID (string progID)
                {
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
+               [MonoTODO("Mono does not support COM")]
                public static Type GetTypeFromProgID (string progID, bool throwOnError)
                {
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
+               [MonoTODO("Mono does not support COM")]
                public static Type GetTypeFromProgID (string progID, string server)
                {
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
+               [MonoTODO("Mono does not support COM")]
                public static Type GetTypeFromProgID (string progID, string server, bool throwOnError)
                {
                        throw new NotImplementedException ();
@@ -544,6 +582,13 @@ namespace System {
 
                public static RuntimeTypeHandle GetTypeHandle (object o)
                {
+                       if (o == null)
+#if NET_2_0
+                               throw new ArgumentNullException ();
+#else
+                               throw new ArgumentNullException ("o");
+#endif
+
                        return o.GetType().TypeHandle;
                }
 
@@ -746,7 +791,6 @@ namespace System {
                public MethodInfo GetMethod (string name, BindingFlags bindingAttr, Binder binder,
                                             Type[] types, ParameterModifier[] modifiers)
                {
-                       
                        return GetMethod (name, bindingAttr, binder, CallingConventions.Any, types, modifiers);
                }
 
@@ -924,7 +968,7 @@ namespace System {
 #endif
                public ConstructorInfo GetConstructor (Type[] types)
                {
-                       return GetConstructor (DefaultBindingFlags, null, CallingConventions.Any, types, null);
+                       return GetConstructor (BindingFlags.Public|BindingFlags.Instance, null, CallingConventions.Any, types, null);
                }
 
 #if NET_2_0
@@ -1103,8 +1147,8 @@ namespace System {
                        throw new NotSupportedException ();
                }
 
-               public abstract bool ContainsGenericParameters {
-                       get;
+               public virtual bool ContainsGenericParameters {
+                       get { return false; }
                }
 
                public virtual extern bool IsGenericTypeDefinition {
@@ -1132,15 +1176,28 @@ namespace System {
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                static extern Type MakeGenericType (Type gt, Type [] types);
 
-               public virtual Type MakeGenericType (params Type[] types)
+               public virtual Type MakeGenericType (params Type[] typeArguments)
                {
-                       if (types == null)
-                               throw new ArgumentNullException ("types");
-                       foreach (Type t in types) {
+                       if (!IsGenericTypeDefinition)
+                               throw new InvalidOperationException ("not a generic type definition");
+                       if (typeArguments == null)
+                               throw new ArgumentNullException ("typeArguments");
+                       if (GetGenericArguments().Length != typeArguments.Length)
+                               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");
+
+                       Type[] systemTypes = new Type[typeArguments.Length];
+                       for (int i = 0; i < typeArguments.Length; ++i) {
+                               Type t = typeArguments [i];
                                if (t == null)
-                                       throw new ArgumentNullException ("types");
+                                       throw new ArgumentNullException ("typeArguments");
+
+                               t = t.UnderlyingSystemType;
+                               if (t == null || !t.IsSystemType)
+                                       throw new ArgumentNullException ("typeArguments");
+                               systemTypes [i] = typeArguments [i].UnderlyingSystemType;
                        }
-                       Type res = MakeGenericType (this, types);
+
+                       Type res = MakeGenericType (this, systemTypes);
                        if (res == null)
                                throw new TypeLoadException ();
                        return res;
@@ -1234,12 +1291,25 @@ namespace System {
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern virtual Type MakePointerType ();
 
-               [MonoTODO]
                public static Type ReflectionOnlyGetType (string typeName, 
-                                                                                                 bool throwIfNotFound, 
-                                                                                                 bool ignoreCase)
+                                                         bool throwIfNotFound, 
+                                                         bool ignoreCase)
                {
-                       throw new NotImplementedException ();
+                       if (typeName == null)
+                               throw new ArgumentNullException ("typeName");
+                       int idx = typeName.IndexOf (',');
+                       if (idx < 0 || idx == 0 || idx == typeName.Length - 1)
+                               throw new ArgumentException ("Assembly qualifed type name is required", "typeName");
+                       string an = typeName.Substring (idx + 1);
+                       Assembly a;
+                       try {
+                               a = Assembly.ReflectionOnlyLoad (an);
+                       } catch {
+                               if (throwIfNotFound)
+                                       throw;
+                               return null;
+                       }
+                       return a.GetType (typeName.Substring (0, idx), throwIfNotFound, ignoreCase);
                }
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]