2005-04-12 Dick Porter <dick@ximian.com>
[mono.git] / mcs / class / corlib / System / Attribute.cs
1 //
2 // System.Attribute.cs
3 //
4 // Authors:
5 //   Miguel de Icaza (miguel@ximian.com) - Original
6 //   Nick D. Drochak II (ndrochak@gol.com) - Implemented most of the guts
7 //   Gonzalo Paniagua Javier (gonzalo@ximian.com)
8 //
9 // (C) 2002, 2003 Ximian, Inc.  http://www.ximian.com
10 //
11
12 //
13 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
22 // 
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 // 
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 //
34
35 using System.Reflection;
36
37 namespace System
38 {
39         [AttributeUsage (AttributeTargets.All)]
40         [Serializable]
41         public abstract class Attribute
42         {
43                 protected Attribute ()
44                 {
45                 }
46
47                 public virtual object TypeId {
48                         get {
49                                 // Derived classes should override this default behaviour as appropriate
50                                 return this.GetType ();
51                         }
52                 }
53
54                 private static void CheckParameters (object element, Type attributeType)
55                 {
56                         // neither parameter is allowed to be null
57                         if (element == null)
58                                 throw new ArgumentNullException ("element");
59
60                         if (attributeType == null)
61                                 throw new ArgumentNullException ("attributeType");
62
63                         if (!typeof (Attribute).IsAssignableFrom (attributeType))
64                                 throw new ArgumentException (Locale.GetText (
65                                         "Type is not derived from System.Attribute."), "attributeType");
66                 }
67
68                 private static Attribute FindAttribute (object[] attributes)
69                 {
70                         // if there exists more than one attribute of the given type, throw an exception
71                         if (attributes.Length > 1) {
72                                 throw new AmbiguousMatchException (Locale.GetText (
73                                         "<element> has more than one attribute of type <attribute_type>"));
74                         }
75
76                         if (attributes.Length < 1)
77                                 return null;
78
79                         // tested above for '> 1' and and '< 1', so only '== 1' is left,
80                         // i.e. we found the attribute
81                         return (Attribute) attributes[0];
82                 }
83
84                 public static Attribute GetCustomAttribute (ParameterInfo element, Type attributeType)
85                 {
86                         return GetCustomAttribute (element, attributeType, true);
87                 }
88
89                 public static Attribute GetCustomAttribute (MemberInfo element, Type attributeType)
90                 {
91                         return GetCustomAttribute (element, attributeType, true);
92                 }
93
94                 public static Attribute GetCustomAttribute (Assembly element, Type attributeType)
95                 {
96                         return GetCustomAttribute (element, attributeType, true);
97                 }
98
99                 public static Attribute GetCustomAttribute (Module element, Type attributeType)
100                 {
101                         return GetCustomAttribute (element, attributeType, true);
102                 }
103
104                 public static Attribute GetCustomAttribute (Module element, Type attributeType, bool inherit)
105                 {
106                         // neither parameter is allowed to be null
107                         CheckParameters (element, attributeType);
108
109                         // Module inheritance hierarchies CAN NOT be searched for attributes, so the second
110                         // parameter of GetCustomAttributes () is IGNORED.
111                         object[] attributes = element.GetCustomAttributes (attributeType, inherit);
112
113                         return FindAttribute (attributes);
114                 }
115
116                 public static Attribute GetCustomAttribute (Assembly element, Type attributeType, bool inherit)
117                 {
118                         // neither parameter is allowed to be null
119                         CheckParameters (element, attributeType);
120
121                         // Assembly inheritance hierarchies CAN NOT be searched for attributes, so the second
122                         // parameter of GetCustomAttributes () is IGNORED.
123                         object[] attributes = element.GetCustomAttributes (attributeType, inherit);
124
125                         return FindAttribute (attributes);
126                 }
127
128                 public static Attribute GetCustomAttribute (ParameterInfo element, Type attributeType, bool inherit)
129                 {
130                         // neither parameter is allowed to be null
131                         CheckParameters (element, attributeType);
132
133                         // ParameterInfo inheritance hierarchies CAN NOT be searched for attributes, so the second
134                         // parameter of GetCustomAttributes () is IGNORED.
135                         object[] attributes = element.GetCustomAttributes (attributeType, inherit);
136
137                         return FindAttribute (attributes);
138                 }
139
140                 public static Attribute GetCustomAttribute (MemberInfo element, Type attributeType, bool inherit)
141                 {
142                         // neither parameter is allowed to be null
143                         CheckParameters (element, attributeType);
144
145                         // MemberInfo inheritance hierarchies can be searched for attributes, so the second
146                         // parameter of GetCustomAttribute () is respected.
147                         return MonoCustomAttrs.GetCustomAttribute (element, attributeType, inherit);
148                 }
149
150                 public static Attribute[] GetCustomAttributes (Assembly element)
151                 {
152                         return GetCustomAttributes (element, true);
153                 }
154
155                 public static Attribute[] GetCustomAttributes (ParameterInfo element)
156                 {
157                         return GetCustomAttributes (element, true);
158                 }
159
160                 public static Attribute[] GetCustomAttributes (MemberInfo element)
161                 {
162                         return GetCustomAttributes (element, true);
163                 }
164
165                 public static Attribute[] GetCustomAttributes (Module element)
166                 {
167                         return GetCustomAttributes (element, true);
168                 }
169
170                 public static Attribute[] GetCustomAttributes (Assembly element, Type attributeType)
171                 {
172                         return GetCustomAttributes (element, attributeType, true);
173                 }
174
175                 public static Attribute[] GetCustomAttributes (Module element, Type attributeType)
176                 {
177                         return GetCustomAttributes (element, attributeType, true);
178                 }
179
180                 public static Attribute[] GetCustomAttributes (ParameterInfo element, Type attributeType)
181                 {
182                         return GetCustomAttributes (element, attributeType, true);
183                 }
184
185                 public static Attribute[] GetCustomAttributes (MemberInfo element, Type attributeType)
186                 {
187                         return GetCustomAttributes (element, attributeType, true);
188                 }
189
190                 public static Attribute[] GetCustomAttributes (Assembly element, Type attributeType, bool inherit)
191                 {
192                         // element parameter is not allowed to be null
193                         CheckParameters (element, attributeType);
194
195                         return (Attribute []) element.GetCustomAttributes (attributeType, inherit);
196                 }
197
198                 public static Attribute[] GetCustomAttributes (ParameterInfo element, Type attributeType, bool inherit)
199                 {
200                         // element parameter is not allowed to be null
201                         CheckParameters (element, attributeType);
202
203                         return (Attribute []) element.GetCustomAttributes (attributeType, inherit);
204                 }
205
206                 public static Attribute[] GetCustomAttributes (Module element, Type attributeType, bool inherit)
207                 {
208                         // element parameter is not allowed to be null
209                         CheckParameters (element, attributeType);
210
211                         return (Attribute []) element.GetCustomAttributes (attributeType, inherit);
212                 }
213
214                 public static Attribute[] GetCustomAttributes (MemberInfo element, Type attributeType, bool inherit)
215                 {
216                         // element parameter is not allowed to be null
217                         CheckParameters (element, attributeType);
218
219                         return (Attribute []) element.GetCustomAttributes (attributeType, inherit);
220                 }
221
222                 public static Attribute[] GetCustomAttributes (Module element, bool inherit)
223                 {
224                         // element parameter is not allowed to be null
225                         CheckParameters (element, typeof (Attribute));
226
227                         return (Attribute []) element.GetCustomAttributes (inherit);
228                 }
229
230                 public static Attribute[] GetCustomAttributes (Assembly element, bool inherit)
231                 {
232                         // element parameter is not allowed to be null
233                         CheckParameters (element, typeof (Attribute));
234
235                         return (Attribute []) element.GetCustomAttributes (inherit);
236                 }
237
238                 public static Attribute[] GetCustomAttributes (MemberInfo element, bool inherit)
239                 {
240                         // element parameter is not allowed to be null
241                         CheckParameters (element, typeof (Attribute));
242
243                         return (Attribute []) element.GetCustomAttributes (inherit);
244                 }
245
246                 public static Attribute[] GetCustomAttributes (ParameterInfo element, bool inherit)
247                 {
248                         // element parameter is not allowed to be null
249                         CheckParameters (element, typeof (Attribute));
250
251                         return (Attribute []) element.GetCustomAttributes (inherit);
252                 }
253
254                 public override int GetHashCode ()
255                 {
256                         return base.GetHashCode ();
257                 }
258
259                 public virtual bool IsDefaultAttribute ()
260                 {
261                         // Derived classes should override this default behaviour as appropriate
262                         return false;
263                 }
264
265                 public static bool IsDefined (Module element, Type attributeType)
266                 {
267                         return IsDefined (element, attributeType, false);
268                 }
269
270                 public static bool IsDefined (ParameterInfo element, Type attributeType)
271                 {
272                         return IsDefined (element, attributeType, true);
273                 }
274
275                 public static bool IsDefined (MemberInfo element, Type attributeType)
276                 {
277                         return IsDefined (element, attributeType, true);
278                 }
279
280                 public static bool IsDefined (Assembly element, Type attributeType)
281                 {
282                         return IsDefined (element, attributeType, true);
283                 }
284
285                 public static bool IsDefined (MemberInfo element, Type attributeType, bool inherit)
286                 {
287                         CheckParameters (element, attributeType);
288
289                         MemberTypes mtype = element.MemberType;
290                         if (mtype != MemberTypes.Constructor && mtype != MemberTypes.Event &&
291                                 mtype != MemberTypes.Field       && mtype != MemberTypes.Method &&
292                                 mtype != MemberTypes.Property    && mtype != MemberTypes.TypeInfo &&
293                                 mtype != MemberTypes.NestedType)
294                                 throw new NotSupportedException (Locale.GetText (
295                                         "Element is not a constructor, method, property, event, type or field."));
296
297                         return ((MemberInfo) element).IsDefined (attributeType, inherit);
298                 }
299
300                 public static bool IsDefined (Assembly element, Type attributeType, bool inherit)
301                 {
302                         CheckParameters (element, attributeType);
303
304                         return element.IsDefined (attributeType, inherit);
305                 }
306
307                 public static bool IsDefined (Module element, Type attributeType, bool inherit)
308                 {
309                         CheckParameters (element, attributeType);
310
311                         return element.IsDefined (attributeType, inherit);
312                 }
313
314                 public static bool IsDefined (ParameterInfo element, Type attributeType, bool inherit)
315                 {
316                         CheckParameters (element, attributeType);
317
318                         return IsDefined (element.Member, attributeType, inherit);
319                 }
320
321                 public virtual bool Match (object obj)
322                 {
323                         // default action is the same as Equals.
324                         // Derived classes should override as appropriate
325                         return this.Equals (obj);
326                 }
327
328                 public override bool Equals (object obj)
329                 {
330                         if (obj == null || !(obj is Attribute))
331                                 return false;
332
333                         return ((Attribute) obj) == this;
334                 }
335         }
336 }