Split XamlNode.cs to object-reader specific code and else.
authorAtsushi Eno <atsushi@ximian.com>
Thu, 11 Nov 2010 03:17:23 +0000 (12:17 +0900)
committerAtsushi Eno <atsushi@ximian.com>
Thu, 11 Nov 2010 03:17:23 +0000 (12:17 +0900)
mcs/class/System.Xaml/System.Xaml.dll.sources
mcs/class/System.Xaml/System.Xaml/XamlNode.cs
mcs/class/System.Xaml/System.Xaml/XamlObjectNodeIterator.cs [new file with mode: 0644]
mcs/class/System.Xaml/System.Xaml/XamlObjectReader.cs

index da0dbd238cf08eeaa9217b8bb3ef9d041d5a9c7b..8a9ee4f2f15f4834390a381966666ad395c39863 100644 (file)
@@ -92,6 +92,7 @@ System.Xaml/XamlNodeList.cs
 System.Xaml/XamlNodeQueue.cs
 System.Xaml/XamlNodeType.cs
 System.Xaml/XamlObjectEventArgs.cs
+System.Xaml/XamlObjectNodeIterator.cs
 System.Xaml/XamlObjectReader.cs
 System.Xaml/XamlObjectReaderException.cs
 System.Xaml/XamlObjectReaderSettings.cs
