Welcome to mirror list, hosted at ThFree Co, Russian Federation.

MonoCustomAttrs.cs « System « corlib « class « mcs - github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 1954e2a293d1a8183b1e1436f8242d90ad92aa60 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// System.MonoCustomAttrs.cs
// Hooks into the runtime to get custom attributes for reflection handles
//
// Paolo Molaro (lupus@ximian.com)
//
// (c) 2002 Ximian, Inc.

using System;
using System.Reflection;
using System.Collections;
using System.Runtime.CompilerServices;

namespace System {
	internal class MonoCustomAttrs {

		static Hashtable handle_to_attrs = new Hashtable ();

		[MethodImplAttribute(MethodImplOptions.InternalCall)]
		internal static extern object[] GetCustomAttributes (ICustomAttributeProvider obj);

		private static object[] from_cache (ICustomAttributeProvider obj) {
			object[] res = (object[])handle_to_attrs [obj];
			if (res != null)
				return res;
			res = GetCustomAttributes (obj);
			handle_to_attrs.Add (obj, res);
			return res;
		}

		internal static object[] GetCustomAttributes (ICustomAttributeProvider obj, Type attributeType, bool inherit) {
			object[] res = from_cache (obj);
			// shortcut
			if (res.Length == 1 && res[0].GetType () == attributeType)
				return (object[])res.Clone ();
			ArrayList a = new ArrayList ();
			Type btype = obj as Type;
			do {
				foreach (object attr in res) {
					if (attributeType.Equals (attr.GetType ()))
						a.Add (attr);
				}
				if (btype != null && ((btype = btype.BaseType) != null)) {
					res = from_cache (btype);
				} else {
					break;
				}
			} while (inherit && btype != null && ((btype = btype.BaseType) != null));
			Attribute[] r = new Attribute [a.Count];
			a.CopyTo (r);
			return r;
		}

		internal static object[] GetCustomAttributes (ICustomAttributeProvider obj, bool inherit) {
			Type btype = obj as Type;
			if (!inherit || btype == null) {
				return (Object[])from_cache (obj).Clone ();
			} else {
				ArrayList a = new ArrayList ();
				a.AddRange (from_cache (obj));
				while ((btype = btype.BaseType) != null) {
					a.AddRange (from_cache (btype));
				}
				Attribute[] r = new Attribute [a.Count];
				a.CopyTo (r);
				return (object[])r;
			}
		}
		internal static bool IsDefined (ICustomAttributeProvider obj, Type attributeType, bool inherit) {
			object[] res = from_cache (obj);
			foreach (object attr in res) {
				if (attributeType.Equals (attr.GetType ()))
					return true;
			}
			Type btype = obj as Type;
			if (inherit && (btype != null) && ((btype = btype.BaseType) != null))
				return IsDefined (btype, attributeType, inherit);
			return false;
		}
	}
}