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 */
}
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) {
{
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 ()))
foreach (object attr in res)
{
AttributeUsageAttribute usage;
+ if (attr == null)
+ throw new CustomAttributeFormatException ("Invalid custom attribute format");
Type attrType = attr.GetType ();
if (attributeType != null)
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);
CustomAttributeData [] attrs = GetCustomAttributesDataInternal (obj);
return Array.AsReadOnly<CustomAttributeData> (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;
}
[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.
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
if (method == null || !method.IsVirtual)
return null;
- MethodInfo baseMethod = method.GetBaseDefinition ();
+ MethodInfo baseMethod = method.GetBaseMethod ();
if (baseMethod == method)
return null;
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
return ((AttributeUsageAttribute) attribs[0]);
}
- private static readonly Type AttributeUsageType = typeof(AttributeUsageAttribute);
private static readonly AttributeUsageAttribute DefaultAttributeUsage =
new AttributeUsageAttribute (AttributeTargets.All);