In Test/System.ComponentModel:
[mono.git] / mcs / class / System / System.ComponentModel / TypeDescriptor.cs
index 178ac189efca8d0137b63110b737af938b859470..91b78bd8e15b8dbc5a45401309c9d184bb698552 100644 (file)
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-using System;
 using System.Collections;
 using System.Reflection;
 using System.Globalization;
 using System.ComponentModel.Design;
+using System.Security.Permissions;
 
 namespace System.ComponentModel
 {
@@ -72,6 +72,7 @@ public sealed class TypeDescriptor
                return null;
        }
 
+       [ReflectionPermission (SecurityAction.LinkDemand, TypeInformation = true, MemberAccess = true)]
        public static EventDescriptor CreateEvent (Type componentType,
                                                   string name,
                                                   Type type,
@@ -80,6 +81,7 @@ public sealed class TypeDescriptor
                return new ReflectionEventDescriptor (componentType, name, type, attributes);
        }
 
+       [ReflectionPermission (SecurityAction.LinkDemand, TypeInformation = true, MemberAccess = true)]
        public static EventDescriptor CreateEvent (Type componentType,
                                                   EventDescriptor oldEventDescriptor,
                                                   Attribute [] attributes)
@@ -87,6 +89,7 @@ public sealed class TypeDescriptor
                return new ReflectionEventDescriptor (componentType, oldEventDescriptor, attributes);
        }
 
+       [ReflectionPermission (SecurityAction.LinkDemand, TypeInformation = true, MemberAccess = true)]
        public static PropertyDescriptor CreateProperty (Type componentType,
                                                         string name,
                                                         Type type,
@@ -95,6 +98,7 @@ public sealed class TypeDescriptor
                return new ReflectionPropertyDescriptor (componentType, name, type, attributes);
        }
 
+       [ReflectionPermission (SecurityAction.LinkDemand, TypeInformation = true, MemberAccess = true)]
        public static PropertyDescriptor CreateProperty (Type componentType,
                                                         PropertyDescriptor oldPropertyDescriptor,
                                                         Attribute [] attributes)
@@ -124,7 +128,7 @@ public sealed class TypeDescriptor
                    return ((ICustomTypeDescriptor) component).GetAttributes ();
                } else {
                        IComponent com = component as IComponent;
-                       if (com != null)
+                       if (com != null && com.Site != null)
                                return GetComponentInfo (com).GetAttributes ();
                        else
                                return GetTypeInfo (component.GetType()).GetAttributes ();
@@ -142,7 +146,12 @@ public sealed class TypeDescriptor
                    throw new ArgumentNullException ("component", "component cannot be null");
 
                if (noCustomTypeDesc == false && component is ICustomTypeDescriptor) {
-                   return ((ICustomTypeDescriptor) component).GetClassName ();
+                   String res = ((ICustomTypeDescriptor) component).GetClassName ();
+                       if (res == null)
+                               res = ((ICustomTypeDescriptor) component).GetComponentName ();
+                       if (res == null)
+                               res = component.GetType ().FullName;
+                       return res;
                } else {
                    return component.GetType ().FullName;
                }
@@ -167,15 +176,14 @@ public sealed class TypeDescriptor
 #if NET_2_0
                        return null;
 #else
-
-#endif
                        return component.GetType().Name;
+#endif
                }
        }
 
        public static TypeConverter GetConverter (object component)
        {
-               return GetConverter (component.GetType ());
+               return GetConverter (component, false);
        }
 
        public static TypeConverter GetConverter (object component, bool noCustomTypeDesc)
