GetAllMSeveral fixes regarding property readability and writability.
authorAtsushi Eno <atsushi@ximian.com>
Fri, 29 Oct 2010 07:50:19 +0000 (16:50 +0900)
committerAtsushi Eno <atsushi@ximian.com>
Fri, 29 Oct 2010 07:50:19 +0000 (16:50 +0900)
XamlMember.IsReadOnly returns false if there is private get accessor.
This is used to filter nonpublic accessors out, so replaced its usage with
!IsWritePublic to check truly read-only members.

This fix also required some changes in markup types (as IsReadOnly value now
differs).

mcs/class/System.Xaml/System.Windows.Markup/ArrayExtension.cs
mcs/class/System.Xaml/System.Windows.Markup/PropertyDefinition.cs
mcs/class/System.Xaml/System.Xaml/TypeExtensionMethods.cs
mcs/class/System.Xaml/System.Xaml/XamlMember.cs
mcs/class/System.Xaml/System.Xaml/XamlNode.cs
mcs/class/System.Xaml/System.Xaml/XamlType.cs
mcs/class/System.Xaml/Test/System.Xaml/TestedTypes.cs
mcs/class/System.Xaml/Test/System.Xaml/XamlTypeTest.cs

index 9ac4a1f85a6829404ee504c9b2835a450230cea9..37c9bb99eb837092398df6e68f741efaced514eb 100755 (executable)
@@ -37,7 +37,7 @@ namespace System.Windows.Markup
        {
                public ArrayExtension ()
                {
-                       Items = new ArrayList ();
+                       items = new ArrayList ();
                }
 
                public ArrayExtension (Array elements)
@@ -45,7 +45,7 @@ namespace System.Windows.Markup
                        if (elements == null)
                                throw new ArgumentNullException ("elements");
                        Type = elements.GetType ().GetElementType ();
-                       Items = new ArrayList (elements);
+                       items = new ArrayList (elements);
                }
 
                public ArrayExtension (Type arrayType)
@@ -53,14 +53,17 @@ namespace System.Windows.Markup
                        if (arrayType == null)
                                throw new ArgumentNullException ("arrayType");
                        Type = arrayType;
-                       Items = new ArrayList ();
+                       items = new ArrayList ();
                }
 
                [ConstructorArgument ("arrayType")]
                public Type Type { get; set; }
 
+               IList items;
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
-               public IList Items { get; private set; }
+               public IList Items {
+                       get { return items; }
+               }
 
                public void AddChild (Object value)
                {
index 4a4e9fef7796efed1154f3db8f15c62ab847435e..cc6a78125ba470621e0f8a849f96197655c301cc 100755 (executable)
@@ -33,10 +33,13 @@ namespace System.Windows.Markup
        {
                public PropertyDefinition ()
                {
-                       Attributes = new List<Attribute> ();
+                       attributes = new List<Attribute> ();
                }
 
-               public IList<Attribute> Attributes { get; private set; }
+               List<Attribute> attributes;
+               public IList<Attribute> Attributes {
+                       get { return attributes; }
+               }
 
                [DefaultValue ("public")]
                public string Modifier { get; set; }
index 8cca451d7e78c3f2c094dda9bdc4e1ad82d6b11d..6594988156bae15b18e214ba8c4633bd3f29ad9b 100644 (file)
@@ -67,6 +67,8 @@ namespace System.Xaml
                                throw new ArgumentNullException ("type");
                        if (definition == null)
                                throw new ArgumentNullException ("definition");
+                       if (type == definition)
+                               return true;
 
                        foreach (var iface in type.GetInterfaces ())
                                if (iface == definition || (iface.IsGenericType && iface.GetGenericTypeDefinition () == definition))
@@ -239,19 +241,25 @@ namespace System.Xaml
                public static IEnumerable<XamlMember> GetSortedConstructorArguments (this XamlType type)
                {
                        var args = type.GetConstructorArguments ().ToArray ();
-                       var ci = type.UnderlyingType.GetConstructors ().FirstOrDefault (c => c.GetParameters ().Length == args.Length);
-                       if (ci == null)
-                               return null;
-                       var pis = ci.GetParameters ();
-                       return args.OrderBy (c => pis.FindParameterWithName (c.ConstructorArgumentName ()).Position);
+                       foreach (var ci in type.UnderlyingType.GetConstructors ().Where (c => c.GetParameters ().Length == args.Length)) {
+                               var pis = ci.GetParameters ();
+                               if (args.Length != pis.Length)
+                                       continue;
+                               bool mismatch = false;
+                               foreach (var pi in pis)
+                               for (int i = 0; i < args.Length; i++)
+                                       if (!args.Any (a => a.ConstructorArgumentName () == pi.Name))
+                                               mismatch = true;
+                               if (mismatch)
+                                       continue;
+                               return args.OrderBy (c => pis.FindParameterWithName (c.ConstructorArgumentName ()).Position);
+                       }
+                       return null;
                }
 
                static ParameterInfo FindParameterWithName (this IEnumerable<ParameterInfo> pis, string name)
                {
-                       var ret = pis.FirstOrDefault (pi => pi.Name == name);
-                       if (ret == null)
-                               throw new ArgumentException (String.Format ("Constructor argument '{0}' is expected, but was not found.", name));
-                       return ret;
+                       return pis.FirstOrDefault (pi => pi.Name == name);
                }
 
                public static string ConstructorArgumentName (this XamlMember xm)
index 45ed220f6819babcb50582ef98f40dd467c5f7d9..d8cab94973cf231c12e4ded4d96a2adf46e87970 100644 (file)
@@ -63,8 +63,8 @@ namespace System.Xaml
                        underlying_member = propertyInfo;
                        DeclaringType = schemaContext.GetXamlType (propertyInfo.DeclaringType);
                        target_type = DeclaringType;
-                       UnderlyingGetter = propertyInfo.GetGetMethod ();
-                       UnderlyingSetter = propertyInfo.GetSetMethod ();
+                       UnderlyingGetter = propertyInfo.GetGetMethod (true);
+                       UnderlyingSetter = propertyInfo.GetSetMethod (true);
                }
 
                public XamlMember (string attachableEventName, MethodInfo adder, XamlSchemaContext schemaContext)
index 7a19ccb30b3813e2f65d3189fe9719e6ec340e9b..85e0e2031fcb4267aee8b325f4fc34c8ba2313bf 100644 (file)
@@ -178,7 +178,7 @@ namespace System.Xaml
                        }
 
                        // collection items: return GetObject and Items.
