2009-07-14 Rodrigo Kumpera <rkumpera@novell.com>
authorRodrigo Kumpera <kumpera@gmail.com>
Wed, 15 Jul 2009 00:23:22 +0000 (00:23 -0000)
committerRodrigo Kumpera <kumpera@gmail.com>
Wed, 15 Jul 2009 00:23:22 +0000 (00:23 -0000)
* Attribute.cs (GetCustomAttributes): Pass typeof(Attribute)
to GetCustomAttributes to match MS.

* MonoCustomAttrs.cs (GetCustomAttributesBase): Do proper
checking of which types are handled by the runtime.

* MonoCustomAttrs.cs (IsDefined): Same.

Fixes #521885.

2009-07-14 Rodrigo Kumpera  <rkumpera@novell.com>

* AttributeTest.cs: Add tests for user types passed to
Attribute.GetCustomAttribute[s].

svn path=/trunk/mcs/; revision=137908

mcs/class/corlib/System/Attribute.cs
mcs/class/corlib/System/ChangeLog
mcs/class/corlib/System/MonoCustomAttrs.cs
mcs/class/corlib/Test/System/AttributeTest.cs
mcs/class/corlib/Test/System/ChangeLog

index 9205c8b3b793f1adb076676537eb656c10593bfb..6739580aec7066f289f7e304b855f08ef2a47540 100644 (file)
@@ -262,7 +262,7 @@ namespace System
                        MemberTypes mtype = element.MemberType;
                        if (mtype == MemberTypes.Property)
                                return (Attribute []) MonoCustomAttrs.GetCustomAttributes (element, inherit);
-                       return (Attribute []) element.GetCustomAttributes (inherit);
+                       return (Attribute []) element.GetCustomAttributes (typeof (Attribute), inherit);
                }
 
                public static Attribute[] GetCustomAttributes (ParameterInfo element, bool inherit)
index 4e3918663d9fc4d2f79affd17bb73c03f0bfceb0..446d59cb15863164e8f7af3b605778b24f09f41c 100644 (file)
@@ -1,3 +1,15 @@
+2009-07-14  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * Attribute.cs (GetCustomAttributes): Pass typeof(Attribute)
+       to GetCustomAttributes to match MS.
+
+       * MonoCustomAttrs.cs (GetCustomAttributesBase): Do proper
+       checking of which types are handled by the runtime.
+
+       * MonoCustomAttrs.cs (IsDefined): Same.
+
+       Fixes #521885.
+
 2009-07-14  Zoltan Varga  <vargaz@gmail.com>
 
        * Environment.cs: Bump corlib version.
index ffd652499ae4383542ec50a0e219a58766f2241b..1e42bc64a73e1198c43d64cddcadb2749226139c 100644 (file)
@@ -35,6 +35,7 @@ using System;
 using System.Reflection;
 using System.Collections;
 using System.Runtime.CompilerServices;
+using System.Reflection.Emit;
 
 #if  NET_2_0
 using System.Collections.Generic;
