X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2Fcorlib%2FSystem%2FMonoCustomAttrs.cs;h=14641fbe66119662e4a5a903a73eb3316fc13627;hb=01ea58cbd474d4a9230acbba5571738896539d42;hp=8659e7aa570a9eb30e180b878532bee4afc6796d;hpb=669beaed8380fa592533c8755f72593b4422d01d;p=mono.git diff --git a/mcs/class/corlib/System/MonoCustomAttrs.cs b/mcs/class/corlib/System/MonoCustomAttrs.cs index 8659e7aa570..14641fbe661 100644 --- a/mcs/class/corlib/System/MonoCustomAttrs.cs +++ b/mcs/class/corlib/System/MonoCustomAttrs.cs @@ -35,20 +35,39 @@ using System; using System.Reflection; using System.Collections; using System.Runtime.CompilerServices; +#if !FULL_AOT_RUNTIME +using System.Reflection.Emit; +#endif -#if NET_2_0 using System.Collections.Generic; -#endif 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 !FULL_AOT_RUNTIME + if ((type is MonoType) || (type is TypeBuilder)) +#else + if (type is MonoType) +#endif + 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); internal static object[] GetPseudoCustomAttributes (ICustomAttributeProvider obj, Type attributeType) { -#if NET_2_0 || BOOTSTRAP_NET_2_0 object[] pseudoAttrs = null; /* FIXME: Add other types */ @@ -72,14 +91,15 @@ namespace System } else return pseudoAttrs; -#else - return null; -#endif } 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) { @@ -115,12 +135,20 @@ namespace System { if (obj == null) throw new ArgumentNullException ("obj"); + if (attributeType == null) + throw new ArgumentNullException ("attributeType"); + if (attributeType == typeof (MonoCustomAttrs)) + attributeType = null; + object[] r; object[] res = GetCustomAttributesBase (obj, attributeType); // shortcut if (!inherit && res.Length == 1) { + if (res [0] == null) + throw new CustomAttributeFormatException ("Invalid custom attribute format"); + if (attributeType != null) { if (attributeType.IsAssignableFrom (res[0].GetType ())) @@ -166,6 +194,8 @@ namespace System foreach (object attr in res) { AttributeUsageAttribute usage; + if (attr == null) + throw new CustomAttributeFormatException ("Invalid custom attribute format"); Type attrType = attr.GetType (); if (attributeType != null) @@ -239,10 +269,9 @@ namespace System if (!inherit) return (object[]) GetCustomAttributesBase (obj, null).Clone (); - return GetCustomAttributes (obj, null, inherit); + return GetCustomAttributes (obj, typeof (MonoCustomAttrs), inherit); } -#if NET_2_0 [MethodImplAttribute (MethodImplOptions.InternalCall)] static extern CustomAttributeData [] GetCustomAttributesDataInternal (ICustomAttributeProvider obj); @@ -254,28 +283,38 @@ namespace System CustomAttributeData [] attrs = GetCustomAttributesDataInternal (obj); return Array.AsReadOnly (attrs); } -#endif internal static bool IsDefined (ICustomAttributeProvider obj, Type attributeType, bool inherit) { - if (obj.GetType ().Assembly != typeof (int).Assembly) - // User types might overwrite GetCustomAttributes () but not - // IsDefined (). - return obj.GetCustomAttributes (attributeType, inherit).Length > 0; + if (attributeType == null) + throw new ArgumentNullException ("attributeType"); + + 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; + } - ICustomAttributeProvider btype; - if (inherit && ((btype = GetBase (obj)) != null)) - return IsDefined (btype, attributeType, inherit); + obj = GetBase (obj); + } while (obj != null); return false; } @@ -283,6 +322,51 @@ namespace System [MethodImplAttribute (MethodImplOptions.InternalCall)] internal static extern bool IsDefinedInternal (ICustomAttributeProvider obj, Type AttributeType); + static PropertyInfo GetBasePropertyDefinition (PropertyInfo property) + { + MethodInfo method = property.GetGetMethod (true); + if (method == null || !method.IsVirtual) + method = property.GetSetMethod (true); + if (method == null || !method.IsVirtual) + return null; + + MethodInfo baseMethod = method.GetBaseMethod (); + if (baseMethod != null && baseMethod != method) { + ParameterInfo[] parameters = property.GetIndexParameters (); + if (parameters != null && parameters.Length > 0) { + Type[] paramTypes = new Type[parameters.Length]; + for (int i=0; i < paramTypes.Length; i++) + paramTypes[i] = parameters[i].ParameterType; + return baseMethod.DeclaringType.GetProperty (property.Name, property.PropertyType, + paramTypes); + } else { + return baseMethod.DeclaringType.GetProperty (property.Name, property.PropertyType); + } + } + return null; + + } + + static EventInfo GetBaseEventDefinition (EventInfo evt) + { + MethodInfo method = evt.GetAddMethod (true); + if (method == null || !method.IsVirtual) + method = evt.GetRaiseMethod (true); + if (method == null || !method.IsVirtual) + method = evt.GetRemoveMethod (true); + if (method == null || !method.IsVirtual) + return null; + + MethodInfo baseMethod = method.GetBaseMethod (); + if (baseMethod != null && baseMethod != method) { + BindingFlags flags = method.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic; + flags |= method.IsStatic ? BindingFlags.Static : BindingFlags.Instance; + + return baseMethod.DeclaringType.GetEvent (evt.Name, flags); + } + return null; + } + // Handles Type, MonoProperty and MonoMethod. // The runtime has also cases for MonoEvent, MonoField, Assembly and ParameterInfo, // but for those we return null here. @@ -296,16 +380,11 @@ namespace System MethodInfo method = null; if (obj is MonoProperty) - { - MonoProperty prop = (MonoProperty) obj; - method = prop.GetGetMethod (true); - if (method == null) - method = prop.GetSetMethod (true); - } + return GetBasePropertyDefinition ((MonoProperty) obj); + else if (obj is MonoEvent) + return GetBaseEventDefinition ((MonoEvent)obj); else if (obj is MonoMethod) - { method = (MethodInfo) obj; - } /** * ParameterInfo -> null @@ -316,7 +395,7 @@ namespace System if (method == null || !method.IsVirtual) return null; - MethodInfo baseMethod = method.GetBaseDefinition (); + MethodInfo baseMethod = method.GetBaseMethod (); if (baseMethod == method) return null; @@ -330,8 +409,7 @@ namespace System return new AttributeUsageAttribute (AttributeTargets.Class); AttributeUsageAttribute usageAttribute = null; - object[] attribs = GetCustomAttributes (attributeType, - MonoCustomAttrs.AttributeUsageType, false); + object[] attribs = GetCustomAttributes (attributeType, typeof(AttributeUsageAttribute), false); if (attribs.Length == 0) { // if no AttributeUsage was defined on the attribute level, then @@ -363,7 +441,6 @@ namespace System return ((AttributeUsageAttribute) attribs[0]); } - private static readonly Type AttributeUsageType = typeof(AttributeUsageAttribute); private static readonly AttributeUsageAttribute DefaultAttributeUsage = new AttributeUsageAttribute (AttributeTargets.All);