index 2c108db83a209bbb2e5af8a932b377e9c9edb98f..f18a6ba101673a9267ad90ecce73b5cae3950cc6 100644 (file)
@@ -32,240 +32,6 @@ using System.Xml;
 
 namespace System.Xaml
 {
-       internal struct XamlNodeIterator
-       {
-               static readonly XamlObject null_object = new XamlObject (XamlLanguage.Null, null);
-
-               public XamlNodeIterator (object root, XamlSchemaContext schemaContext, PrefixLookup prefixLookup)
-               {
-                       ctx = schemaContext;
-                       this.root = root;
-                       this.prefix_lookup = prefixLookup;
-               }
-               
-               XamlSchemaContext ctx;
-               object root;
-               // FIXME: this will become IServiceProvider.
-               PrefixLookup prefix_lookup;
-               
-               public XamlSchemaContext SchemaContext {
-                       get { return ctx; }
-               }
-               
-               XamlType GetType (object obj)
-               {
-                       return ctx.GetXamlType (new InstanceContext (obj).GetWrappedValue ().GetType ());
-               }
-               
-               // returns StartObject, StartMember, Value, EndMember and EndObject. (NamespaceDeclaration is not included)
-               public IEnumerable<XamlNodeInfo> GetNodes ()
-               {
-                       var xobj = new XamlObject (GetType (root), root);
-                       foreach (var node in GetNodes (null, xobj))
-                               yield return node;
-               }
-               
-               IEnumerable<XamlNodeInfo> GetNodes (XamlMember xm, XamlObject xobj)
-               {
-                       return GetNodes (xm, xobj, null);
-               }
-
-               IEnumerable<XamlNodeInfo> GetNodes (XamlMember xm, XamlObject xobj, XamlType overrideMemberType)
-               {
-                       // collection items: each item is exposed as a standalone object that has StartObject, EndObject and contents.
-                       if (xm == XamlLanguage.Items) {
-                               foreach (var xn in GetItemsNodes (xm, xobj))
-                                       yield return xn;
-                               yield break;
-                       }
-                       
-                       // Arguments: each argument is written as a standalone object
-                       if (xm == XamlLanguage.Arguments) {
-                               foreach (var argm in xobj.Type.GetSortedConstructorArguments ()) {
-                                       var argv = argm.Invoker.GetValue (xobj.GetRawValue ());
-                                       var xarg = new XamlObject (argm.Type, argv);
-                                       foreach (var cn in GetNodes (null, xarg))
-                                               yield return cn;
-                               }
-                               yield break;
-                       }
-
-                       // PositionalParameters: items are from constructor arguments, and are all in simple string value, written as Value node sequentially.
-                       if (xm == XamlLanguage.PositionalParameters) {
-                               foreach (var argm in xobj.Type.GetSortedConstructorArguments ()) {
-                                       // Unlike XamlLanguage.Items, it only outputs string value. So, convert values here.
-                                       var argv = argm.Type.GetStringValue (xobj.GetMemberValue (argm), prefix_lookup);
-                                       yield return new XamlNodeInfo ((string) argv);
-                               }
-                               yield break;
-                       }
-
-                       if (xm == XamlLanguage.Initialization) {
-                               yield return new XamlNodeInfo (xobj.Type.GetStringValue (xobj.GetRawValue (), prefix_lookup));
-                               yield break;
-                       }
-
-                       // Value - only for non-top-level node (thus xm != null)
-                       if (xm != null) {
-                               // overrideMemberType is (so far) used for XamlLanguage.Key.
-                               var xtt = overrideMemberType ?? xm.Type;
-                               if (xtt.IsContentValue ()) {
-                                       // though null value is special: it is written as a standalone object.
-                                       var val = xobj.GetRawValue ();
-                                       if (val == null)
-                                               foreach (var xn in GetNodes (null, null_object))
-                                                       yield return xn;
-                                       else
-                                               yield return new XamlNodeInfo (xtt.GetStringValue (val, prefix_lookup));
-                                       yield break;
-                               }
-                       }
-
-                       // collection items: return GetObject and Items.
-                       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);
-                               var en = GetNodes (XamlLanguage.Items, xnm.Value).GetEnumerator ();
-                               if (en.MoveNext ()) {
-                                       yield return new XamlNodeInfo (XamlNodeType.StartMember, xnm);
-                                       do {
-                                               yield return en.Current;
-                                       } while (en.MoveNext ());
-                                       yield return new XamlNodeInfo (XamlNodeType.EndMember, xnm);
-                               }
-                               yield return new XamlNodeInfo (XamlNodeType.EndObject, xobj);
-                       } else {
-                               // Object
-                               yield return new XamlNodeInfo (XamlNodeType.StartObject, xobj);
-                               foreach (var xn in GetObjectMemberNodes (xobj))
-                                       yield return xn;
-                               yield return new XamlNodeInfo (XamlNodeType.EndObject, xobj);
-                       }
-               }
-
-               IEnumerable<XamlNodeInfo> GetObjectMemberNodes (XamlObject xobj)
-               {
-                       var xce = xobj.Children ().GetEnumerator ();
-                       while (xce.MoveNext ()) {
-                               // XamlLanguage.Items does not show up if the content is empty.
-                               if (xce.Current.Member == XamlLanguage.Items)
-                                       if (!GetNodes (xce.Current.Member, xce.Current.Value).GetEnumerator ().MoveNext ())
-                                               continue;
-
-                               // Other collections as well, but needs different iteration (as nodes contain GetObject and EndObject).
-                               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;
-                               }
-
-                               yield return new XamlNodeInfo (XamlNodeType.StartMember, xce.Current);
-                               foreach (var cn in GetNodes (xce.Current.Member, xce.Current.Value))
-                                       yield return cn;
-                               yield return new XamlNodeInfo (XamlNodeType.EndMember, xce.Current);
-                       }
-               }
-
-               IEnumerable<XamlNodeInfo> GetItemsNodes (XamlMember xm, XamlObject xobj)
-               {
-                       var ie = xobj.Type.Invoker.GetItems (xobj.GetRawValue ());
-                       while (ie.MoveNext ()) {
-                               var iobj = ie.Current;
-                               // If it is dictionary, then retrieve the key, and rewrite the item as the Value part.
-                               object ikey = null;
-                               if (xobj.Type.IsDictionary) {
-                                       Type kvpType = iobj.GetType ();
-                                       bool isNonGeneric = kvpType == typeof (DictionaryEntry);
-                                       var kp = isNonGeneric ? null : kvpType.GetProperty ("Key");
-                                       var vp = isNonGeneric ? null : kvpType.GetProperty ("Value");
-                                       ikey = isNonGeneric ? ((DictionaryEntry) iobj).Key : kp.GetValue (iobj, null);
-                                       iobj = isNonGeneric ? ((DictionaryEntry) iobj).Value : vp.GetValue (iobj, null);
-                               }
-
-                               var xiobj = new XamlObject (GetType (iobj), iobj);
-                               if (ikey != null) {
-                                       // Key member is written *inside* the item object.
-                                       //
-                                       // It is messy, but Key and Value are *sorted*. In most cases Key goes first, but for example PositionalParameters comes first.
-                                       // To achieve this behavior, we compare XamlLanguage.Key and value's Member and returns in order. It's all nasty hack, but at least it could be achieved like this!
-
-                                       var en = GetNodes (null, xiobj).ToArray ();
-                                       yield return en [0]; // StartObject
-
-                                       var xknm = new XamlNodeMember (xobj, XamlLanguage.Key);
-                                       if (TypeExtensionMethods.CompareMembers (en [1].Member.Member, XamlLanguage.Key) < 0) { // en[1] is the StartMember of the first member.
-                                               // value -> key -> endobject
-                                               for (int i = 1; i < en.Length - 1; i++)
-                                                       yield return en [i];
-                                               foreach (var kn in GetKeyNodes (ikey, xobj.Type.KeyType, xknm))
-                                                       yield return kn;
-                                               yield return en [en.Length - 1];
-                                       } else {
-                                               // key -> value -> endobject
-                                               foreach (var kn in GetKeyNodes (ikey, xobj.Type.KeyType, xknm))
-                                                       yield return kn;
-                                               for (int i = 1; i < en.Length - 1; i++)
-                                                       yield return en [i];
-                                               yield return en [en.Length - 1];
-                                       }
-                               }
-                               else
-                                       foreach (var xn in GetNodes (null, xiobj))
-                                               yield return xn;
-                       }
-               }
-
-               IEnumerable<XamlNodeInfo> GetKeyNodes (object ikey, XamlType keyType, XamlNodeMember xknm)
-               {
-                       yield return new XamlNodeInfo (XamlNodeType.StartMember, xknm);
-                       foreach (var xn in GetNodes (XamlLanguage.Key, new XamlObject (GetType (ikey), ikey), keyType))
-                               yield return xn;
-                       yield return new XamlNodeInfo (XamlNodeType.EndMember, xknm);
-               }
-
-               // Namespace retrieval. 
-               // It is iterated before iterating the actual object nodes,
-               // and results are cached for use in XamlObjectReader.
-               public void CollectNamespaces ()
-               {
-                       prefix_lookup.IsCollectingNamespaces = true;
-                       foreach (var xn in GetNodes ()) {
-                               if (xn.NodeType == XamlNodeType.GetObject)
-                                       continue; // it is out of consideration here.
-                               if (xn.NodeType == XamlNodeType.StartObject) {
-                                       foreach (var ns in NamespacesInType (xn.Object.Type))
-                                               prefix_lookup.LookupPrefix (ns);
-                               } else if (xn.NodeType == XamlNodeType.StartMember) {
-                                       var xm = xn.Member.Member;
-                                       // This filtering is done as a black list so far. There does not seem to be any usable property on XamlDirective.
-                                       if (xm == XamlLanguage.Items || xm == XamlLanguage.PositionalParameters || xm == XamlLanguage.Initialization)
-                                               continue;
-                                       prefix_lookup.LookupPrefix (xn.Member.Member.PreferredXamlNamespace);
-                               } else {
-                                       if (xn.NodeType == XamlNodeType.Value && xn.Value is Type)
-                                               // this tries to lookup existing prefix, and if there isn't any, then adds a new declaration.
-                                               XamlLanguage.Type.GetStringValue (xn.Value, prefix_lookup);
-                                       continue;
-                               }
-                       }
-                       prefix_lookup.Namespaces.Sort ((nd1, nd2) => String.CompareOrdinal (nd1.Prefix, nd2.Prefix));
-                       prefix_lookup.IsCollectingNamespaces = false;
-               }
-               
-               IEnumerable<string> NamespacesInType (XamlType xt)
-               {
-                       yield return xt.PreferredXamlNamespace;
-                       if (xt.TypeArguments != null) {
-                               // It is for x:TypeArguments
-                               yield return XamlLanguage.Xaml2006Namespace;
-                               foreach (var targ in xt.TypeArguments)
-                                       foreach (var ns in NamespacesInType (targ))
-                                               yield return ns;
-                       }
-               }
-       }
-       
        internal struct XamlNodeInfo
        {
                public XamlNodeInfo (XamlNodeType nodeType, XamlObject value)
diff --git a/mcs/class/System.Xaml/System.Xaml/XamlObjectNodeIterator.cs b/mcs/class/System.Xaml/System.Xaml/XamlObjectNodeIterator.cs
new file mode 100644 (file)
index 0000000..8863e99
--- /dev/null
@@ -0,0 +1,289 @@
+//
+// Copyright (C) 2010 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.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Windows.Markup;
+using System.Xaml;
+using System.Xaml.Schema;
+
+//
+// This implementation can be compiled under .NET, using different namespace
+// (Mono.Xaml). To compile it into a usable library, use the following compile
+// optons and sources:
+//
+//     dmcs -d:DOTNET -t:library -r:System.Xaml.dll \
+//             System.Xaml/XamlObjectReader.cs \
+//             System.Xaml/XamlNode.cs \
+//             System.Xaml/PrefixLookup.cs \
+//             System.Xaml/TypeExtensionMethods.cs
+//
+// (At least it should compile as of the revision that this comment is added.)
+//
+// Adding Test/System.Xaml/TestedTypes.cs might also be useful to examine this
+// reader behavior under .NET and see where bugs are alive.
+//
+
+#if DOTNET
+namespace Mono.Xaml
+#else
+namespace System.Xaml
+#endif
+{
+       internal struct XamlObjectNodeIterator
+       {
+               static readonly XamlObject null_object = new XamlObject (XamlLanguage.Null, null);
+
+               public XamlObjectNodeIterator (object root, XamlSchemaContext schemaContext, PrefixLookup prefixLookup)
+               {
+                       ctx = schemaContext;
+                       this.root = root;
+                       this.prefix_lookup = prefixLookup;
+               }
+               
+               XamlSchemaContext ctx;
+               object root;
+               // FIXME: this will become IServiceProvider.
+               PrefixLookup prefix_lookup;
+               
+               public XamlSchemaContext SchemaContext {
+                       get { return ctx; }
+               }
+               
+               XamlType GetType (object obj)
+               {
+                       return ctx.GetXamlType (new InstanceContext (obj).GetWrappedValue ().GetType ());
+               }
+               
+               // returns StartObject, StartMember, Value, EndMember and EndObject. (NamespaceDeclaration is not included)
+               public IEnumerable<XamlNodeInfo> GetNodes ()
+               {
+                       var xobj = new XamlObject (GetType (root), root);
+                       foreach (var node in GetNodes (null, xobj))
+                               yield return node;
+               }
+               
+               IEnumerable<XamlNodeInfo> GetNodes (XamlMember xm, XamlObject xobj)
+               {
+                       return GetNodes (xm, xobj, null);
+               }
+
+               IEnumerable<XamlNodeInfo> GetNodes (XamlMember xm, XamlObject xobj, XamlType overrideMemberType)
+               {
+                       // collection items: each item is exposed as a standalone object that has StartObject, EndObject and contents.
+                       if (xm == XamlLanguage.Items) {
+                               foreach (var xn in GetItemsNodes (xm, xobj))
+                                       yield return xn;
+                               yield break;
+                       }
+                       
+                       // Arguments: each argument is written as a standalone object
+                       if (xm == XamlLanguage.Arguments) {
+                               foreach (var argm in xobj.Type.GetSortedConstructorArguments ()) {
+                                       var argv = argm.Invoker.GetValue (xobj.GetRawValue ());
+                                       var xarg = new XamlObject (argm.Type, argv);
+                                       foreach (var cn in GetNodes (null, xarg))
+                                               yield return cn;
+                               }
+                               yield break;
+                       }
+
+                       // PositionalParameters: items are from constructor arguments, and are all in simple string value, written as Value node sequentially.
+                       if (xm == XamlLanguage.PositionalParameters) {
+                               foreach (var argm in xobj.Type.GetSortedConstructorArguments ()) {
+                                       // Unlike XamlLanguage.Items, it only outputs string value. So, convert values here.
+                                       var argv = argm.Type.GetStringValue (xobj.GetMemberValue (argm), prefix_lookup);
+                                       yield return new XamlNodeInfo ((string) argv);
+                               }
+                               yield break;
+                       }
+
+                       if (xm == XamlLanguage.Initialization) {
+                               yield return new XamlNodeInfo (xobj.Type.GetStringValue (xobj.GetRawValue (), prefix_lookup));
+                               yield break;
+                       }
+
+                       // Value - only for non-top-level node (thus xm != null)
+                       if (xm != null) {
+                               // overrideMemberType is (so far) used for XamlLanguage.Key.
+                               var xtt = overrideMemberType ?? xm.Type;
+                               if (xtt.IsContentValue ()) {
+                                       // though null value is special: it is written as a standalone object.
+                                       var val = xobj.GetRawValue ();
+                                       if (val == null)
+                                               foreach (var xn in GetNodes (null, null_object))
+                                                       yield return xn;
+                                       else
+                                               yield return new XamlNodeInfo (xtt.GetStringValue (val, prefix_lookup));
+                                       yield break;
+                               }
+                       }
+
+                       // collection items: return GetObject and Items.
+                       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);
+                               var en = GetNodes (XamlLanguage.Items, xnm.Value).GetEnumerator ();
+                               if (en.MoveNext ()) {
+                                       yield return new XamlNodeInfo (XamlNodeType.StartMember, xnm);
+                                       do {
+                                               yield return en.Current;
+                                       } while (en.MoveNext ());
+                                       yield return new XamlNodeInfo (XamlNodeType.EndMember, xnm);
+                               }
+                               yield return new XamlNodeInfo (XamlNodeType.EndObject, xobj);
+                       } else {
+                               // Object
+                               yield return new XamlNodeInfo (XamlNodeType.StartObject, xobj);
+                               foreach (var xn in GetObjectMemberNodes (xobj))
+                                       yield return xn;
+                               yield return new XamlNodeInfo (XamlNodeType.EndObject, xobj);
+                       }
+               }
+
+               IEnumerable<XamlNodeInfo> GetObjectMemberNodes (XamlObject xobj)
+               {
+                       var xce = xobj.Children ().GetEnumerator ();
+                       while (xce.MoveNext ()) {
+                               // XamlLanguage.Items does not show up if the content is empty.
+                               if (xce.Current.Member == XamlLanguage.Items)
+                                       if (!GetNodes (xce.Current.Member, xce.Current.Value).GetEnumerator ().MoveNext ())
+                                               continue;
+
+                               // Other collections as well, but needs different iteration (as nodes contain GetObject and EndObject).
+                               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;
+                               }
+
+                               yield return new XamlNodeInfo (XamlNodeType.StartMember, xce.Current);
+                               foreach (var cn in GetNodes (xce.Current.Member, xce.Current.Value))
+                                       yield return cn;
+                               yield return new XamlNodeInfo (XamlNodeType.EndMember, xce.Current);
+                       }
+               }
+
+               IEnumerable<XamlNodeInfo> GetItemsNodes (XamlMember xm, XamlObject xobj)
+               {
+                       var ie = xobj.Type.Invoker.GetItems (xobj.GetRawValue ());
+                       while (ie.MoveNext ()) {
+                               var iobj = ie.Current;
+                               // If it is dictionary, then retrieve the key, and rewrite the item as the Value part.
+                               object ikey = null;
+                               if (xobj.Type.IsDictionary) {
+                                       Type kvpType = iobj.GetType ();
+                                       bool isNonGeneric = kvpType == typeof (DictionaryEntry);
+                                       var kp = isNonGeneric ? null : kvpType.GetProperty ("Key");
+                                       var vp = isNonGeneric ? null : kvpType.GetProperty ("Value");
+                                       ikey = isNonGeneric ? ((DictionaryEntry) iobj).Key : kp.GetValue (iobj, null);
+                                       iobj = isNonGeneric ? ((DictionaryEntry) iobj).Value : vp.GetValue (iobj, null);
+                               }
+
+                               var xiobj = new XamlObject (GetType (iobj), iobj);
+                               if (ikey != null) {
+                                       // Key member is written *inside* the item object.
+                                       //
+                                       // It is messy, but Key and Value are *sorted*. In most cases Key goes first, but for example PositionalParameters comes first.
+                                       // To achieve this behavior, we compare XamlLanguage.Key and value's Member and returns in order. It's all nasty hack, but at least it could be achieved like this!
+
+                                       var en = GetNodes (null, xiobj).ToArray ();
+                                       yield return en [0]; // StartObject
+
+                                       var xknm = new XamlNodeMember (xobj, XamlLanguage.Key);
+                                       if (TypeExtensionMethods.CompareMembers (en [1].Member.Member, XamlLanguage.Key) < 0) { // en[1] is the StartMember of the first member.
+                                               // value -> key -> endobject
+                                               for (int i = 1; i < en.Length - 1; i++)
+                                                       yield return en [i];
+                                               foreach (var kn in GetKeyNodes (ikey, xobj.Type.KeyType, xknm))
+                                                       yield return kn;
+                                               yield return en [en.Length - 1];
+                                       } else {
+                                               // key -> value -> endobject
+                                               foreach (var kn in GetKeyNodes (ikey, xobj.Type.KeyType, xknm))
+                                                       yield return kn;
+                                               for (int i = 1; i < en.Length - 1; i++)
+                                                       yield return en [i];
+                                               yield return en [en.Length - 1];
+                                       }
+                               }
+                               else
+                                       foreach (var xn in GetNodes (null, xiobj))
+                                               yield return xn;
+                       }
+               }
+
+               IEnumerable<XamlNodeInfo> GetKeyNodes (object ikey, XamlType keyType, XamlNodeMember xknm)
+               {
+                       yield return new XamlNodeInfo (XamlNodeType.StartMember, xknm);
+                       foreach (var xn in GetNodes (XamlLanguage.Key, new XamlObject (GetType (ikey), ikey), keyType))
+                               yield return xn;
+                       yield return new XamlNodeInfo (XamlNodeType.EndMember, xknm);
+               }
+
+               // Namespace retrieval. 
+               // It is iterated before iterating the actual object nodes,
+               // and results are cached for use in XamlObjectReader.
+               public void CollectNamespaces ()
+               {
+                       prefix_lookup.IsCollectingNamespaces = true;
+                       foreach (var xn in GetNodes ()) {
+                               if (xn.NodeType == XamlNodeType.GetObject)
+                                       continue; // it is out of consideration here.
+                               if (xn.NodeType == XamlNodeType.StartObject) {
+                                       foreach (var ns in NamespacesInType (xn.Object.Type))
+                                               prefix_lookup.LookupPrefix (ns);
+                               } else if (xn.NodeType == XamlNodeType.StartMember) {
+                                       var xm = xn.Member.Member;
+                                       // This filtering is done as a black list so far. There does not seem to be any usable property on XamlDirective.
+                                       if (xm == XamlLanguage.Items || xm == XamlLanguage.PositionalParameters || xm == XamlLanguage.Initialization)
+                                               continue;
+                                       prefix_lookup.LookupPrefix (xn.Member.Member.PreferredXamlNamespace);
+                               } else {
+                                       if (xn.NodeType == XamlNodeType.Value && xn.Value is Type)
+                                               // this tries to lookup existing prefix, and if there isn't any, then adds a new declaration.
+                                               XamlLanguage.Type.GetStringValue (xn.Value, prefix_lookup);
+                                       continue;
+                               }
+                       }
+                       prefix_lookup.Namespaces.Sort ((nd1, nd2) => String.CompareOrdinal (nd1.Prefix, nd2.Prefix));
+                       prefix_lookup.IsCollectingNamespaces = false;
+               }
+               
+               IEnumerable<string> NamespacesInType (XamlType xt)
+               {
+                       yield return xt.PreferredXamlNamespace;
+                       if (xt.TypeArguments != null) {
+                               // It is for x:TypeArguments
+                               yield return XamlLanguage.Xaml2006Namespace;
+                               foreach (var targ in xt.TypeArguments)
+                                       foreach (var ns in NamespacesInType (targ))
+                                               yield return ns;
+                       }
+               }
+       }
+}
\ No newline at end of file
index 25f7de11e8513963789e41d0f71a33a97a096f18..31d23e9d2bd9a2f5d8246870403a86ce4b28ccbf 100644 (file)
@@ -37,6 +37,7 @@ using System.Xaml.Schema;
 //
 //     dmcs -d:DOTNET -t:library -r:System.Xaml.dll \
 //             System.Xaml/XamlObjectReader.cs \
+//             System.Xaml/XamlObjectNodeIterator.cs \
 //             System.Xaml/XamlNode.cs \
 //             System.Xaml/PrefixLookup.cs \
 //             System.Xaml/TypeExtensionMethods.cs
@@ -94,7 +95,7 @@ namespace System.Xaml
                                        throw new XamlObjectReaderException (String.Format ("instance type '{0}' has no default constructor.", type));
                        }
 
-                       new XamlNodeIterator (instance, sctx, prefix_lookup).CollectNamespaces ();
+                       new XamlObjectNodeIterator (instance, sctx, prefix_lookup).CollectNamespaces ();
                }
                
                bool is_eof;
@@ -163,7 +164,7 @@ namespace System.Xaml
                        if (ns_iterator.MoveNext ())
                                return true;
                        if (nodes == null)
-                               nodes = new XamlNodeIterator (root, sctx, prefix_lookup).GetNodes ().GetEnumerator ();
+                               nodes = new XamlObjectNodeIterator (root, sctx, prefix_lookup).GetNodes ().GetEnumerator ();
                        if (nodes.MoveNext ())
                                return true;
                        if (!is_eof)