1 // System.MonoCustomAttrs.cs
2 // Hooks into the runtime to get custom attributes for reflection handles
5 // Paolo Molaro (lupus@ximian.com)
6 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
8 // (c) 2002,2003 Ximian, Inc. (http://www.ximian.com)
12 using System.Reflection;
13 using System.Collections;
14 using System.Runtime.CompilerServices;
17 internal class MonoCustomAttrs {
19 static Hashtable handle_to_attrs = new Hashtable ();
21 [MethodImplAttribute(MethodImplOptions.InternalCall)]
22 internal static extern object[] GetCustomAttributes (ICustomAttributeProvider obj);
24 private static object[] from_cache (ICustomAttributeProvider obj)
26 object[] res = (object []) handle_to_attrs [obj];
29 res = GetCustomAttributes (obj);
30 handle_to_attrs.Add (obj, res);
34 internal static object[] GetCustomAttributes (ICustomAttributeProvider obj, Type attributeType, bool inherit)
37 return (object []) Array.CreateInstance (attributeType, 0);
40 object[] res = from_cache (obj);
42 if (!inherit && res.Length == 1) {
43 if (attributeType.IsAssignableFrom (res[0].GetType ())) {
44 r = (object []) Array.CreateInstance (attributeType, 1);
47 r = (object []) Array.CreateInstance (attributeType, 0);
52 ArrayList a = new ArrayList ();
53 ICustomAttributeProvider btype = obj;
55 foreach (object attr in res)
56 if (attributeType.IsAssignableFrom (attr.GetType ()))
59 if ((btype = GetBase (btype)) != null)
60 res = from_cache (btype);
61 } while (inherit && btype != null);
63 return (object []) a.ToArray (attributeType);
66 internal static object [] GetCustomAttributes (ICustomAttributeProvider obj, bool inherit)
69 return new object [0]; //FIXME: Should i throw an exception here?
72 return (object []) from_cache (obj).Clone ();
74 ArrayList a = new ArrayList ();
75 ICustomAttributeProvider btype = obj;
76 a.AddRange (from_cache (btype));
77 while ((btype = GetBase (btype)) != null)
78 a.AddRange (from_cache (btype));
80 return (object []) a.ToArray (typeof (Attribute));
83 internal static bool IsDefined (ICustomAttributeProvider obj, Type attributeType, bool inherit)
85 object[] res = from_cache (obj);
86 foreach (object attr in res) {
87 if (attributeType.Equals (attr.GetType ()))
91 ICustomAttributeProvider btype = GetBase (obj);
92 if (inherit && (btype != null))
93 return IsDefined (btype, attributeType, inherit);
98 // Handles Type, MonoProperty and MonoMethod.
99 // The runtime has also cases for MonoEvent, MonoField, Assembly and ParameterInfo,
100 // but for those we return null here.
101 static ICustomAttributeProvider GetBase (ICustomAttributeProvider obj)
107 return ((Type) obj).BaseType;
109 MethodInfo method = null;
110 if (obj is MonoProperty) {
111 MonoProperty prop = (MonoProperty) obj;
112 method = prop.GetGetMethod ();
114 method = prop.GetSetMethod ();
115 } else if (obj is MonoMethod) {
116 method = (MethodInfo) obj;
120 * ParameterInfo -> null
125 if (method == null || !method.IsVirtual)
128 MethodInfo baseMethod = method.GetBaseDefinition ();
129 if (baseMethod == method)