diff options
author | Marek Habersack <grendel@twistedcode.net> | 2009-06-22 22:24:19 +0400 |
---|---|---|
committer | Marek Habersack <grendel@twistedcode.net> | 2009-06-22 22:24:19 +0400 |
commit | 1821e106c70e691e2c4b703575f0d4b28f1d8838 (patch) | |
tree | 6c219097a51108c712e57c38f4125582708c3dc4 | |
parent | 62732ea52e8dedd7dbb533482e6a0931ec101572 (diff) |
2009-06-22 Marek Habersack <mhabersack@novell.com>
* WeakObjectWrapper.cs, WeakObjectWrapperComparer.cs: added - used
by TypeDescriptor for storage of type description providers.
* TypeDescriptor.cs: implemented part of the 2.0+ API which deals
with adding/removing/getting type description providers.
* AttributeCollection.cs: do not throw NREX when attrList is
null in Count.
2009-06-22 Marek Habersack <mhabersack@novell.com>
* TypeDescriptorTests.cs: added tests for 2.0+ APIs which deal
with adding/removing/getting type description providers.
svn path=/trunk/mcs/; revision=136634
8 files changed, 1060 insertions, 26 deletions
diff --git a/mcs/class/System/System.ComponentModel/AttributeCollection.cs b/mcs/class/System/System.ComponentModel/AttributeCollection.cs index 56f3464fffe..c60ddc8ea0c 100644 --- a/mcs/class/System/System.ComponentModel/AttributeCollection.cs +++ b/mcs/class/System/System.ComponentModel/AttributeCollection.cs @@ -161,7 +161,7 @@ namespace System.ComponentModel public int Count { get { - return attrList.Count; + return attrList != null ? attrList.Count : 0; } } diff --git a/mcs/class/System/System.ComponentModel/ChangeLog b/mcs/class/System/System.ComponentModel/ChangeLog index 8561892c47e..04afad39214 100644 --- a/mcs/class/System/System.ComponentModel/ChangeLog +++ b/mcs/class/System/System.ComponentModel/ChangeLog @@ -1,3 +1,14 @@ +2009-06-22 Marek Habersack <mhabersack@novell.com> + + * WeakObjectWrapper.cs, WeakObjectWrapperComparer.cs: added - used + by TypeDescriptor for storage of type description providers. + + * TypeDescriptor.cs: implemented part of the 2.0+ API which deals + with adding/removing/getting type description providers. + + * AttributeCollection.cs: do not throw NREX when attrList is + null in Count. + 2009-05-14 Jonathan Pryor <jpryor@novell.com> * ListChangedEventArgs.cs: Fix .NET compatibility problems (discovered diff --git a/mcs/class/System/System.ComponentModel/TypeDescriptor.cs b/mcs/class/System/System.ComponentModel/TypeDescriptor.cs index 2a9f4b29a24..6642c2c1f2b 100644 --- a/mcs/class/System/System.ComponentModel/TypeDescriptor.cs +++ b/mcs/class/System/System.ComponentModel/TypeDescriptor.cs @@ -39,6 +39,10 @@ using System.Globalization; using System.ComponentModel.Design; using System.Security.Permissions; +#if NET_2_0 +using System.Collections.Generic; +#endif + namespace System.ComponentModel { @@ -51,43 +55,98 @@ public sealed class TypeDescriptor private static Hashtable typeTable = new Hashtable (); private static Hashtable editors; +#if NET_2_0 + static object typeDescriptionProvidersLock = new object (); + static Dictionary <Type, LinkedList <TypeDescriptionProvider>> typeDescriptionProviders; + + static object componentDescriptionProvidersLock = new object (); + static Dictionary <WeakObjectWrapper, LinkedList <TypeDescriptionProvider>> componentDescriptionProviders; + + static TypeDescriptor () + { + typeDescriptionProviders = new Dictionary <Type, LinkedList <TypeDescriptionProvider>> (); + componentDescriptionProviders = new Dictionary <WeakObjectWrapper, LinkedList <TypeDescriptionProvider>> (new WeakObjectWrapperComparer ()); + } +#endif private TypeDescriptor () { } #if NET_2_0 - [MonoNotSupported ("")] + [MonoNotSupported ("Mono does not support COM")] [EditorBrowsable (EditorBrowsableState.Advanced)] public static Type ComObjectType { get { throw new NotImplementedException (); } } - [MonoNotSupported("")] [EditorBrowsable (EditorBrowsableState.Advanced)] public static TypeDescriptionProvider AddAttributes (object instance, params Attribute [] attributes) { - throw new NotImplementedException (); + if (instance == null) + throw new ArgumentNullException ("instance"); + if (attributes == null) + throw new ArgumentNullException ("attributes"); + + var ret = new AttributeProvider (attributes, GetProvider (instance)); + AddProvider (ret, instance); + + return ret; } - [MonoNotSupported("")] [EditorBrowsable (EditorBrowsableState.Advanced)] public static TypeDescriptionProvider AddAttributes (Type type, params Attribute [] attributes) { - throw new NotImplementedException (); - } + if (type == null) + throw new ArgumentNullException ("type"); + if (attributes == null) + throw new ArgumentNullException ("attributes"); - [MonoNotSupported("")] + var ret = new AttributeProvider (attributes, GetProvider (type)); + AddProvider (ret, type); + + return ret; + } + [EditorBrowsable (EditorBrowsableState.Advanced)] public static void AddProvider (TypeDescriptionProvider provider, object instance) { - throw new NotImplementedException (); + if (provider == null) + throw new ArgumentNullException ("provider"); + if (instance == null) + throw new ArgumentNullException ("instance"); + + lock (componentDescriptionProvidersLock) { + LinkedList <TypeDescriptionProvider> plist; + WeakObjectWrapper instanceWrapper = new WeakObjectWrapper (instance); + + if (!componentDescriptionProviders.TryGetValue (instanceWrapper, out plist)) { + plist = new LinkedList <TypeDescriptionProvider> (); + componentDescriptionProviders.Add (new WeakObjectWrapper (instance), plist); + } + + plist.AddLast (provider); + instanceWrapper = null; + } } - [MonoNotSupported("")] [EditorBrowsable (EditorBrowsableState.Advanced)] public static void AddProvider (TypeDescriptionProvider provider, Type type) { - throw new NotImplementedException (); + if (provider == null) + throw new ArgumentNullException ("provider"); + if (type == null) + throw new ArgumentNullException ("type"); + + lock (typeDescriptionProvidersLock) { + LinkedList <TypeDescriptionProvider> plist; + + if (!typeDescriptionProviders.TryGetValue (type, out plist)) { + plist = new LinkedList <TypeDescriptionProvider> (); + typeDescriptionProviders.Add (type, plist); + } + + plist.AddLast (provider); + } } [MonoTODO] @@ -695,32 +754,65 @@ public sealed class TypeDescriptor } #if NET_2_0 - [MonoNotSupported ("")] [EditorBrowsable (EditorBrowsableState.Advanced)] public static TypeDescriptionProvider GetProvider (object instance) { - throw new NotImplementedException (); + if (instance == null) + throw new ArgumentNullException ("instance"); + + TypeDescriptionProvider ret = null; + lock (componentDescriptionProvidersLock) { + LinkedList <TypeDescriptionProvider> plist; + WeakObjectWrapper instanceWrapper = new WeakObjectWrapper (instance); + + if (componentDescriptionProviders.TryGetValue (instanceWrapper, out plist) && plist.Count > 0) + ret = plist.Last.Value; + + instanceWrapper = null; + } + + if (ret == null) + ret = new DefaultTypeDescriptionProvider (); + + return new WrappedTypeDescriptionProvider (ret); } - [MonoNotSupported ("")] [EditorBrowsable (EditorBrowsableState.Advanced)] public static TypeDescriptionProvider GetProvider (Type type) { - throw new NotImplementedException (); + if (type == null) + throw new ArgumentNullException ("type"); + + TypeDescriptionProvider ret = null; + lock (typeDescriptionProvidersLock) { + LinkedList <TypeDescriptionProvider> plist; + + if (typeDescriptionProviders.TryGetValue (type, out plist) && plist.Count > 0) + ret = plist.Last.Value; + } + + if (ret == null) + ret = new DefaultTypeDescriptionProvider (); + + return new WrappedTypeDescriptionProvider (ret); } - [MonoNotSupported ("")] [EditorBrowsable (EditorBrowsableState.Advanced)] public static Type GetReflectionType (object instance) { - throw new NotImplementedException (); + if (instance == null) + throw new ArgumentNullException ("instance"); + + return instance.GetType (); } - [MonoNotSupported ("")] [EditorBrowsable (EditorBrowsableState.Advanced)] public static Type GetReflectionType (Type type) { - throw new NotImplementedException (); + if (type == null) + throw new ArgumentNullException ("type"); + + return type; } [MonoNotSupported("Associations not supported")] @@ -751,18 +843,73 @@ public sealed class TypeDescriptor throw new NotImplementedException (); } - [MonoNotSupported ("")] [EditorBrowsable (EditorBrowsableState.Advanced)] public static void RemoveProvider (TypeDescriptionProvider provider, object instance) { - throw new NotImplementedException (); + if (provider == null) + throw new ArgumentNullException ("provider"); + if (instance == null) + throw new ArgumentNullException ("instance"); + + bool removed = false; + lock (componentDescriptionProvidersLock) { + LinkedList <TypeDescriptionProvider> plist; + WeakObjectWrapper instanceWrapper = new WeakObjectWrapper (instance); + + if (componentDescriptionProviders.TryGetValue (instanceWrapper, out plist) && plist.Count > 0) { + RemoveProvider (provider, plist); + removed = true; + } + + instanceWrapper = null; + } + + var refreshed = Refreshed; + if (refreshed != null) + refreshed (new RefreshEventArgs (instance)); } - [MonoNotSupported ("")] [EditorBrowsable (EditorBrowsableState.Advanced)] public static void RemoveProvider (TypeDescriptionProvider provider, Type type) { - throw new NotImplementedException (); + if (provider == null) + throw new ArgumentNullException ("provider"); + if (type == null) + throw new ArgumentNullException ("type"); + + bool removed = false; + lock (typeDescriptionProvidersLock) { + LinkedList <TypeDescriptionProvider> plist; + + if (typeDescriptionProviders.TryGetValue (type, out plist) && plist.Count > 0) { + RemoveProvider (provider, plist); + removed = true; + } + } + + var refreshed = Refreshed; + if (refreshed != null) + refreshed (new RefreshEventArgs (type)); + } + + static void RemoveProvider (TypeDescriptionProvider provider, LinkedList <TypeDescriptionProvider> plist) + { + LinkedListNode <TypeDescriptionProvider> node = plist.Last; + LinkedListNode <TypeDescriptionProvider> first = plist.First; + TypeDescriptionProvider p; + + do { + p = node.Value; + if (p == provider) { + plist.Remove (node); + break; + } + if (node == first) + break; + + node = node.Previous; + + } while (true); } #endif @@ -874,6 +1021,165 @@ public sealed class TypeDescriptor type = Type.GetType (typeName); return type; } + +#if NET_2_0 + sealed class AttributeProvider : TypeDescriptionProvider + { + Attribute[] attributes; + + public AttributeProvider (Attribute[] attributes, TypeDescriptionProvider parent) + : base (parent) + { + this.attributes = attributes; + } + + public override ICustomTypeDescriptor GetTypeDescriptor (Type type, object instance) + { + return new AttributeTypeDescriptor (base.GetTypeDescriptor (type, instance), attributes); + } + + sealed class AttributeTypeDescriptor : CustomTypeDescriptor + { + Attribute[] attributes; + + public AttributeTypeDescriptor (ICustomTypeDescriptor parent, Attribute[] attributes) + : base (parent) + { + this.attributes = attributes; + } + + public override AttributeCollection GetAttributes () + { + AttributeCollection attrs = base.GetAttributes (); + + if (attrs != null && attrs.Count > 0) + return AttributeCollection.FromExisting (attrs, attributes); + else + return new AttributeCollection (attributes); + } + } + } + + sealed class WrappedTypeDescriptionProvider : TypeDescriptionProvider + { + public TypeDescriptionProvider Wrapped { get; private set; } + + public WrappedTypeDescriptionProvider (TypeDescriptionProvider wrapped) + { + Wrapped = wrapped; + } + + public override object CreateInstance (IServiceProvider provider, Type objectType, Type[] argTypes, object[] args) + { + TypeDescriptionProvider wrapped = Wrapped; + + if (wrapped == null) + return base.CreateInstance (provider, objectType, argTypes, args); + + return wrapped.CreateInstance (provider, objectType, argTypes, args); + } + + public override IDictionary GetCache (object instance) + { + TypeDescriptionProvider wrapped = Wrapped; + + if (wrapped == null) + return base.GetCache (instance); + + return wrapped.GetCache (instance); + } + + public override ICustomTypeDescriptor GetExtendedTypeDescriptor (object instance) + { + return new DefaultTypeDescriptor (this, null, instance); + } + + public override string GetFullComponentName (object component) + { + TypeDescriptionProvider wrapped = Wrapped; + + if (wrapped == null) + return base.GetFullComponentName (component); + + return wrapped.GetFullComponentName (component); + } + + public override Type GetReflectionType (Type type, object instance) + { + TypeDescriptionProvider wrapped = Wrapped; + + if (wrapped == null) + return base.GetReflectionType (type, instance); + + return wrapped.GetReflectionType (type, instance); + } + + public override ICustomTypeDescriptor GetTypeDescriptor (Type objectType, object instance) + { + return new DefaultTypeDescriptor (this, objectType, instance); + } + } + + // TODO: this needs more work + sealed class DefaultTypeDescriptor : CustomTypeDescriptor + { + TypeDescriptionProvider owner; + Type objectType; + object instance; + + public DefaultTypeDescriptor (TypeDescriptionProvider owner, Type objectType, object instance) + { + this.owner = owner; + this.objectType = objectType; + this.instance = instance; + } + + public override string GetClassName () + { + var wrapped = owner as WrappedTypeDescriptionProvider; + + if (wrapped != null) + return wrapped.Wrapped.GetTypeDescriptor (objectType, instance).GetClassName (); + + return base.GetClassName (); + } + + public override PropertyDescriptor GetDefaultProperty () + { + var wrapped = owner as WrappedTypeDescriptionProvider; + + if (wrapped != null) + return wrapped.Wrapped.GetTypeDescriptor (objectType, instance).GetDefaultProperty (); + + PropertyDescriptor ret; + if (objectType != null) + ret = TypeDescriptor.GetTypeInfo (objectType).GetDefaultProperty (); + else if (instance != null) + ret = TypeDescriptor.GetTypeInfo (instance.GetType ()).GetDefaultProperty (); + else + ret = base.GetDefaultProperty (); + + return ret; + } + } + + sealed class DefaultTypeDescriptionProvider : TypeDescriptionProvider + { + public DefaultTypeDescriptionProvider () + { + } + + public override ICustomTypeDescriptor GetExtendedTypeDescriptor (object instance) + { + return new DefaultTypeDescriptor (this, null, instance); + } + + public override ICustomTypeDescriptor GetTypeDescriptor (Type objectType, object instance) + { + return new DefaultTypeDescriptor (this, objectType, instance); + } + } +#endif } internal abstract class Info diff --git a/mcs/class/System/System.ComponentModel/WeakObjectWrapper.cs b/mcs/class/System/System.ComponentModel/WeakObjectWrapper.cs new file mode 100644 index 00000000000..8bf426906f8 --- /dev/null +++ b/mcs/class/System/System.ComponentModel/WeakObjectWrapper.cs @@ -0,0 +1,51 @@ +// +// System.ComponentModel.WeakObjectWrapper.cs +// +// Authors: +// Marek Habersack <mhabersack@novell.com> +// +// +// (C) 2009 Novell, Inc (http://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. +// + +#if NET_2_0 +using System; +using System.Collections; +using System.Collections.Generic; + +namespace System.ComponentModel +{ + sealed class WeakObjectWrapper + { + public int TargetHashCode { get; private set; } + public WeakReference Weak { get; private set; } + + public WeakObjectWrapper (object target) + { + TargetHashCode = target.GetHashCode (); + Weak = new WeakReference (target); + } + } +} +#endif
\ No newline at end of file diff --git a/mcs/class/System/System.ComponentModel/WeakObjectWrapperComparer.cs b/mcs/class/System/System.ComponentModel/WeakObjectWrapperComparer.cs new file mode 100644 index 00000000000..830ced2a920 --- /dev/null +++ b/mcs/class/System/System.ComponentModel/WeakObjectWrapperComparer.cs @@ -0,0 +1,67 @@ +// +// System.ComponentModel.WeakObjectWrapperComparer.cs +// +// Authors: +// Marek Habersack <mhabersack@novell.com> +// +// +// (C) 2009 Novell, Inc (http://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. +// + +#if NET_2_0 +using System; +using System.Collections; +using System.Collections.Generic; + +namespace System.ComponentModel +{ + sealed class WeakObjectWrapperComparer : EqualityComparer <WeakObjectWrapper> + { + public override bool Equals (WeakObjectWrapper x, WeakObjectWrapper y) + { + if (x == null && y == null) + return false; + + if (x == null || y == null) + return false; + + WeakReference xWeak = x.Weak; + WeakReference yWeak = y.Weak; + + if (!xWeak.IsAlive && !yWeak.IsAlive) + return false; + + return xWeak.Target == yWeak.Target; + } + + public override int GetHashCode (WeakObjectWrapper obj) + { + if (obj == null) + return 0; + + return obj.TargetHashCode; + } + } +} +#endif diff --git a/mcs/class/System/System.dll.sources b/mcs/class/System/System.dll.sources index f7df2051e56..9ba50a8e5ac 100644 --- a/mcs/class/System/System.dll.sources +++ b/mcs/class/System/System.dll.sources @@ -409,6 +409,8 @@ System.ComponentModel/UInt16Converter.cs System.ComponentModel/UInt32Converter.cs System.ComponentModel/UInt64Converter.cs System.ComponentModel/WarningException.cs +System.ComponentModel/WeakObjectWrapper.cs +System.ComponentModel/WeakObjectWrapperComparer.cs System.ComponentModel/Win32Exception.cs System.Configuration/ApplicationScopedSettingAttribute.cs System.Configuration/ApplicationSettingsBase.cs diff --git a/mcs/class/System/Test/System.ComponentModel/ChangeLog b/mcs/class/System/Test/System.ComponentModel/ChangeLog index 48306615b18..c47e32828d4 100644 --- a/mcs/class/System/Test/System.ComponentModel/ChangeLog +++ b/mcs/class/System/Test/System.ComponentModel/ChangeLog @@ -1,3 +1,8 @@ +2009-06-22 Marek Habersack <mhabersack@novell.com> + + * TypeDescriptorTests.cs: added tests for 2.0+ APIs which deal + with adding/removing/getting type description providers. + 2009-05-14 Jonathan Pryor <jpryor@novell.com> * ListChangedEventArgsTest.cs: Fix .NET 1.1 compile error. diff --git a/mcs/class/System/Test/System.ComponentModel/TypeDescriptorTests.cs b/mcs/class/System/Test/System.ComponentModel/TypeDescriptorTests.cs index 4f7055db09f..82ef9917936 100644 --- a/mcs/class/System/Test/System.ComponentModel/TypeDescriptorTests.cs +++ b/mcs/class/System/Test/System.ComponentModel/TypeDescriptorTests.cs @@ -14,6 +14,10 @@ using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; using System.ComponentModel.Design; using System.Globalization; +#if NET_2_0 +using System.Collections.Generic; +#endif + using NUnit.Framework; namespace MonoTests.System.ComponentModel @@ -362,7 +366,7 @@ namespace MonoTests.System.ComponentModel { public TestClass() {} - + void TestFunction () {} } @@ -390,7 +394,7 @@ namespace MonoTests.System.ComponentModel public TypeConverter GetConverter() { - return new StringConverter(); + return new StringConverter (); } public EventDescriptorCollection GetEvents(Attribute[] attributes) @@ -452,9 +456,53 @@ namespace MonoTests.System.ComponentModel public string GetClassName() { - return this.GetType().Name; + return this.GetType ().Name; + } + } + +#if NET_2_0 + class MyCustomTypeDescriptor : CustomTypeDescriptor + { + public MyTypeDescriptionProvider Provider { get; private set; } + + public MyCustomTypeDescriptor (MyTypeDescriptionProvider provider) + { + Provider = provider; + } + + public override string GetClassName () + { + return Provider.Id; + } + } + + class MyTypeDescriptionProvider : TypeDescriptionProvider + { + public string Id { get; private set; } + public bool CreateInstanceCalled { get; private set; } + + public MyTypeDescriptionProvider () + : this (null) + { + } + + public MyTypeDescriptionProvider (string id) + { + Id = id; + } + + public override ICustomTypeDescriptor GetTypeDescriptor (Type objectType, object instance) + { + return new MyCustomTypeDescriptor (this); + } + + public override object CreateInstance (IServiceProvider provider, Type objectType, Type[] argTypes, object[] args) + { + CreateInstanceCalled = true; + return base.CreateInstance (provider, objectType, argTypes, args); } } +#endif [TestFixture] public class TypeDescriptorTests @@ -464,6 +512,550 @@ namespace MonoTests.System.ComponentModel MyComponent nfscom = new MyComponent (new NoFilterSite (new MyContainer ())); AnotherComponent anothercom = new AnotherComponent (); +#if NET_2_0 + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void TestAddAttributes_Type_Attributes_1 () + { + TypeDescriptionProvider provider = TypeDescriptor.AddAttributes ((Type) null, null); + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void TestAddAttributes_Type_Attributes_2 () + { + TypeDescriptionProvider provider = TypeDescriptor.AddAttributes (typeof (string), null); + } + + [Test] + public void TestAddAttributes_Type_Attributes_3 () + { + Attribute[] new_attributes = new Attribute[] { + new ReadOnlyAttribute (true), + new BindableAttribute (true) + }; + + TypeDescriptionProvider provider = null; + ICustomTypeDescriptor descriptor; + AttributeCollection attributes; + + try { + provider = TypeDescriptor.AddAttributes (typeof (string), new Attribute[] { }); + Assert.IsNotNull (provider, "#A1"); + + descriptor = provider.GetTypeDescriptor (typeof (string)); + Assert.IsNotNull (descriptor, "#A1-1"); + + attributes = descriptor.GetAttributes (); + Assert.IsNotNull (attributes, "#A1-2"); + } finally { + if (provider != null) + TypeDescriptor.RemoveProvider (provider, typeof (string)); + } + + provider = null; + try { + provider = TypeDescriptor.AddAttributes (typeof (string), new_attributes); + Assert.IsNotNull (provider, "#B1"); + + descriptor = provider.GetTypeDescriptor (typeof (string)); + Assert.IsNotNull (descriptor, "#B1-1"); + + attributes = descriptor.GetAttributes (); + Assert.IsNotNull (attributes, "#B1-2"); + Assert.AreNotEqual (0, attributes.Count, "#B1-3"); + Assert.IsTrue (attributes.Contains (new_attributes)); + } finally { + if (provider != null) + TypeDescriptor.RemoveProvider (provider, typeof (string)); + } + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void TestAddAttributes_Instance_Attributes_1 () + { + TypeDescriptionProvider provider = TypeDescriptor.AddAttributes ((object) null, null); + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void TestAddAttributes_Instance_Attributes_2 () + { + string s = "test"; + TypeDescriptionProvider provider = TypeDescriptor.AddAttributes (s, null); + } + + [Test] + public void TestAddAttributes_Instance_Attributes_3 () + { + Attribute[] new_attributes = new Attribute[] { + new ReadOnlyAttribute (true), + new BindableAttribute (true) + }; + + TypeDescriptionProvider provider = null; + ICustomTypeDescriptor descriptor; + AttributeCollection attributes; + string s = "test"; + + try { + provider = TypeDescriptor.AddAttributes (s, new Attribute[] { }); + Assert.IsNotNull (provider, "#A1"); + + descriptor = provider.GetTypeDescriptor (s); + Assert.IsNotNull (descriptor, "#A1-1"); + + attributes = descriptor.GetAttributes (); + Assert.IsNotNull (attributes, "#A1-2"); + } finally { + if (provider != null) + TypeDescriptor.RemoveProvider (provider, s); + } + + provider = null; + try { + provider = TypeDescriptor.AddAttributes (s, new_attributes); + Assert.IsNotNull (provider, "#B1"); + + descriptor = provider.GetTypeDescriptor (s); + Assert.IsNotNull (descriptor, "#B1-1"); + + attributes = descriptor.GetAttributes (); + Assert.IsNotNull (attributes, "#B1-2"); + Assert.AreNotEqual (0, attributes.Count, "#B1-3"); + Assert.IsTrue (attributes.Contains (new_attributes)); + } finally { + if (provider != null) + TypeDescriptor.RemoveProvider (provider, s); + } + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void TestAddProvider_Provider_Instance_1 () + { + TypeDescriptor.AddProvider (null, (object)null); + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void TestAddProvider_Provider_Instance_2 () + { + var provider = new MyTypeDescriptionProvider (); + TypeDescriptor.AddProvider (provider, (object) null); + } + + [Test] + public void TestAddProvider_Provider_Instance_3 () + { + var instance = new MyComponent (); + var providers = new MyTypeDescriptionProvider[] { + new MyTypeDescriptionProvider ("One"), + new MyTypeDescriptionProvider ("Two"), + new MyTypeDescriptionProvider ("Three"), + new MyTypeDescriptionProvider ("Four") + }; + + try { + TypeDescriptionProvider provider; + ICustomTypeDescriptor descriptor; + + TypeDescriptor.AddProvider (providers[0], instance); + provider = TypeDescriptor.GetProvider (instance); + Assert.IsNotNull (provider, "#A1"); + descriptor = provider.GetTypeDescriptor (instance.GetType (), instance); + Assert.IsNotNull (descriptor, "#A1-1"); + Assert.AreEqual ("One", descriptor.GetClassName (), "#A1-2"); + Assert.AreEqual (false, providers[0].CreateInstanceCalled, "#A1-3"); + + descriptor.GetProperties (); + + TypeDescriptor.AddProvider (providers[1], instance); + provider = TypeDescriptor.GetProvider (instance); + Assert.IsNotNull (provider, "#B1"); + descriptor = provider.GetTypeDescriptor (instance.GetType (), instance); + Assert.IsNotNull (descriptor, "#B1-1"); + Assert.AreEqual ("Two", descriptor.GetClassName (), "#B1-2"); + + // Providers are stored in a stack according to docs, but it's in reality + // a FIFO linked list + TypeDescriptor.AddProvider (providers[2], instance); + TypeDescriptor.AddProvider (providers[3], instance); + provider = TypeDescriptor.GetProvider (instance); + Assert.IsNotNull (provider, "#C1"); + descriptor = provider.GetTypeDescriptor (instance.GetType (), instance); + Assert.IsNotNull (descriptor, "#C1-1"); + Assert.AreEqual ("Four", descriptor.GetClassName (), "#C1-2"); + + TypeDescriptor.RemoveProvider (providers[2], instance); + provider = TypeDescriptor.GetProvider (instance); + Assert.IsNotNull (provider, "#D1"); + descriptor = provider.GetTypeDescriptor (instance.GetType (), instance); + Assert.IsNotNull (descriptor, "#D1-1"); + Assert.AreEqual ("Four", descriptor.GetClassName (), "#D1-2"); + + TypeDescriptor.RemoveProvider (providers[3], instance); + provider = TypeDescriptor.GetProvider (instance); + Assert.IsNotNull (provider, "#E1"); + descriptor = provider.GetTypeDescriptor (instance.GetType (), instance); + Assert.IsNotNull (descriptor, "#E1-1"); + Assert.AreEqual ("Two", descriptor.GetClassName (), "#E1-2"); + + } finally { + TypeDescriptor.RemoveProvider (providers[0], instance); + TypeDescriptor.RemoveProvider (providers[1], instance); + TypeDescriptor.RemoveProvider (providers[2], instance); + TypeDescriptor.RemoveProvider (providers[3], instance); + } + } + + [Test] + public void TestAddProvider_Provider_Instance_4 () + { + var instance = new MyComponent (); + var providers = new MyTypeDescriptionProvider[] { + new MyTypeDescriptionProvider ("One"), + new MyTypeDescriptionProvider ("Two"), + new MyTypeDescriptionProvider ("Three"), + new MyTypeDescriptionProvider ("Four") + }; + + try { + TypeDescriptionProvider provider; + ICustomTypeDescriptor descriptor; + + TypeDescriptor.AddProvider (providers[0], instance); + provider = TypeDescriptor.GetProvider (instance); + Assert.IsNotNull (provider, "#A1"); + descriptor = provider.GetTypeDescriptor (instance.GetType (), instance); + Assert.IsNotNull (descriptor, "#A1-1"); + Assert.AreEqual ("One", descriptor.GetClassName (), "#A1-2"); + Assert.AreEqual (false, providers[0].CreateInstanceCalled, "#A1-3"); + + descriptor.GetProperties (); + + TypeDescriptor.AddProvider (providers[1], instance); + provider = TypeDescriptor.GetProvider (instance); + Assert.IsNotNull (provider, "#B1"); + descriptor = provider.GetTypeDescriptor (instance.GetType (), instance); + Assert.IsNotNull (descriptor, "#B1-1"); + Assert.AreEqual ("Two", descriptor.GetClassName (), "#B1-2"); + + // Providers are stored in a stack according to docs, but it's in reality + // a FIFO linked list + TypeDescriptor.AddProvider (providers[0], instance); + TypeDescriptor.AddProvider (providers[0], instance); + provider = TypeDescriptor.GetProvider (instance); + Assert.IsNotNull (provider, "#C1"); + descriptor = provider.GetTypeDescriptor (instance.GetType (), instance); + Assert.IsNotNull (descriptor, "#C1-1"); + Assert.AreEqual ("One", descriptor.GetClassName (), "#C1-2"); + + TypeDescriptor.RemoveProvider (providers[0], instance); + provider = TypeDescriptor.GetProvider (instance); + Assert.IsNotNull (provider, "#D1"); + descriptor = provider.GetTypeDescriptor (instance.GetType (), instance); + Assert.IsNotNull (descriptor, "#D1-1"); + Assert.AreEqual ("One", descriptor.GetClassName (), "#D1-2"); + + TypeDescriptor.RemoveProvider (providers[0], instance); + provider = TypeDescriptor.GetProvider (instance); + Assert.IsNotNull (provider, "#E1"); + descriptor = provider.GetTypeDescriptor (instance.GetType (), instance); + Assert.IsNotNull (descriptor, "#E1-1"); + Assert.AreEqual ("Two", descriptor.GetClassName (), "#E1-2"); + + } finally { + TypeDescriptor.RemoveProvider (providers[0], instance); + TypeDescriptor.RemoveProvider (providers[1], instance); + TypeDescriptor.RemoveProvider (providers[2], instance); + TypeDescriptor.RemoveProvider (providers[3], instance); + } + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void TestAddProvider_Provider_Type_1 () + { + TypeDescriptor.AddProvider (null, (Type) null); + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void TestAddProvider_Provider_Type_2 () + { + var provider = new MyTypeDescriptionProvider (); + TypeDescriptor.AddProvider (provider, (Type) null); + } + + [Test] + public void TestAddProvider_Provider_Type_3 () + { + var type = typeof (MyComponent); + var providers = new MyTypeDescriptionProvider[] { + new MyTypeDescriptionProvider ("One"), + new MyTypeDescriptionProvider ("Two"), + new MyTypeDescriptionProvider ("Three"), + new MyTypeDescriptionProvider ("Four") + }; + + try { + TypeDescriptionProvider provider; + ICustomTypeDescriptor descriptor; + + TypeDescriptor.AddProvider (providers[0], type); + provider = TypeDescriptor.GetProvider (type); + Assert.IsNotNull (provider, "#A1"); + descriptor = provider.GetTypeDescriptor (type); + Assert.IsNotNull (descriptor, "#A1-1"); + Assert.AreEqual ("One", descriptor.GetClassName (), "#A1-2"); + Assert.AreEqual (false, providers[0].CreateInstanceCalled, "#A1-3"); + + TypeDescriptor.AddProvider (providers[1], type); + provider = TypeDescriptor.GetProvider (type); + Assert.IsNotNull (provider, "#B1"); + descriptor = provider.GetTypeDescriptor (type.GetType (), type); + Assert.IsNotNull (descriptor, "#B1-1"); + Assert.AreEqual ("Two", descriptor.GetClassName (), "#B1-2"); + + // Providers are stored in a stack according to docs, but it's in reality + // a FIFO linked list + TypeDescriptor.AddProvider (providers[2], type); + TypeDescriptor.AddProvider (providers[3], type); + provider = TypeDescriptor.GetProvider (type); + Assert.IsNotNull (provider, "#C1"); + descriptor = provider.GetTypeDescriptor (type.GetType (), type); + Assert.IsNotNull (descriptor, "#C1-1"); + Assert.AreEqual ("Four", descriptor.GetClassName (), "#C1-2"); + + TypeDescriptor.RemoveProvider (providers[2], type); + provider = TypeDescriptor.GetProvider (type); + Assert.IsNotNull (provider, "#D1"); + descriptor = provider.GetTypeDescriptor (type.GetType (), type); + Assert.IsNotNull (descriptor, "#D1-1"); + Assert.AreEqual ("Four", descriptor.GetClassName (), "#D1-2"); + + TypeDescriptor.RemoveProvider (providers[3], type); + provider = TypeDescriptor.GetProvider (type); + Assert.IsNotNull (provider, "#E1"); + descriptor = provider.GetTypeDescriptor (type.GetType (), type); + Assert.IsNotNull (descriptor, "#E1-1"); + Assert.AreEqual ("Two", descriptor.GetClassName (), "#E1-2"); + + } finally { + TypeDescriptor.RemoveProvider (providers[0], type); + TypeDescriptor.RemoveProvider (providers[1], type); + TypeDescriptor.RemoveProvider (providers[2], type); + TypeDescriptor.RemoveProvider (providers[3], type); + } + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void TestGetProvider_Type_1 () + { + TypeDescriptor.GetProvider ((Type)null); + } + + [Test] + public void TestGetProvider_Type_2 () + { + TypeDescriptionProvider provider = TypeDescriptor.GetProvider (typeof (string)); + Assert.IsNotNull (provider, "#A1"); + provider = new MyTypeDescriptionProvider ("One"); + + try { + TypeDescriptor.AddProvider (provider, typeof (string)); + ICustomTypeDescriptor descriptor = provider.GetTypeDescriptor (typeof (string)); + Assert.IsNotNull (descriptor, "#B1"); + Assert.AreEqual ("One", descriptor.GetClassName (), "#B1-1"); + } finally { + TypeDescriptor.RemoveProvider (provider, typeof (string)); + } + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void TestGetProvider_Instance_1 () + { + TypeDescriptor.GetProvider ((object) null); + } + + [Test] + public void TestGetProvider_Instance_2 () + { + var instance = new MyComponent (); + TypeDescriptionProvider provider = TypeDescriptor.GetProvider (instance); + Assert.IsNotNull (provider, "#A1"); + provider = new MyTypeDescriptionProvider ("One"); + + try { + TypeDescriptor.AddProvider (provider, instance); + ICustomTypeDescriptor descriptor = provider.GetTypeDescriptor (instance); + Assert.IsNotNull (descriptor, "#B1"); + Assert.AreEqual ("One", descriptor.GetClassName (), "#B1-1"); + } finally { + TypeDescriptor.RemoveProvider (provider, instance); + } + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void TestRemoveProvider_Provider_Type_1 () + { + TypeDescriptor.RemoveProvider (null, (Type)null); + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void TestRemoveProvider_Provider_Type_2 () + { + var provider = new MyTypeDescriptionProvider (); + TypeDescriptor.RemoveProvider (provider, null); + } + + [Test] + public void TestRemoveProvider_Provider_Type_3 () + { + var provider = new MyTypeDescriptionProvider (); + bool refreshedCalled = false; + bool refreshedCorrectComponentChanged = false; + bool refreshedCorrectTypeChanged = false; + + RefreshEventHandler handler = (RefreshEventArgs args) => { + refreshedCalled = true; + refreshedCorrectComponentChanged = args.ComponentChanged == null; + refreshedCorrectTypeChanged = args.TypeChanged == typeof (string); + }; + + try { + TypeDescriptor.Refreshed += handler; + + TypeDescriptor.RemoveProvider (provider, typeof (string)); + Assert.AreEqual (true, refreshedCalled, "#A1"); + Assert.AreEqual (true, refreshedCorrectComponentChanged, "#A2"); + Assert.AreEqual (true, refreshedCorrectTypeChanged, "#A3"); + } finally { + TypeDescriptor.Refreshed -= handler; + } + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void TestRemoveProvider_Provider_Instance_1 () + { + TypeDescriptor.RemoveProvider (null, (object)null); + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void TestRemoveProvider_Provider_Instance_2 () + { + var provider = new MyTypeDescriptionProvider (); + TypeDescriptor.RemoveProvider (provider, (object)null); + } + + [Test] + public void TestRemoveProvider_Provider_Instance_3 () + { + var instance = new MyComponent (); + var provider = new MyTypeDescriptionProvider (); + bool refreshedCalled = false; + bool refreshedCorrectComponentChanged = false; + bool refreshedCorrectTypeChanged = false; + + RefreshEventHandler handler = (RefreshEventArgs args) => { + refreshedCalled = true; + refreshedCorrectComponentChanged = args.ComponentChanged == instance; + refreshedCorrectTypeChanged = args.TypeChanged == typeof (MyComponent); + }; + + try { + TypeDescriptor.Refreshed += handler; + + TypeDescriptor.RemoveProvider (provider, instance); + Assert.AreEqual (true, refreshedCalled, "#A1"); + Assert.AreEqual (true, refreshedCorrectComponentChanged, "#A2"); + Assert.AreEqual (true, refreshedCorrectTypeChanged, "#A3"); + } finally { + TypeDescriptor.Refreshed -= handler; + } + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void TestGetReflectionType_Type_1 () + { + TypeDescriptor.GetReflectionType ((Type) null); + } + + [Test] + public void TestGetReflectionType_Type_2 () + { + Type type = TypeDescriptor.GetReflectionType (typeof (string)); + Assert.IsNotNull (type, "#A1"); + Assert.AreEqual (typeof (string), type, "#A1-1"); + + type = TypeDescriptor.GetReflectionType (typeof (MyComponent)); + Assert.IsNotNull (type, "#B1"); + Assert.AreEqual (typeof (MyComponent), type, "#B1-1"); + + type = TypeDescriptor.GetReflectionType (typeof (List<string>)); + Assert.IsNotNull (type, "#C1"); + Assert.AreEqual (typeof (List <string>), type, "#C1-1"); + + type = TypeDescriptor.GetReflectionType (typeof (IList<>)); + Assert.IsNotNull (type, "#D1"); + Assert.AreEqual (typeof (IList<>), type, "#D1-1"); + + type = TypeDescriptor.GetReflectionType (typeof (IDictionary<,>)); + Assert.IsNotNull (type, "#E1"); + Assert.AreEqual (typeof (IDictionary<,>), type, "#E1-1"); + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void TestGetReflectionType_Instance_1 () + { + TypeDescriptor.GetReflectionType ((object) null); + } + + [Test] + public void TestGetReflectionType_Instance_2 () + { + string s = "string"; + Type type = TypeDescriptor.GetReflectionType (s); + Assert.IsNotNull (type, "#A1"); + Assert.AreEqual (typeof (string), type, "#A1-1"); + + var mc = new MyComponent (); + type = TypeDescriptor.GetReflectionType (mc); + Assert.IsNotNull (type, "#B1"); + Assert.AreEqual (typeof (MyComponent), type, "#B1-1"); + + var l = new List<string> (); + type = TypeDescriptor.GetReflectionType (l); + Assert.IsNotNull (type, "#C1"); + Assert.AreEqual (typeof (List<string>), type, "#C1-1"); + + IList il = new List<string> (); + type = TypeDescriptor.GetReflectionType (il); + Assert.IsNotNull (type, "#D1"); + Assert.AreEqual (typeof (List<string>), type, "#D1-1"); + + IDictionary id = new Dictionary<string, object> (); + type = TypeDescriptor.GetReflectionType (id); + Assert.IsNotNull (type, "#E1"); + Assert.AreEqual (typeof (Dictionary<string,object>), type, "#E1-1"); + + object o = 1; + type = TypeDescriptor.GetReflectionType (o); + Assert.IsNotNull (type, "#F1"); + Assert.AreEqual (typeof (int), type, "#F1-1"); + } +#endif + [Test] public void TestICustomTypeDescriptor () { |