2010-04-22 Atsushi Enomoto <atsushi@ximian.com>
authorAtsushi Eno <atsushieno@gmail.com>
Thu, 22 Apr 2010 11:54:12 +0000 (11:54 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Thu, 22 Apr 2010 11:54:12 +0000 (11:54 -0000)
* XamlObjectReader.cs, TypeExtensionMethods.cs : now it can return
  Type name correctly, with INamespacePrefixLookup implementation.

* XamlObjectReaderTest.cs : enabled working tests. Add decent
  namespace declaration node assertions in the next tests.

svn path=/trunk/mcs/; revision=155945

mcs/class/System.Xaml/System.Windows.Markup/ChangeLog
mcs/class/System.Xaml/System.Xaml/TypeExtensionMethods.cs
mcs/class/System.Xaml/System.Xaml/XamlObjectReader.cs
mcs/class/System.Xaml/Test/System.Xaml/ChangeLog
mcs/class/System.Xaml/Test/System.Xaml/XamlObjectReaderTest.cs

index 99f5a2e8f1de2c49e99809b772623cdaca53a6e9..510a2b890b28a7e054e796d117225e6099dcdf9b 100644 (file)
@@ -1,3 +1,8 @@
+2010-04-22  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * XamlObjectReader.cs, TypeExtensionMethods.cs : now it can return
+         Type name correctly, with INamespacePrefixLookup implementation.
+
 2010-04-20  Atsushi Enomoto  <atsushi@ximian.com>
 
        * ArrayExtension.cs : remove MonoTODO.
index f915c1153ce62ff224c85363ae3f6c83e0def2b8..2baf023b6189667955d4dbc228f7270f3c08f4ee 100644 (file)
@@ -85,10 +85,13 @@ namespace System.Xaml
                
                #region type conversion and member value retrieval
                
-               public static string GetStringValue (this XamlType xt, object obj)
+               public static string GetStringValue (this XamlType xt, object obj, INamespacePrefixLookup prefixLookup)
                {
                        if (obj == null)
                                return String.Empty;
+                       if (obj is Type)
+                               return new XamlTypeName (xt.SchemaContext.GetXamlType ((Type) obj)).ToString (prefixLookup);
+
                        if (obj is DateTime)
                                // FIXME: DateTimeValueSerializer should apply
                                return (string) TypeDescriptor.GetConverter (typeof (DateTime)).ConvertToInvariantString (obj);
@@ -101,14 +104,10 @@ namespace System.Xaml
                        return DoConvert (xt.TypeConverter, target, explicitTargetType ?? xt.UnderlyingType);
                }
                
-               public static object GetMemberValueForObjectReader (this XamlMember xm, XamlType xt, object target)
+               public static object GetMemberValueForObjectReader (this XamlMember xm, XamlType xt, object target, INamespacePrefixLookup prefixLookup)
                {
-                       object native = GetPropertyOrFieldValueForObjectReader (xm, xt, target);
+                       object native = GetPropertyOrFieldValueForObjectReader (xm, xt, target, prefixLookup);
                        var convertedType = xm.Type == null ? null : xm.Type.UnderlyingType;
-                       // FIXME: not sure if it REALLY applies to everywhere.
-                       if (convertedType == typeof (Type))
-                               convertedType = typeof (string);
-
                        return DoConvert (xm.TypeConverter, native, convertedType);
                }
                
@@ -121,7 +120,7 @@ namespace System.Xaml
                        return value;
                }
 
-               static object GetPropertyOrFieldValueForObjectReader (this XamlMember xm, XamlType xt, object target)
+               static object GetPropertyOrFieldValueForObjectReader (this XamlMember xm, XamlType xt, object target, INamespacePrefixLookup prefixLookup)
                {
                        // FIXME: should this be done here??
                        if (xm == XamlLanguage.Initialization)
@@ -131,7 +130,7 @@ namespace System.Xaml
                                string [] args = new string [argdefs.Length];
                                for (int i = 0; i < args.Length; i++) {
                                        var am = argdefs [i];
-                                       args [i] = GetStringValue (am.Type, GetMemberValueForObjectReader (am, xt, target));
+                                       args [i] = GetStringValue (am.Type, GetMemberValueForObjectReader (am, xt, target, prefixLookup), prefixLookup);
                                }
                                return String.Join (", ", args);
                        }
