From b79a0d627919d34608eb1c740b882f2040bbfdfc Mon Sep 17 00:00:00 2001 From: Rodrigo Kumpera Date: Wed, 15 Jul 2009 00:23:22 +0000 Subject: [PATCH] 2009-07-14 Rodrigo Kumpera * 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 * AttributeTest.cs: Add tests for user types passed to Attribute.GetCustomAttribute[s]. svn path=/trunk/mcs/; revision=137908 --- mcs/class/corlib/System/Attribute.cs | 2 +- mcs/class/corlib/System/ChangeLog | 12 ++ mcs/class/corlib/System/MonoCustomAttrs.cs | 30 +++- mcs/class/corlib/Test/System/AttributeTest.cs | 140 ++++++++++++++++++ mcs/class/corlib/Test/System/ChangeLog | 5 + 5 files changed, 181 insertions(+), 8 deletions(-) diff --git a/mcs/class/corlib/System/Attribute.cs b/mcs/class/corlib/System/Attribute.cs index 9205c8b3b79..6739580aec7 100644 --- a/mcs/class/corlib/System/Attribute.cs +++ b/mcs/class/corlib/System/Attribute.cs @@ -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) diff --git a/mcs/class/corlib/System/ChangeLog b/mcs/class/corlib/System/ChangeLog index 4e3918663d9..446d59cb158 100644 --- a/mcs/class/corlib/System/ChangeLog +++ b/mcs/class/corlib/System/ChangeLog @@ -1,3 +1,15 @@ +2009-07-14 Rodrigo Kumpera + + * 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 * Environment.cs: Bump corlib version. diff --git a/mcs/class/corlib/System/MonoCustomAttrs.cs b/mcs/class/corlib/System/MonoCustomAttrs.cs index ffd652499ae..1e42bc64a73 100644 --- a/mcs/class/corlib/System/MonoCustomAttrs.cs +++ b/mcs/class/corlib/System/MonoCustomAttrs.cs @@ -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; diff --git a/mcs/class/corlib/Test/System/AttributeTest.cs b/mcs/class/corlib/Test/System/AttributeTest.cs index c7919bed238..707f6ae2058 100644 --- a/mcs/class/corlib/Test/System/AttributeTest.cs +++ b/mcs/class/corlib/Test/System/AttributeTest.cs @@ -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; diff --git a/mcs/class/corlib/Test/System/ChangeLog b/mcs/class/corlib/Test/System/ChangeLog index 7b3504abc09..ffbe67ee37a 100644 --- a/mcs/class/corlib/Test/System/ChangeLog +++ b/mcs/class/corlib/Test/System/ChangeLog @@ -1,3 +1,8 @@ +2009-07-14 Rodrigo Kumpera + + * AttributeTest.cs: Add tests for user types passed to + Attribute.GetCustomAttribute[s]. + 2009-07-12 Gert Driesen * TypeTest.cs: Enabled test that was failing due to regression. -- 2.25.1