Merge pull request #961 from ermshiperete/bug-xamarin-18118
[mono.git] / mcs / class / System.Xaml / System.Xaml / XamlNode.cs
index a3a52dc0d59389f4f37a2ccaff23d86134fd0c3f..f033e78fd1cdbaa982ece60ad6c2e40906e464a9 100644 (file)
@@ -48,13 +48,20 @@ namespace System.Xaml
                        this.member = member;
                }
                
-               public XamlNodeInfo (string value)
+               public XamlNodeInfo (object value)
                {
                        node_type = XamlNodeType.Value;
                        this.value = value;
                        member = default (XamlNodeMember);
                }
                
+               public XamlNodeInfo (NamespaceDeclaration ns)
+               {
+                       node_type = XamlNodeType.NamespaceDeclaration;
+                       this.value = ns;
+                       member = default (XamlNodeMember);
+               }
+
                XamlNodeType node_type;
                object value;
                XamlNodeMember member;
@@ -72,6 +79,18 @@ namespace System.Xaml
                        get { return value; }
                }
        }
+
+       internal struct XamlNodeLineInfo
+       {
+               public readonly XamlNodeInfo Node;
+               public readonly int LineNumber, LinePosition;
+               public XamlNodeLineInfo (XamlNodeInfo node, int line, int column)
+               {
+                       Node = node;
+                       LineNumber = line;
+                       LinePosition = column;
+               }
+       }
        
        internal struct XamlObject
        {
@@ -99,24 +118,13 @@ namespace System.Xaml
                
                XamlType GetType (object obj)
                {
-                       return type.SchemaContext.GetXamlType (new InstanceContext (obj).GetWrappedValue ().GetType ());
-               }
-               
-               public IEnumerable<XamlNodeMember> Children (IValueSerializerContext vsctx)
-               {
-                       foreach (var xm in type.GetAllObjectReaderMembersByType (vsctx))
-                               yield return new XamlNodeMember (this, xm);
+                       return type.SchemaContext.GetXamlType (obj.GetType ());
                }
                
                public object GetRawValue ()
                {
                        return context.GetRawValue ();
                }
-               
-               public object GetWrappedValue ()
-               {
-                       return context.GetWrappedValue ();
-               }
        }
        
        internal struct XamlNodeMember
@@ -145,15 +153,13 @@ namespace System.Xaml
 
                XamlType GetType (object obj)
                {
-                       return owner.Type.SchemaContext.GetXamlType (new InstanceContext (obj).GetWrappedValue ().GetType ());
+                       return obj == null ? XamlLanguage.Null : owner.Type.SchemaContext.GetXamlType (new InstanceContext (obj).GetRawValue ().GetType ());
                }
        }
        
        // Its original purpose was to enable delayed reflection, but it's not supported yet.
        internal struct InstanceContext
        {
-               static readonly NullExtension null_value = new NullExtension ();
-
                public InstanceContext (object value)
                {
                        this.value = value;
@@ -161,20 +167,6 @@ namespace System.Xaml
                
                object value;
                
-               public object GetWrappedValue ()
-               {
-                       var o = GetRawValue ();
-
-                       // FIXME: should this manually checked, or is there any way to automate it?
-                       if (o == null)
-                               return null_value;
-                       if (o is Array)
-                               return new ArrayExtension ((Array) o);
-                       if (o is Type)
-                               return new TypeExtension ((Type) o);
-                       return o;
-               }
-               
                public object GetRawValue ()
                {
                        return value; // so far.
@@ -210,9 +202,15 @@ namespace System.Xaml
                                // do not read constructor arguments twice (they are written inside Arguments).
                                if (args != null && args.Contains (m))
                                        continue;
-                               // do not return non-public members. Not sure why .NET filters out them though.
+                               // do not return non-public members (of non-collection/xdata). Not sure why .NET filters out them though.
                                if (!m.IsReadPublic)
                                        continue;
+                               if (!m.IsWritePublic &&
+                                   !m.Type.IsXData &&
+                                   !m.Type.IsArray &&
+                                   !m.Type.IsCollection &&
+                                   !m.Type.IsDictionary)
+                                       continue;
 
                                yield return m;
                        }
@@ -228,6 +226,10 @@ namespace System.Xaml
                {
                        if (xm.IsUnknown)
                                return null;
+
+                       if (xm.IsAttachable)
+                               return xobj.GetRawValue (); // attachable property value
+
                        // FIXME: this looks like an ugly hack. Is this really true? What if there's MarkupExtension that uses another MarkupExtension type as a member type.
                        var obj = xobj.Context.GetRawValue ();
                        if (xm == XamlLanguage.Initialization)
@@ -237,8 +239,8 @@ namespace System.Xaml
                        if (xm == XamlLanguage.Arguments) // object itself
                                return obj;
                        if (xm == XamlLanguage.PositionalParameters)
-                               return xobj.GetWrappedValue (); // dummy value
-                       return xm.Invoker.GetValue (xobj.GetWrappedValue ());
+                               return xobj.GetRawValue (); // dummy value
+                       return xm.Invoker.GetValue (xobj.GetRawValue ());
                }
        }
 }