Write null value as NullExtension regardless of its member type.
authorAtsushi Eno <atsushi@ximian.com>
Sat, 16 Oct 2010 10:06:48 +0000 (19:06 +0900)
committerAtsushi Eno <atsushi@ximian.com>
Sat, 16 Oct 2010 10:06:48 +0000 (19:06 +0900)
mcs/class/System.Xaml/System.Xaml/TypeExtensionMethods.cs
mcs/class/System.Xaml/System.Xaml/XamlObjectReader.cs
mcs/class/System.Xaml/Test/System.Xaml/XamlObjectReaderTest.cs

index 86094c14415be0a19773d7312c99761658e712e2..2d0aa185842bfd88c043775edde4d85148d8348a 100644 (file)
@@ -107,6 +107,8 @@ namespace System.Xaml
                public static object GetMemberValueForObjectReader (this XamlMember xm, XamlType xt, object target, INamespacePrefixLookup prefixLookup)
                {
                        object native = GetPropertyOrFieldValueForObjectReader (xm, xt, target, prefixLookup);
+                       if (native == null)
+                               return null; // this is to prevent SringConverter to convert null to empty.
                        var convertedType = xm.Type == null ? null : xm.Type.UnderlyingType;
                        return DoConvert (xm.TypeConverter, native, convertedType);
                }
index 581da0097e0e77acb2000c407a7b5e363263cad1..29b77ce05617aa11bfcd7f6cfacbb7ac648c0793 100644 (file)
@@ -44,7 +44,7 @@ namespace System.Xaml
                        
                        public XamlNodeType OwnerType { get; set; }
 
-                       public new IEnumerator<NamespaceDeclaration> GetEnumerator ()
+                       public IEnumerator<NamespaceDeclaration> GetEnumerator ()
                        {
                                return new NSEnumerator (this, base.GetEnumerator ());
                        }
@@ -120,7 +120,6 @@ namespace System.Xaml
                {
                }
 
-               [MonoTODO ("settings is not used")]
                public XamlObjectReader (object instance, XamlSchemaContext schemaContext, XamlObjectReaderSettings settings)
                {
                        if (schemaContext == null)
@@ -131,7 +130,7 @@ namespace System.Xaml
 
                        this.root = instance;
                        sctx = schemaContext;
-//                     this.settings = settings;
+                       this.settings = settings;
 
                        prefix_lookup = new PrefixLookup (this);
 
@@ -150,7 +149,7 @@ namespace System.Xaml
                readonly object root;
                readonly XamlType root_type;
                readonly XamlSchemaContext sctx;
-//             readonly XamlObjectReaderSettings settings;
+               readonly XamlObjectReaderSettings settings;
                readonly INamespacePrefixLookup prefix_lookup;
 
                Stack<XamlType> types = new Stack<XamlType> ();
@@ -251,7 +250,9 @@ namespace System.Xaml
                        case XamlNodeType.StartObject:
                                var obj = objects.Peek ();
                                var xt = obj != null ? SchemaContext.GetXamlType (obj.GetType ()) : XamlLanguage.Null;
-                               members = xt.GetAllObjectReaderMembers ().GetEnumerator ();
+                               ml = xt.GetAllObjectReaderMembers ().ToList ();
+                               ml.Sort ((m1, m2) => m1.DeclaringType.ContentProperty == m1 ? 1 : m2.DeclaringType.ContentProperty == m2 ? -1 : String.CompareOrdinal (m1.Name, m2.Name));
+                               members = ml.GetEnumerator ();
                                if (members.MoveNext ()) {
                                        members_stack.Push (members);
                                        StartNextMember ();
@@ -277,12 +278,14 @@ namespace System.Xaml
                                }
                                else if (curMember == XamlLanguage.Items)
                                        MoveToNextCollectionItem ();
-                               else if (!curMember.IsContentValue ())
-                                       StartNextObject (curMember);
                                else {
                                        instance = GetMemberValueOrRootInstance ();
-                                       objects.Push (GetExtensionWrappedInstance (instance));
-                                       node_type = XamlNodeType.Value;
+                                       if (instance == null || !curMember.IsContentValue ())
+                                               StartNextObject (instance, curMember);
+                                       else {
+                                               objects.Push (GetExtensionWrappedInstance (instance));
+                                               node_type = XamlNodeType.Value;
+                                       }
                                }
                                return true;
 
@@ -323,9 +326,6 @@ namespace System.Xaml
                                        if (members.Current == XamlLanguage.Items) {
                                                MoveToNextCollectionItem ();
                                                return true;
-                                       } else if (members.MoveNext ()) {
-                                               StartNextMember ();
-                                               return true;
                                        }
                                }
                                // then, move to the end of current object member.
@@ -443,14 +443,15 @@ namespace System.Xaml
                                                return null;
                                        var xtt = SchemaContext.GetXamlType (type);
                                        var ns = xtt.PreferredXamlNamespace;
