2010-03-18 Carlos Alberto Cortez <calberto.cortez@gmail.com>
[mono.git] / mcs / class / corlib / System / MonoType.cs
index f4a7f950497184d64d185b645f525f2da906ef28..d4a19182c9ef0394ff6cfe36e10c15557d922bc7 100644 (file)
@@ -30,6 +30,7 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
+using System.Collections.Generic;
 using System.Globalization;
 using System.Reflection;
 using System.Runtime.CompilerServices;
@@ -38,9 +39,17 @@ using System.Security;
 
 namespace System
 {
+       // Contains information about the type which is expensive to compute
+       internal class MonoTypeInfo {
+               public string full_name;
+               public ConstructorInfo default_ctor;
+       }
+               
        [Serializable]
        internal class MonoType : Type, ISerializable
        {
+               [NonSerialized]
+               MonoTypeInfo type_info;
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                private static extern void type_from_obj (MonoType type, Object obj);
@@ -55,7 +64,21 @@ namespace System
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                private static extern TypeAttributes get_attributes (Type type);
+
+               internal ConstructorInfo GetDefaultConstructor () {
+                       ConstructorInfo ctor = null;
+                       
+                       if (type_info == null)
+                               type_info = new MonoTypeInfo ();
+                       if ((ctor = type_info.default_ctor) == null) {
+                               const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic;
        
+                               ctor = type_info.default_ctor = GetConstructor (flags,  null, CallingConventions.Any, Type.EmptyTypes, null);
+                       }
+
+                       return ctor;
+               }
+
                protected override TypeAttributes GetAttributeFlagsImpl ()
                {
                        return get_attributes (this);
@@ -66,11 +89,20 @@ namespace System
                                                                       CallingConventions callConvention,
                                                                       Type[] types,
                                                                       ParameterModifier[] modifiers)
+               {
+                       ConstructorInfo[] methods = GetConstructors (bindingAttr);
+                       return GetConstructorImpl (methods, bindingAttr, binder, callConvention, types, modifiers);
+               }
+
+               internal static ConstructorInfo GetConstructorImpl (ConstructorInfo[] methods, BindingFlags bindingAttr,
+                                                                      Binder binder,
+                                                                      CallingConventions callConvention,
+                                                                      Type[] types,
+                                                                      ParameterModifier[] modifiers)
                {
                        if (bindingAttr == BindingFlags.Default)
                                bindingAttr = BindingFlags.Public | BindingFlags.Instance;
 
-                       ConstructorInfo[] methods = GetConstructors (bindingAttr);
                        ConstructorInfo found = null;
                        MethodBase[] match;
                        int count = 0;
@@ -229,11 +261,15 @@ namespace System
 
                internal override MethodInfo GetMethod (MethodInfo fromNoninstanciated)
                 {
+                       if (fromNoninstanciated == null)
+                               throw new ArgumentNullException ("fromNoninstanciated");
                         return GetCorrespondingInflatedMethod (fromNoninstanciated);
                 }
 
                internal override ConstructorInfo GetConstructor (ConstructorInfo fromNoninstanciated)
                {
+                       if (fromNoninstanciated == null)
+                               throw new ArgumentNullException ("fromNoninstanciated");
                         return GetCorrespondingInflatedConstructor (fromNoninstanciated);
                }
 
@@ -270,7 +306,8 @@ namespace System
                        if (count == 0)
                                return null;
                        
-                       if (count == 1 && (types == null || types.Length == 0)) 
+                       if (count == 1 && (types == null || types.Length == 0) && 
+                           (returnType == null || returnType == props[0].PropertyType))
                                return props [0];
 
                        if (binder == null)
@@ -314,11 +351,7 @@ namespace System
                                                     ParameterModifier[] modifiers,
                                                     CultureInfo culture, string[] namedParameters)
                {
-#if NET_2_0
                        const string bindingflags_arg = "bindingFlags";
-#else
-                       const string bindingflags_arg = "invokeAttr";
-#endif
 
 
                        if ((invokeAttr & BindingFlags.CreateInstance) != 0) {
@@ -378,6 +411,8 @@ namespace System
                        if ((invokeAttr & BindingFlags.InvokeMethod) != 0) {
                                MethodInfo[] methods = GetMethodsByName (name, invokeAttr, ignoreCase, this);
                                object state = null;
+                               if (args == null)
+                                       args = new object [0];
                                MethodBase m = binder.BindToMethod (invokeAttr, methods, ref args, modifiers, culture, namedParameters, out state);
                                if (m == null) {
                                        if (methods.Length > 0)
@@ -388,7 +423,7 @@ namespace System
                                        ParameterInfo[] parameters = m.GetParameters();
                                        for (int i = 0; i < parameters.Length; ++i) {
                                                if (System.Reflection.Missing.Value == args [i] && (parameters [i].Attributes & ParameterAttributes.HasDefault) != ParameterAttributes.HasDefault)
-                                                       throw new ArgumentException (parameters [i].Name);
+                                                       throw new ArgumentException ("Used Missing.Value for argument without default value", "parameters");
                                        }
                                        bool hasParamArray = parameters.Length > 0 ? Attribute.IsDefined (parameters [parameters.Length - 1], 
                                                typeof (ParamArrayAttribute)) : false;
@@ -410,10 +445,8 @@ namespace System
                        } else if ((invokeAttr & BindingFlags.SetField) != 0) {
                                FieldInfo f = GetField (name, invokeAttr);
                                if (f != null) {
-#if NET_2_0
                                        if (args == null)
                                                throw new ArgumentNullException ("providedArgs");
-#endif
                                        if ((args == null) || args.Length != 1)
                                                throw new ArgumentException ("Only the field value can be specified to set a field value.", bindingflags_arg);
                                        f.SetValue (target, args [0]);
@@ -519,7 +552,14 @@ namespace System
 
                public override string FullName {
                        get {
-                               return getFullName (true, false);
+                               string fullName;
+                               // This doesn't need locking
+                               if (type_info == null)
+                                       type_info = new MonoTypeInfo ();
+                               if ((fullName = type_info.full_name) == null)
+                                       fullName = type_info.full_name = getFullName (true, false);
+
+                               return fullName;
                        }
                }
 
@@ -554,7 +594,7 @@ namespace System
 
                public override MemberTypes MemberType {
                        get {
-                               if (DeclaringType != null)
+                               if (DeclaringType != null && !IsGenericParameter)
                                        return MemberTypes.NestedType;
                                else
                                        return MemberTypes.TypeInfo;
@@ -606,7 +646,6 @@ namespace System
                        return getFullName (false, false);
                }
 
-#if NET_2_0 || BOOTSTRAP_NET_2_0
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern override Type [] GetGenericArguments ();
 
@@ -637,10 +676,34 @@ namespace System
                        [MethodImplAttribute(MethodImplOptions.InternalCall)]
                        get;
                }
+
+               public override Type GetGenericTypeDefinition () {
+                       Type res = GetGenericTypeDefinition_impl ();
+                       if (res == null)
+                               throw new InvalidOperationException ();
+
+                       return res;
+               }
+
+#if NET_4_0
+               public override IList<CustomAttributeData> GetCustomAttributesData () {
+                       return CustomAttributeData.GetCustomAttributes (this);
+               }
+
+
+               public override Array GetEnumValues () {
+                       if (!IsEnum)
+                               throw new ArgumentException ("Type is not an enumeration", "enumType");
+
+                       return Enum.GetValues (this);
+               }
 #endif
 
-               private MethodBase CheckMethodSecurity (MethodBase mb)
+               static MethodBase CheckMethodSecurity (MethodBase mb)
                {
+#if NET_2_1
+                       return mb;
+#else
                        if (!SecurityManager.SecurityEnabled || (mb == null))
                                return mb;
 
@@ -651,6 +714,7 @@ namespace System
 
                        // this (unlike the Invoke step) is _and stays_ a LinkDemand (caller)
                        return SecurityManager.ReflectedLinkDemandQuery (mb) ? mb : null;
+#endif
                }
 
                void ReorderParamArrayArguments(ref object[] args, MethodBase method)
@@ -671,5 +735,27 @@ namespace System
                        newArgs [parameters.Length - 1] = paramArray;
                        args = newArgs;
                }
+
+#if NET_4_0
+               //seclevel { transparent = 0, safe-critical = 1, critical = 2}
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               public extern int get_core_clr_security_level ();
+
+               public override bool IsSecurityTransparent
+               {
+                       get { return get_core_clr_security_level () == 0; }
+               }
+
+               public override bool IsSecurityCritical
+               {
+                       get { return get_core_clr_security_level () > 0; }
+               }
+
+               public override bool IsSecuritySafeCritical
+               {
+                       get { return get_core_clr_security_level () == 1; }
+               }
+#endif
+
        }
 }