@@ -44,6 +45,21 @@ namespace System
 {
        internal class MonoCustomAttrs
        {
+               static Assembly corlib;
+
+               /* Treat as user types all corlib types extending System.Type that are not MonoType and TypeBuilder */
+               static bool IsUserCattrProvider (object obj)
+               {
+                       Type type = obj as Type;
+                       if ((type is MonoType) || (type is TypeBuilder))
+                               return false;
+                       if ((obj is Type))
+                               return true;
+                       if (corlib == null)
+                                corlib = typeof (int).Assembly;
+                       return obj.GetType ().Assembly != corlib;
+               }
+       
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                internal static extern object[] GetCustomAttributesInternal (ICustomAttributeProvider obj, Type attributeType, bool pseudoAttrs);
 
@@ -79,7 +95,11 @@ namespace System
 
                internal static object[] GetCustomAttributesBase (ICustomAttributeProvider obj, Type attributeType)
                {
-                       object[] attrs = GetCustomAttributesInternal (obj, attributeType, false);
+                       object[] attrs;
+                       if (IsUserCattrProvider (obj))
+                               attrs = obj.GetCustomAttributes (attributeType, true);
+                       else
+                               attrs = GetCustomAttributesInternal (obj, attributeType, false);
 
                        object[] pseudoAttrs = GetPseudoCustomAttributes (obj, attributeType);
                        if (pseudoAttrs != null) {
@@ -266,12 +286,8 @@ namespace System
                        if (attributeType == null)
                                throw new ArgumentNullException ("attributeType");
 
-                       /* Avoid calling .Assembly if possible */
-                       Type otype = obj.GetType ();
-                       if (otype != typeof (MonoType) && otype.Assembly != typeof (int).Assembly)
-                               // User types might overwrite GetCustomAttributes () but not 
-                               // IsDefined ().
-                               return obj.GetCustomAttributes (attributeType, inherit).Length > 0;
+                       if (IsUserCattrProvider (obj))
+                               return obj.IsDefined (attributeType, inherit);
 
                        if (IsDefinedInternal (obj, attributeType))
                                return true;
index c7919bed2385e5333ce9f9a2450de955d906a569..707f6ae2058fd271ade8012938c3514e30d81ea6 100644 (file)
@@ -12,7 +12,9 @@
 
 using System;
 using System.Reflection;
+using System.Reflection.Emit;
 using System.Runtime.InteropServices;
+using System.Threading;
 
 using NUnit.Framework;
 
@@ -724,6 +726,144 @@ namespace MonoTests.System
                        Assert.IsFalse (a.Equals (null), "#8");
                }
 
+#if NET_2_0
+               class UserType : TypeDelegator {
+                       public int GetCattr1;
+                       public int GetCattr2;
+                       public int IsDef;
+                       public bool lastInherit;
+                       public Type lastAttrType;
+
+                       public UserType (Type type) : base (type) {}
+                       
+                       public override object [] GetCustomAttributes (bool inherit)
+                       {
+                               ++GetCattr1;
+                               lastInherit = inherit;
+                               lastAttrType = null;
+                               return base.GetCustomAttributes (inherit);
+                       }
+
+                       public override object [] GetCustomAttributes (Type attributeType, bool inherit)
+                       {
+                               ++GetCattr2;
+                               lastInherit = inherit;
+                               lastAttrType = attributeType;
+                               return base.GetCustomAttributes (attributeType, inherit);
+                       }
+
+                       public override bool IsDefined (Type attributeType, bool inherit)
+                       {
+                               ++IsDef;
+                               lastInherit = inherit;
+                               lastAttrType = attributeType;
+                               return base.IsDefined (attributeType, inherit);
+                       }
+               }
+
+               [Test]
+               public void GetCustomAttributeOnUserType ()
+               {
+                       UserType type = new UserType (typeof (AttributeTest));
+                       var res = Attribute.GetCustomAttribute (type, typeof (TestFixtureAttribute));
+                       Assert.IsNotNull (res, "#1");
+                       Assert.AreEqual (typeof (TestFixtureAttribute), res.GetType (), "#2");
+
+                       Assert.AreEqual (0, type.IsDef, "#4");
+                       Assert.AreEqual (0, type.GetCattr1, "#5");
+                       Assert.AreEqual (1, type.GetCattr2, "#6");
+                       Assert.IsTrue (type.lastInherit, "#7");
+                       Assert.AreEqual (typeof (TestFixtureAttribute), type.lastAttrType, "#8");
+               }
+
+               [Test]
+               public void GetCustomAttributeOnMethodInfo ()
+               {
+                       MemberInfo method = typeof (AttributeTest).GetMethod ("GetCustomAttributeOnMethodInfo");
+                       var res = Attribute.GetCustomAttribute (method, typeof (TestAttribute));
+
+                       Assert.IsNotNull (res, "#1");
+                       Assert.AreEqual (typeof (TestAttribute), res.GetType (), "#2");
+               }
+
+               [Test]
+               public void GetCustomAttributesOnUserType ()
+               {
+                       UserType type = new UserType (typeof (AttributeTest));
+                       var res = Attribute.GetCustomAttributes (type);
+                       Assert.IsNotNull (res, "#1");
+                       Assert.AreEqual (1, res.Length, "#2");
+                       Assert.AreEqual (typeof (TestFixtureAttribute), res [0].GetType (), "#3");
+
+                       Assert.AreEqual (0, type.IsDef, "#4");
+                       Assert.AreEqual (0, type.GetCattr1, "#5");
+                       Assert.AreEqual (1, type.GetCattr2, "#6");
+                       Assert.IsTrue (type.lastInherit, "#7");
+                       Assert.AreEqual (typeof (Attribute), type.lastAttrType, "#8");
+               }
+
+               [Test]
+               public void IsDefinedOnUserType ()
+               {
+                       UserType type = new UserType (typeof (AttributeTest));
+                       var res = Attribute.IsDefined (type, typeof (TestFixtureAttribute));
+                       Assert.IsTrue (res, "#1");
+
+                       Assert.AreEqual (1, type.IsDef, "#4");
+                       Assert.AreEqual (0, type.GetCattr1, "#5");
+                       Assert.AreEqual (0, type.GetCattr2, "#6");
+                       Assert.IsTrue (type.lastInherit, "#7");
+                       Assert.AreEqual (typeof (TestFixtureAttribute), type.lastAttrType, "#8");
+               }
+
+               [Test]
+               public void GetCustomAttributeOnNewSreTypes ()
+               {
+                       AssemblyName assemblyName = new AssemblyName ();
+                       assemblyName.Name = "MonoTests.System.Reflection.Emit.TypeBuilderTest";
+                       AssemblyBuilder assembly = Thread.GetDomain ().DefineDynamicAssembly (
+                                       assemblyName, AssemblyBuilderAccess.Run);
+                       ModuleBuilder module = assembly.DefineDynamicModule ("module1");
+
+                       var tb = module.DefineType ("ns.type", TypeAttributes.Public);
+                       var arr = tb.MakeArrayType ();
+                       var ptr = tb.MakePointerType ();
+                       var byref = tb.MakeByRefType ();
+
+                       try {
+                               Attribute.GetCustomAttribute (arr, typeof (ObsoleteAttribute));
+                               Assert.Fail ("#1");
+                       } catch (NotSupportedException) {}
+
+                       try {
+                               Attribute.GetCustomAttribute (ptr, typeof (ObsoleteAttribute));
+                               Assert.Fail ("#2");
+                       } catch (NotSupportedException) {}
+
+                       try {
+                               Attribute.GetCustomAttribute (byref, typeof (ObsoleteAttribute));
+                               Assert.Fail ("#3");
+                       } catch (NotSupportedException) {}
+               }
+
+               [Test]
+               [Category ("NotDotNet")]
+               public void GetCustomAttributeOnBadSreTypes ()
+               {
+                       AssemblyName assemblyName = new AssemblyName ();
+                       assemblyName.Name = "MonoTests.System.Reflection.Emit.TypeBuilderTest";
+                       AssemblyBuilder assembly = Thread.GetDomain ().DefineDynamicAssembly (
+                                       assemblyName, AssemblyBuilderAccess.Run);
+                       ModuleBuilder module = assembly.DefineDynamicModule ("module1");
+
+                       var tb = module.DefineType ("ns.type", TypeAttributes.Public);
+                       tb.DefineGenericParameters ("T");
+                       var ginst = tb.MakeGenericType (typeof (int));
+                       Assert.IsNull (Attribute.GetCustomAttribute (ginst, typeof (ObsoleteAttribute)), "#1");
+               }
+#endif
+
+
                private int GetAttributeCount (object[] attributes, Type attributeType)
                {
                        int counter = 0;
index 7b3504abc09dceb8341662c1f7f1676d656c1c01..ffbe67ee37ab283c349db51122280eb273bb1980 100644 (file)
@@ -1,3 +1,8 @@
+2009-07-14 Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * AttributeTest.cs: Add tests for user types passed to
+       Attribute.GetCustomAttribute[s].
+       
 2009-07-12  Gert Driesen  <drieseng@users.sourceforge.net>
 
        * TypeTest.cs: Enabled test that was failing due to regression.