+                                       var nss = collectingNamespaces;
                                        CheckAddNamespace (collectingNamespaces, ns);
                                        return null;
                                }
-                               else if (retxt.IsContentValue ())
+                               else if (retobj != null && retxt.IsContentValue ())
                                        return null;
                                else
                                        return retobj;
-                       } else if (retxt.IsContentValue ()) {
+                       } else if (retobj != null && retxt.IsContentValue ()) {
                                // FIXME: I'm not sure if this should be really done 
                                // here, but every primitive values seem to be exposed
                                // as a string, not a typed object in XamlObjectReader.
index 62f1475606daeef303234a7a7d08ce71f5ca91a7..1a91503b8c868ed3cf193214a2aa3ff710ba8e9b 100644 (file)
@@ -175,6 +175,66 @@ namespace MonoTests.System.Xaml
                        new XamlObjectReader (new TestClass3 ());
                }
 
+               [Test]
+               public void WriteNullMemberAsObject ()
+               {
+                       var r = new XamlObjectReader (new TestClass4 ());
+
+                       Assert.AreEqual (XamlNodeType.None, r.NodeType, "#1");
+                       Assert.IsTrue (r.Read (), "#6");
+                       Assert.AreEqual (XamlNodeType.NamespaceDeclaration, r.NodeType, "#7");
+                       Assert.AreEqual (String.Empty, r.Namespace.Prefix, "#7-2");
+                       Assert.AreEqual ("clr-namespace:MonoTests.System.Xaml;assembly=" + GetType ().Assembly.GetName ().Name, r.Namespace.Namespace, "#7-3");
+
+                       Assert.IsTrue (r.Read (), "#11");
+                       Assert.AreEqual (XamlNodeType.NamespaceDeclaration, r.NodeType, "#12");
+                       Assert.AreEqual ("x", r.Namespace.Prefix, "#12-2");
+                       Assert.AreEqual (XamlLanguage.Xaml2006Namespace, r.Namespace.Namespace, "#12-3");
+
+                       Assert.IsTrue (r.Read (), "#16");
+                       Assert.AreEqual (XamlNodeType.StartObject, r.NodeType, "#17");
+                       var xt = new XamlType (typeof (TestClass4), r.SchemaContext);
+                       Assert.AreEqual (xt, r.Type, "#17-2");
+                       Assert.IsTrue (r.Instance is TestClass4, "#17-3");
+                       Assert.AreEqual (2, xt.GetAllMembers ().Count, "#17-4");
+
+                       Assert.IsTrue (r.Read (), "#21");
+                       Assert.AreEqual (XamlNodeType.StartMember, r.NodeType, "#22");
+                       Assert.AreEqual (xt.GetMember ("Bar"), r.Member, "#22-2");
+
+                       Assert.IsTrue (r.Read (), "#26");
+                       Assert.AreEqual (XamlNodeType.StartObject, r.NodeType, "#27");
+                       Assert.AreEqual (XamlLanguage.Null, r.Type, "#27-2");
+                       Assert.IsNull (r.Instance, "#27-3");
+
+                       Assert.IsTrue (r.Read (), "#31");
+                       Assert.AreEqual (XamlNodeType.EndObject, r.NodeType, "#32");
+
+                       Assert.IsTrue (r.Read (), "#36");
+                       Assert.AreEqual (XamlNodeType.EndMember, r.NodeType, "#37");
+
+                       Assert.IsTrue (r.Read (), "#41");
+                       Assert.AreEqual (XamlNodeType.StartMember, r.NodeType, "#42");
+                       Assert.AreEqual (xt.GetMember ("Foo"), r.Member, "#42-2");
+
+                       Assert.IsTrue (r.Read (), "#43");
+                       Assert.AreEqual (XamlNodeType.StartObject, r.NodeType, "#43-2");
+                       Assert.AreEqual (XamlLanguage.Null, r.Type, "#43-3");
+                       Assert.IsNull (r.Instance, "#43-4");
+
+                       Assert.IsTrue (r.Read (), "#44");
+                       Assert.AreEqual (XamlNodeType.EndObject, r.NodeType, "#44-2");
+
+                       Assert.IsTrue (r.Read (), "#46");
+                       Assert.AreEqual (XamlNodeType.EndMember, r.NodeType, "#47");
+
+                       Assert.IsTrue (r.Read (), "#51");
+                       Assert.AreEqual (XamlNodeType.EndObject, r.NodeType, "#52");
+
+                       Assert.IsFalse (r.Read (), "#56");
+                       Assert.IsTrue (r.IsEof, "#57");
+               }
+
                [Test]
                public void Skip ()
                {
@@ -896,6 +956,11 @@ namespace MonoTests.System.Xaml
                public TestClass3 Nested { get; set; }
        }
 
+       public class TestClass4
+       {
+               public string Foo { get; set; }
+               public string Bar { get; set; }
+       }
 
        public class MyExtension : MarkupExtension
        {