2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / corlib / System / MonoCustomAttrs.cs
index 096e7178f48f17350b5a6ac9e60c54631f6cd701..4a00d26446edf57982764e80cbab879c37522208 100755 (executable)
@@ -8,6 +8,29 @@
 // (c) 2002,2003 Ximian, Inc. (http://www.ximian.com)
 //
 
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
 using System;
 using System.Reflection;
 using System.Collections;
@@ -18,7 +41,37 @@ namespace System
        internal class MonoCustomAttrs
        {
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               internal static extern object[] GetCustomAttributes (ICustomAttributeProvider obj);
+               internal static extern object[] GetCustomAttributesInternal (ICustomAttributeProvider obj, bool pseudoAttrs);
+
+               internal static object[] GetCustomAttributesBase (ICustomAttributeProvider obj)
+               {
+                       object[] attrs = GetCustomAttributesInternal (obj, false);
+
+#if NET_2_0 || BOOTSTRAP_NET_2_0
+                       object[] pseudoAttrs = null;
+
+                       /* FIXME: Add other types */
+                       if (obj is Type)
+                               pseudoAttrs = ((Type)obj).GetPseudoCustomAttributes ();
+                       else if (obj is MonoMethod)
+                               pseudoAttrs = ((MonoMethod)obj).GetPseudoCustomAttributes ();
+                       else if (obj is FieldInfo)
+                               pseudoAttrs = ((FieldInfo)obj).GetPseudoCustomAttributes ();
+                       else if (obj is ParameterInfo)
+                               pseudoAttrs = ((ParameterInfo)obj).GetPseudoCustomAttributes ();
+
+                       if (pseudoAttrs != null) {
+                               object[] res = new object [attrs.Length + pseudoAttrs.Length];
+                               System.Array.Copy (attrs, res, attrs.Length);
+                               System.Array.Copy (pseudoAttrs, 0, res, attrs.Length, pseudoAttrs.Length);
+                               return res;
+                       }
+                       else
+                               return attrs;
+#else
+                       return attrs;
+#endif
+               }
 
                internal static Attribute GetCustomAttribute (ICustomAttributeProvider obj,
                                                                Type attributeType,
@@ -45,7 +98,7 @@ namespace System
                                throw new ArgumentNullException ("obj");
 
                        object[] r;
-                       object[] res = GetCustomAttributes (obj);
+                       object[] res = GetCustomAttributesBase (obj);
                        // shortcut
                        if (!inherit && res.Length == 1)
                        {
@@ -63,15 +116,15 @@ namespace System
                                }
                                else
                                {
-                                       r = (object[]) Array.CreateInstance (res[0].GetType (), 1);\r
-                                       r[0] = res[0];\r
+                                       r = (object[]) Array.CreateInstance (res[0].GetType (), 1);
+                                       r[0] = res[0];
                                }
                                return r;
                        }
 
                        // if AttributeType is sealed, and Inherited is set to false, then 
                        // there's no use in scanning base types 
-                       if ((attributeType != null && attributeType.IsSealed) && !inherit)
+                       if ((attributeType != null && attributeType.IsSealed) && inherit)
                        {
                                AttributeUsageAttribute usageAttribute = RetrieveAttributeUsage (
                                        attributeType);
@@ -139,7 +192,7 @@ namespace System
                                if ((btype = GetBase (btype)) != null)
                                {
                                        inheritanceLevel++;
-                                       res = GetCustomAttributes (btype);
+                                       res = GetCustomAttributesBase (btype);
                                }
                        } while (inherit && btype != null);
 
@@ -165,22 +218,20 @@ namespace System
                                throw new ArgumentNullException ("obj");
 
                        if (!inherit)
-                               return (object[]) GetCustomAttributes (obj).Clone ();
+                               return (object[]) GetCustomAttributesBase (obj).Clone ();
 
                        return GetCustomAttributes (obj, null, inherit);
                }
 
                internal static bool IsDefined (ICustomAttributeProvider obj, Type attributeType, bool inherit)
                {
-                       object[] res = GetCustomAttributes (obj);
+                       object [] res = GetCustomAttributesBase (obj);
                        foreach (object attr in res)
-                       {
                                if (attributeType.Equals (attr.GetType ()))
                                        return true;
-                       }
 
-                       ICustomAttributeProvider btype = GetBase (obj);
-                       if (inherit && (btype != null))
+                       ICustomAttributeProvider btype;
+                       if (inherit && ((btype = GetBase (obj)) != null))
                                return IsDefined (btype, attributeType, inherit);
 
                        return false;
@@ -228,6 +279,10 @@ namespace System
 
                private static AttributeUsageAttribute RetrieveAttributeUsage (Type attributeType)
                {
+                       if (attributeType == typeof (AttributeUsageAttribute))
+                               /* Avoid endless recursion */
+                               return new AttributeUsageAttribute (AttributeTargets.Class);
+
                        AttributeUsageAttribute usageAttribute = null;
                        object[] attribs = GetCustomAttributes (attributeType,
                                MonoCustomAttrs.AttributeUsageType, false);