@@ -323,7 +331,7 @@ public sealed class TypeDescriptor
                        return ((ICustomTypeDescriptor) component).GetDefaultEvent ();
                else {
                        IComponent com = component as IComponent;
-                       if (com != null)
+                       if (com != null && com.Site != null)
                                return GetComponentInfo (com).GetDefaultEvent ();
                        else
                                return GetTypeInfo (component.GetType()).GetDefaultEvent ();
@@ -346,7 +354,7 @@ public sealed class TypeDescriptor
                        return ((ICustomTypeDescriptor) component).GetDefaultProperty ();
                else {
                        IComponent com = component as IComponent;
-                       if (com != null)
+                       if (com != null && com.Site != null)
                                return GetComponentInfo (com).GetDefaultProperty ();
                        else
                                return GetTypeInfo (component.GetType()).GetDefaultProperty ();
@@ -391,10 +399,29 @@ public sealed class TypeDescriptor
                return GetEditor (component, editorBaseType, false);
        }
 
-       [MonoTODO]
        public static object GetEditor (object component, Type editorBaseType, bool noCustomTypeDesc)
        {
-               throw new NotImplementedException ();
+               if (component == null)
+                       throw new ArgumentNullException ("component");
+               if (editorBaseType == null)
+                       throw new ArgumentNullException ("editorBaseType");
+               
+               if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
+                       return ((ICustomTypeDescriptor) component).GetEditor (editorBaseType);
+
+               object [] atts = component.GetType ().GetCustomAttributes (typeof (EditorAttribute), true);
+               if (atts.Length == 0)
+                       return null;
+               string target = editorBaseType.AssemblyQualifiedName;
+               
+               foreach (EditorAttribute ea in atts){
+                       if (ea.EditorBaseTypeName == target){
+                               Type t = Type.GetType (ea.EditorTypeName, true);
+
+                               return Activator.CreateInstance (t);
+                       }
+               }
+               return null;
        }
 
        public static EventDescriptorCollection GetEvents (object component)
@@ -414,7 +441,15 @@ public sealed class TypeDescriptor
 
        public static EventDescriptorCollection GetEvents (object component, bool noCustomTypeDesc)
        {
-               return GetEvents (component, null, noCustomTypeDesc);
+               if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
+                       return ((ICustomTypeDescriptor) component).GetEvents ();
+               else {
+                       IComponent com = component as IComponent;
+                       if (com != null && com.Site != null)
+                               return GetComponentInfo (com).GetEvents ();
+                       else
+                               return GetTypeInfo (component.GetType()).GetEvents ();
+               }
        }
 
        public static EventDescriptorCollection GetEvents (Type componentType, Attribute [] attributes)
@@ -428,7 +463,7 @@ public sealed class TypeDescriptor
                        return ((ICustomTypeDescriptor) component).GetEvents (attributes);
                else {
                        IComponent com = component as IComponent;
-                       if (com != null)
+                       if (com != null && com.Site != null)
                                return GetComponentInfo (com).GetEvents (attributes);
                        else
                                return GetTypeInfo (component.GetType()).GetEvents (attributes);
@@ -453,13 +488,13 @@ public sealed class TypeDescriptor
        public static PropertyDescriptorCollection GetProperties (object component, Attribute [] attributes, bool noCustomTypeDesc)
        {
                if (component == null)
-                       throw new ArgumentNullException ("component");
+                       return PropertyDescriptorCollection.Empty;
 
                if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
                        return ((ICustomTypeDescriptor) component).GetProperties (attributes);
                else {
                        IComponent com = component as IComponent;
-                       if (com != null)
+                       if (com != null && com.Site != null)
                                return GetComponentInfo (com).GetProperties (attributes);
                        else
                                return GetTypeInfo (component.GetType()).GetProperties (attributes);
@@ -468,7 +503,18 @@ public sealed class TypeDescriptor
 
        public static PropertyDescriptorCollection GetProperties (object component, bool noCustomTypeDesc)
        {
-               return GetProperties (component, null, noCustomTypeDesc);
+               if (component == null)
+                       return PropertyDescriptorCollection.Empty;
+
+               if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
+                       return ((ICustomTypeDescriptor) component).GetProperties ();
+               else {
+                       IComponent com = component as IComponent;
+                       if (com != null && com.Site != null)
+                               return GetComponentInfo (com).GetProperties ();
+                       else
+                               return GetTypeInfo (component.GetType()).GetProperties ();
+               }
        }
 
        public static PropertyDescriptorCollection GetProperties (Type componentType, Attribute [] attributes)
@@ -491,7 +537,9 @@ public sealed class TypeDescriptor
        }
 
        public static IComNativeDescriptorHandler ComNativeDescriptorHandler {
+               [PermissionSet (SecurityAction.LinkDemand, Unrestricted = true)]
                get { return descriptorHandler; }
+               [PermissionSet (SecurityAction.LinkDemand, Unrestricted = true)]
                set { descriptorHandler = value; }
        }
 
@@ -570,7 +618,8 @@ public sealed class TypeDescriptor
        {
                if (component != null && component.Site != null) {
                        ITypeResolutionService resver = (ITypeResolutionService) component.Site.GetService (typeof(ITypeResolutionService));
-                       if (resver != null) return resver.GetType (typeName, true, false);
+                       if (resver != null)
+                               return resver.GetType (typeName, true, false);
                }
                
                Type t = Type.GetType (typeName);
@@ -605,20 +654,25 @@ public sealed class TypeDescriptor
                public EventDescriptorCollection GetEvents (Attribute[] attributes)
                {
                        EventDescriptorCollection evs = GetEvents ();
-                       if (attributes == null) return evs;
-                       else return evs.Filter (attributes);
+                       if (attributes == null)
+                               return evs;
+                       else
+                               return evs.Filter (attributes);
                }
                
                public PropertyDescriptorCollection GetProperties (Attribute[] attributes)
                {
                        PropertyDescriptorCollection props = GetProperties ();
-                       if (attributes == null) return props;
-                       else return props.Filter (attributes);
+                       if (attributes == null)
+                               return props;
+                       else
+                               return props.Filter (attributes);
                }
                
                public EventDescriptor GetDefaultEvent ()
                {
-                       if (_gotDefaultEvent) return _defaultEvent;
+                       if (_gotDefaultEvent)
+                               return _defaultEvent;
                        
                        DefaultEventAttribute attr = (DefaultEventAttribute) GetAttributes()[typeof(DefaultEventAttribute)];
                        if (attr == null || attr.Name == null) 
@@ -646,7 +700,8 @@ public sealed class TypeDescriptor
                
                public PropertyDescriptor GetDefaultProperty ()
                {
-                       if (_gotDefaultProperty) return _defaultProperty;
+                       if (_gotDefaultProperty)
+                               return _defaultProperty;
                        
                        DefaultPropertyAttribute attr = (DefaultPropertyAttribute) GetAttributes()[typeof(DefaultPropertyAttribute)];
                        if (attr == null || attr.Name == null) 
@@ -661,13 +716,19 @@ public sealed class TypeDescriptor
                
                protected AttributeCollection GetAttributes (IComponent comp)
                {
-                       if (_attributes != null) return _attributes;
+                       if (_attributes != null)
+                               return _attributes;
                        
                        bool cache = true;
                        object[] ats = _infoType.GetCustomAttributes (true);
                        Hashtable t = new Hashtable ();
-                       foreach (Attribute at in ats)
-                               t [at.TypeId] = at;
+
+                       // Filter the custom attributes, so that only the top
+                       // level of the same type are left.
+                       //
+                       for (int i = ats.Length -1; i >= 0; i--) {
+                               t [((Attribute) ats[i]).TypeId] = ats[i];
+                       }
                                        
                        if (comp != null && comp.Site != null) 
                        {
@@ -678,7 +739,8 @@ public sealed class TypeDescriptor
                        ArrayList atts = new ArrayList ();
                        atts.AddRange (t.Values);
                        AttributeCollection attCol = new AttributeCollection (atts);
-                       if (cache) _attributes = attCol;
+                       if (cache)
+                               _attributes = attCol;
                        return attCol;
                }
        }
@@ -701,7 +763,8 @@ public sealed class TypeDescriptor
                
                public override EventDescriptorCollection GetEvents ()
                {
-                       if (_events != null) return _events;
+                       if (_events != null)
+                               return _events;
                        
                        bool cache = true;
                        EventInfo[] events = _component.GetType().GetEvents ();
@@ -724,10 +787,11 @@ public sealed class TypeDescriptor
                
                public override PropertyDescriptorCollection GetProperties ()
                {
-                       if (_properties != null) return _properties;
+                       if (_properties != null)
+                               return _properties;
                        
                        bool cache = true;
-                       PropertyInfo[] props = _component.GetType().GetProperties ();
+                       PropertyInfo[] props = _component.GetType().GetProperties (BindingFlags.Instance | BindingFlags.Public);
                        Hashtable t = new Hashtable ();
                        foreach (PropertyInfo pr in props)
                                t [pr.Name] = new ReflectionPropertyDescriptor (pr);
@@ -741,7 +805,8 @@ public sealed class TypeDescriptor
                        PropertyDescriptor[] descriptors = new PropertyDescriptor[t.Values.Count];
                        t.Values.CopyTo (descriptors, 0);
                        PropertyDescriptorCollection attCol = new PropertyDescriptorCollection (descriptors, true);
-                       if (cache) _properties = attCol;
+                       if (cache)
+                               _properties = attCol;
                        return attCol;
                }
        }
@@ -762,7 +827,8 @@ public sealed class TypeDescriptor
                
                public override EventDescriptorCollection GetEvents ()
                {
-                       if (_events != null) return _events;
+                       if (_events != null)
+                               return _events;
                        
                        EventInfo[] events = InfoType.GetEvents ();
                        EventDescriptor[] descs = new EventDescriptor [events.Length];
@@ -775,14 +841,16 @@ public sealed class TypeDescriptor
                
                public override PropertyDescriptorCollection GetProperties ()
                {
-                       if (_properties != null) return _properties;
+                       if (_properties != null)
+                               return _properties;
                        
-                       PropertyInfo[] props = InfoType.GetProperties ();
-                       PropertyDescriptor[] descs = new PropertyDescriptor [props.Length];
+                       PropertyInfo[] props = InfoType.GetProperties (BindingFlags.Instance | BindingFlags.Public);
+                       ArrayList descs = new ArrayList (props.Length);
                        for (int n=0; n<props.Length; n++)
-                               descs [n] = new ReflectionPropertyDescriptor (props[n]);
+                               if (props [n].GetIndexParameters ().Length == 0)
+                                       descs.Add (new ReflectionPropertyDescriptor (props[n]));
 
-                       _properties = new PropertyDescriptorCollection (descs, true);
+                       _properties = new PropertyDescriptorCollection ((PropertyDescriptor[]) descs.ToArray (typeof (PropertyDescriptor)), true);
                        return _properties;
                }
        }