Don't ignore Inherited flag in Attribute.IsDefined. Fixes #181
authorMarek Safar <marek.safar@gmail.com>
Thu, 3 Nov 2011 18:07:51 +0000 (18:07 +0000)
committerMarek Safar <marek.safar@gmail.com>
Fri, 4 Nov 2011 13:10:18 +0000 (13:10 +0000)
mcs/class/corlib/System/MonoCustomAttrs.cs
mcs/class/corlib/Test/System/AttributeTest.cs

index b887c55e02d699c7ad6023c6d1be872465bab8a3..dda41dd8c767c6c91ef9a0e19950bca9e84a8eca 100644 (file)
@@ -282,41 +282,32 @@ namespace System
                        if (attributeType == null)
                                throw new ArgumentNullException ("attributeType");
 
-                       if (IsUserCattrProvider (obj))
-                               return obj.IsDefined (attributeType, inherit);
+                       AttributeUsageAttribute usage = null;
+                       do {
+                               if (IsUserCattrProvider (obj))
+                                       return obj.IsDefined (attributeType, inherit);
+
+                               if (IsDefinedInternal (obj, attributeType))
+                                       return true;
+
+                               object[] pseudoAttrs = GetPseudoCustomAttributes (obj, attributeType);
+                               if (pseudoAttrs != null) {
+                                       for (int i = 0; i < pseudoAttrs.Length; ++i)
+                                               if (attributeType.IsAssignableFrom (pseudoAttrs[i].GetType ()))
+                                                       return true;
+                               }
 
-                       if (IsDefinedInternal (obj, attributeType))
-                               return true;
+                               if (usage == null) {
+                                       if (!inherit)
+                                               return false;
 
-                       object[] pseudoAttrs = GetPseudoCustomAttributes (obj, attributeType);
-                       if (pseudoAttrs != null) {
-                               for (int i = 0; i < pseudoAttrs.Length; ++i)
-                                       if (attributeType.IsAssignableFrom (pseudoAttrs [i].GetType ()))
-                                               return true;
-                       }
+                                       usage = RetrieveAttributeUsage (attributeType);
+                                       if (!usage.Inherited)
+                                               return false;
+                               }
 
-#if ONLY_1_1
-                       if (inherit) {
-                               AttributeUsageAttribute usage = RetrieveAttributeUsage (attributeType);
-                               if (!usage.Inherited)
-                                       inherit = false;
-                       }
-#endif
-
-                       // FIXME (bug #82431):
-                       // on 2.0 profile we should always walk the inheritance
-                       // chain and base the behavior on the inheritance level:
-                       //
-                       // 0  : return true if "attributeType" is assignable from
-                       // any of the custom attributes
-                       //
-                       // > 0: return true if "attributeType" is assignable from
-                       // any of the custom attributes and AttributeUsageAttribute
-                       // .Inherited of the assignable attribute is true
-
-                       ICustomAttributeProvider btype;
-                       if (inherit && ((btype = GetBase (obj)) != null))
-                               return IsDefined (btype, attributeType, inherit);
+                               obj = GetBase (obj);
+                       } while (obj != null);
 
                        return false;
                }
index d9f2d601993b2a9209b4aba281762a8359999a3e..a4e162bc26fb645fb4b6e9edcf67ee9eb2e437d7 100644 (file)
@@ -82,6 +82,10 @@ namespace MonoTests.System
                        {
                        }
                }
+
+               class MyDerivedClassNoAttribute : MyClass
+               {
+               }
        }
 
        [TestFixture]
@@ -100,6 +104,7 @@ namespace MonoTests.System
                        Assert.IsFalse (Attribute.IsDefined (typeof (MyDerivedClass), typeof (YourCustomAttribute), false), "#8");
                        Assert.IsFalse (Attribute.IsDefined (typeof (MyDerivedClass), typeof (UnusedAttribute), false), "#9");
                        Assert.IsTrue (Attribute.IsDefined (typeof (MyClass).GetMethod ("ParamsMethod").GetParameters () [0], typeof (ParamArrayAttribute), false), "#10");
+                       Assert.IsFalse (Attribute.IsDefined (typeof (MyDerivedClassNoAttribute), typeof (MyCustomAttribute)), "#11");
                }
 
                [Test]
@@ -134,17 +139,9 @@ namespace MonoTests.System
                public void IsDefined_PropertyInfo_Override ()
                {
                        PropertyInfo pi = typeof (TestSub).GetProperty ("PropBase3");
-#if NET_2_0
                        Assert.IsTrue (Attribute.IsDefined (pi, typeof (PropTestAttribute)), "#B1");
-#else
-                       Assert.IsFalse (Attribute.IsDefined (pi, typeof (PropTestAttribute)), "#B1");
-#endif
                        Assert.IsFalse (Attribute.IsDefined (pi, typeof (PropTestAttribute), false), "#B2");
-#if NET_2_0
                        Assert.IsTrue (Attribute.IsDefined (pi, typeof (PropTestAttribute), true), "#B3");
-#else
-                       Assert.IsFalse (Attribute.IsDefined (pi, typeof (PropTestAttribute), true), "#B3");
-#endif
                        Assert.IsFalse (Attribute.IsDefined (pi, typeof (ComVisibleAttribute)), "#B4");
                        Assert.IsFalse (Attribute.IsDefined (pi, typeof (ComVisibleAttribute), false), "#B5");
                        Assert.IsFalse (Attribute.IsDefined (pi, typeof (ComVisibleAttribute), true), "#B6");