Merge pull request #487 from mayerwin/patch-1
[mono.git] / mcs / class / corlib / System / MonoCustomAttrs.cs
index acaa63f4f4a3151be80a93f8783a973fc563bae1..14641fbe66119662e4a5a903a73eb3316fc13627 100644 (file)
@@ -35,7 +35,10 @@ using System;
 using System.Reflection;
 using System.Collections;
 using System.Runtime.CompilerServices;
+#if !FULL_AOT_RUNTIME
 using System.Reflection.Emit;
+#endif
+
 using System.Collections.Generic;
 
 namespace System
@@ -48,7 +51,11 @@ namespace System
                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;
@@ -139,6 +146,9 @@ namespace System
                        // 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 ()))
@@ -184,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)
@@ -277,41 +289,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;
+                               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;
-                       }
+                               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 ONLY_1_1
-                       if (inherit) {
-                               AttributeUsageAttribute usage = RetrieveAttributeUsage (attributeType);
-                               if (!usage.Inherited)
-                                       inherit = false;
-                       }
-#endif
+                               if (usage == null) {
+                                       if (!inherit)
+                                               return false;
 
-                       // 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);
+                                       usage = RetrieveAttributeUsage (attributeType);
+                                       if (!usage.Inherited)
+                                               return false;
+                               }
+
+                               obj = GetBase (obj);
+                       } while (obj != null);
 
                        return false;
                }
@@ -327,7 +330,7 @@ namespace System
                        if (method == null || !method.IsVirtual)
                                return null;
 
-                       MethodInfo baseMethod = method.GetBaseDefinition ();
+                       MethodInfo baseMethod = method.GetBaseMethod ();
                        if (baseMethod != null && baseMethod != method) {
                                ParameterInfo[] parameters = property.GetIndexParameters ();
                                if (parameters != null && parameters.Length > 0) {
@@ -344,6 +347,26 @@ namespace System
 
                }
 
+               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.
@@ -358,6 +381,8 @@ namespace System
                        MethodInfo method = null;
                        if (obj is MonoProperty)
                                return GetBasePropertyDefinition ((MonoProperty) obj);
+                       else if (obj is MonoEvent)
+                               return GetBaseEventDefinition ((MonoEvent)obj);
                        else if (obj is MonoMethod)
                                method = (MethodInfo) obj;
 
@@ -370,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;
 
@@ -384,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
@@ -417,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);