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