-                       if (xm != null && xm.Type.IsCollection && xm.IsReadOnly) {
+                       if (xm != null && xm.Type.IsCollection && !xm.IsWritePublic) {
                                yield return new XamlNodeInfo (XamlNodeType.GetObject, xobj);
                                // Write Items member only when there are items (i.e. do not write it if it is empty).
                                var xnm = new XamlNodeMember (xobj, XamlLanguage.Items);
@@ -210,7 +210,7 @@ namespace System.Xaml
                                                continue;
 
                                // Other collections as well, but needs different iteration (as nodes contain GetObject and EndObject).
-                               if (xce.Current.Member.IsReadOnly && xce.Current.Member.Type != null && xce.Current.Member.Type.IsCollection) {
+                               if (!xce.Current.Member.IsWritePublic && xce.Current.Member.Type != null && xce.Current.Member.Type.IsCollection) {
                                        var e = GetNodes (xce.Current.Member, xce.Current.Value).GetEnumerator ();
                                        if (!(e.MoveNext () && e.MoveNext () && e.MoveNext ())) // GetObject, EndObject and more
                                                continue;
index 154eb98a1ea3a43639b4b7da601e13fadcecb518..b7fcea432c626a2c82916d609d82a21c21be0687 100644 (file)
@@ -317,7 +317,7 @@ namespace System.Xaml
 
                public XamlMember GetMember (string name)
                {
-                       return LookupMember (name, false);
+                       return LookupMember (name, true);
                }
 
                public IList<XamlType> GetPositionalParameters (int parameterCount)
@@ -414,27 +414,18 @@ namespace System.Xaml
                        foreach (var ei in UnderlyingType.GetEvents (bf))
                                yield return new XamlMember (ei, SchemaContext);
                }
+               
+               static bool IsPublicAccessor (MethodInfo mi)
+               {
+                       return mi != null && mi.IsPublic;
+               }
 
-               static bool IsCollectionType (Type type)
+               bool IsCollectionType (Type type)
                {
                        if (type == null)
                                return false;
-                       if (type.IsArray)
-                               return true;
-
-                       Type [] ifaces = type.GetInterfaces ();
-                       foreach (Type i in ifaces)
-                               if (i.IsGenericType && i.GetGenericTypeDefinition ().Equals (typeof (ICollection<>)))
-                                       return true;
-                       foreach (Type i in ifaces)
-                               if (i == typeof (IList))
-                                       return true;
-
-                       foreach (var iface in type.GetInterfaces ())
-                               if (iface == typeof (IDictionary) || (iface.IsGenericType && iface.GetGenericTypeDefinition () == typeof (IDictionary<,>)))
-                                       return true;
-
-                       return false;
+                       var xt = SchemaContext.GetXamlType (type);
+                       return xt.LookupCollectionKind () != XamlCollectionKind.None;
                }
 
                protected virtual IList<XamlType> LookupAllowedContentTypes ()
@@ -483,7 +474,7 @@ namespace System.Xaml
                        if (type.ImplementsAnyInterfacesOf (typeof (IDictionary), typeof (IDictionary<,>)))
                                return XamlCollectionKind.Dictionary;
 
-                       if (type.ImplementsAnyInterfacesOf (typeof (ICollection), typeof (ICollection<>)))
+                       if (type.ImplementsAnyInterfacesOf (typeof (IList), typeof (ICollection<>)))
                                return XamlCollectionKind.Collection;
 
                        return XamlCollectionKind.None;
index cafcb74487d0c7b16e33ec32b6781515cf5416cc..aa73111006682ce6d646f109b44901fe1eff4528 100644 (file)
@@ -83,12 +83,12 @@ namespace MonoTests.System.Xaml
        {
                public MyArrayExtension ()
                {
-                       Items = new ArrayList ();
+                       items = new ArrayList ();
                }
 
                public MyArrayExtension (Array array)
                {
-                       this.Items = array;
+                       items = new ArrayList (array);
                        this.Type = array.GetType ().GetElementType ();
                }
                
@@ -101,7 +101,11 @@ namespace MonoTests.System.Xaml
                [ConstructorArgument ("type")]
                public Type Type { get; set; }
 
-               public IList Items { get; private set; }
+               IList items;
+               public IList Items {
+                       get { return items; }
+                       private set { items = value; }
+               }
                
                public override object ProvideValue (IServiceProvider serviceProvider)
                {
index ea9fe05e4950b8537cc7ebbbf2e02ac1928fcd52..dcd701780d171681fa3f1d06b9a23f12bd3b4881 100644 (file)
@@ -210,17 +210,34 @@ namespace MonoTests.System.Xaml
                        Assert.IsFalse (t.IsArray, "#1.1");
                        Assert.IsFalse (t.IsCollection, "#1.2");
                        Assert.IsNull (t.ItemType, "#1.3");
+
                        t = new XamlType (typeof (ArrayList), sctx);
                        Assert.IsFalse (t.IsArray, "#2.1");
                        Assert.IsTrue (t.IsCollection, "#2.2");
                        Assert.IsNotNull (t.ItemType, "#2.3");
                        Assert.AreEqual ("Object", t.ItemType.Name, "#2.4");
+
                        t = new XamlType (typeof (int []), sctx);
                        Assert.IsTrue (t.IsArray, "#3.1");
-                       // why?
                        Assert.IsFalse (t.IsCollection, "#3.2");
                        Assert.IsNotNull (t.ItemType, "#3.3");
                        Assert.AreEqual (typeof (int), t.ItemType.UnderlyingType, "#3.4");
+
+                       t = new XamlType (typeof (IList), sctx);
+                       Assert.IsFalse (t.IsArray, "#4.1");
+                       Assert.IsTrue (t.IsCollection, "#4.2");
+                       Assert.IsNotNull (t.ItemType, "#4.3");
+                       Assert.AreEqual (typeof (object), t.ItemType.UnderlyingType, "#4.4");
+
+                       t = new XamlType (typeof (ICollection), sctx); // it is not a XAML collection.
+                       Assert.IsFalse (t.IsArray, "#5.1");
+                       Assert.IsFalse (t.IsCollection, "#5.2");
+                       Assert.IsNull (t.ItemType, "#5.3");
+
+                       t = new XamlType (typeof (ArrayExtension), sctx);
+                       Assert.IsFalse (t.IsArray, "#6.1");
+                       Assert.IsFalse (t.IsCollection, "#6.2");
+                       Assert.IsNull (t.ItemType, "#6.3");
                }
 
                [Test]
@@ -681,6 +698,12 @@ namespace MonoTests.System.Xaml
                public void CustomArrayExtension ()
                {
                        var xt = new XamlType (typeof (MyArrayExtension), sctx);
+                       var xm = xt.GetMember ("Items");
+                       Assert.IsNotNull (xt.GetAllMembers ().FirstOrDefault (m => m.Name == "Items"), "#0");
+                       Assert.IsNotNull (xm, "#1");
+                       Assert.IsFalse (xm.IsReadOnly, "#2"); // Surprisingly it is False. Looks like XAML ReadOnly is true only if it lacks set accessor. Having private member does not make it ReadOnly.
+                       Assert.IsTrue (xm.Type.IsCollection, "#3");
+                       Assert.IsFalse (xm.Type.IsConstructible, "#4");
                }
        }