index 1868c322822a6bf0a71fe420d5353d17eb68ea9d..2cc044fc6ab9721b17a5b896d80c4b1eb9e6a0e9 100644 (file)
@@ -26,11 +26,14 @@ using System.Collections.Generic;
 using System.ComponentModel;
 using System.Linq;
 using System.Windows.Markup;
+using System.Xaml.Schema;
 
 namespace System.Xaml
 {
        public class XamlObjectReader : XamlReader
        {
+               #region nested types
+
                class NSList : List<NamespaceDeclaration>
                {
                        public NSList (XamlNodeType ownerType, IEnumerable<NamespaceDeclaration> nsdecls)
@@ -85,6 +88,26 @@ namespace System.Xaml
                        }
                }
        
+               class PrefixLookup : INamespacePrefixLookup
+               {
+                       XamlObjectReader source;
+
+                       public PrefixLookup (XamlObjectReader source)
+                       {
+                               this.source = source;
+                       }
+
+                       public string LookupPrefix (string ns)
+                       {
+                               foreach (var nsd in source.namespaces)
+                                       if (nsd.Namespace == ns)
+                                               return nsd.Prefix;
+                               return null;
+                       }
+               }
+
+               #endregion nested types
+
                public XamlObjectReader (object instance)
                        : this (instance, new XamlSchemaContext (null, null), null)
                {
@@ -112,6 +135,8 @@ namespace System.Xaml
                        sctx = schemaContext;
                        this.settings = settings;
 
+                       prefix_lookup = new PrefixLookup (this);
+
                        if (instance != null) {
                                // check type validity. Note that some checks are done at Read() phase.
                                var type = instance.GetType ();
@@ -130,10 +155,13 @@ namespace System.Xaml
                XamlSchemaContext sctx;
                XamlObjectReaderSettings settings;
 
+               INamespacePrefixLookup prefix_lookup;
+
                Stack<XamlType> types = new Stack<XamlType> ();
                Stack<object> objects = new Stack<object> ();
                Stack<IEnumerator<XamlMember>> members_stack = new Stack<IEnumerator<XamlMember>> ();
-               IEnumerator<NamespaceDeclaration> namespaces;
+               NSList namespaces;
+               IEnumerator<NamespaceDeclaration> ns_iterator;
                XamlNodeType node_type = XamlNodeType.None;
                bool is_eof;
 
@@ -150,7 +178,7 @@ namespace System.Xaml
                }
 
                public override NamespaceDeclaration Namespace {
-                       get { return NodeType == XamlNodeType.NamespaceDeclaration ? namespaces.Current : null; }
+                       get { return NodeType == XamlNodeType.NamespaceDeclaration ? ns_iterator.Current : null; }
                }
 
                public override XamlNodeType NodeType {
@@ -183,16 +211,17 @@ namespace System.Xaml
                                var l = new List<string> ();
                                CollectNamespaces (l, instance, root_type);
                                var nss = from s in l select new NamespaceDeclaration (s, s == XamlLanguage.Xaml2006Namespace ? "x" : s == root_type.PreferredXamlNamespace ? String.Empty : SchemaContext.GetPreferredPrefix (s));
-                               namespaces = new NSList (XamlNodeType.StartObject, nss).GetEnumerator ();
+                               namespaces = new NSList (XamlNodeType.StartObject, nss);
+                               ns_iterator = namespaces.GetEnumerator ();
 
-                               namespaces.MoveNext ();
+                               ns_iterator.MoveNext ();
                                node_type = XamlNodeType.NamespaceDeclaration;
                                return true;
 
                        case XamlNodeType.NamespaceDeclaration:
-                               if (namespaces.MoveNext ())
+                               if (ns_iterator.MoveNext ())
                                        return true;
-                               node_type = ((NSEnumerator) namespaces).OwnerType; // StartObject or StartMember
+                               node_type = ((NSEnumerator) ns_iterator).OwnerType; // StartObject or StartMember
                                if (node_type == XamlNodeType.StartObject)
                                        StartNextObject ();
                                else
@@ -315,9 +344,24 @@ namespace System.Xaml
                        var xm = members_stack.Peek ().Current;
                        var obj = objects.Peek ();
                        var xt = types.Peek ();
-                       if (xt.IsContentValue ())
-                               return xt.GetStringValue (obj);
-                       return xm != null ? xm.GetMemberValueForObjectReader (xt, obj) : instance;
+
+                       object retobj;
+                       XamlType retxt;
+                       if (xt.IsContentValue ()) {
+                               retxt = xt;
+                               retobj = obj;
+                       } else {
+                               retxt = xm.Type;
+                               retobj = xm.GetMemberValueForObjectReader (xt, obj, prefix_lookup);
+                       }
+
+                       // 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.
+                       if (retxt.IsContentValue ())
+                               return retxt.GetStringValue (retobj, prefix_lookup);
+                       else
+                               return retobj;
                }
        }
 }
index bbee007589dd09232d902cdfeda173d1d81f1dd4..d373b3474c75fccf29fa20b383390fbc9fe039cf 100644 (file)
@@ -1,3 +1,8 @@
+2010-04-22  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * XamlObjectReaderTest.cs : enabled working tests. Add decent
+         namespace declaration node assertions in the next tests.
+
 2010-04-22  Atsushi Enomoto  <atsushi@ximian.com>
 
        * XamlObjectReaderTest.cs : add another MarkupExtension test.
index 2fd18a5d047b46ba00312cef24b60339ff7bdb70..7b3a746aa74f2df5be8134d848bd0d90589b2717 100644 (file)
@@ -276,7 +276,6 @@ namespace MonoTests.System.Xaml
                }
 
                [Test]
-               [Category ("NotWorking")]
                public void Read_Type ()
                {
                        var r = new XamlObjectReader (typeof (int));
@@ -284,7 +283,6 @@ namespace MonoTests.System.Xaml
                }
                
                [Test]
-               [Category ("NotWorking")]
                public void Read_TypeExtension ()
                {
                        var r = new XamlObjectReader (new TypeExtension (typeof (int)));
@@ -355,14 +353,21 @@ namespace MonoTests.System.Xaml
                {
                        Assert.IsTrue (r.Read (), "#11");
                        Assert.AreEqual (XamlNodeType.NamespaceDeclaration, r.NodeType, "#12");
-                       Assert.AreEqual (String.Empty, r.Namespace.Prefix, "#13-2");
-                       Assert.AreEqual ("clr-namespace:MonoTests.System.Xaml;assembly=" + GetType ().Assembly.GetName ().Name, r.Namespace.Namespace, "#13-3");
+
+                       var nsmap = new Dictionary<string,string> ();
+                       nsmap ["x"] = XamlLanguage.Xaml2006Namespace;
+                       nsmap [String.Empty] = "clr-namespace:MonoTests.System.Xaml;assembly=" + GetType ().Assembly.GetName ().Name;
+
+                       Assert.IsTrue (nsmap.ContainsKey (r.Namespace.Prefix), "#13-2");
+                       Assert.AreEqual (nsmap [r.Namespace.Prefix], r.Namespace.Namespace, "#13-3:" + r.Namespace.Prefix);
+                       nsmap.Remove (r.Namespace.Prefix);
 
                        Assert.IsTrue (r.Read (), "#16");
                        Assert.AreEqual (XamlNodeType.NamespaceDeclaration, r.NodeType, "#17");
                        Assert.IsNotNull (r.Namespace, "#18");
-                       Assert.AreEqual ("x", r.Namespace.Prefix, "#18-2");
-                       Assert.AreEqual (XamlLanguage.Xaml2006Namespace, r.Namespace.Namespace, "#18-3");
+                       Assert.IsTrue (nsmap.ContainsKey (r.Namespace.Prefix), "#18-2");
+                       Assert.AreEqual (nsmap [r.Namespace.Prefix], r.Namespace.Namespace, "#18-3:" + r.Namespace.Prefix);
+                       nsmap.Remove (r.Namespace.Prefix);
 
                        Assert.IsTrue (r.Read (), "#21");
                        Assert.AreEqual (XamlNodeType.StartObject, r.NodeType, "#22");
@@ -644,8 +649,7 @@ namespace MonoTests.System.Xaml
                        Assert.AreEqual (xt.GetMember ("Foo"), r.Member, "#3");
                        Assert.IsTrue (r.Read (), "#4");
                        Assert.AreEqual (XamlNodeType.Value, r.NodeType, "#5");
-                       // FIXME: enable this.
-                       //Assert.AreEqual ("x:Int32", r.Value, "#6");
+                       Assert.AreEqual ("x:Int32", r.Value, "#6");
                }
 
                void SimpleReadStandardType (object instance)