2010-04-22 Atsushi Enomoto <atsushi@ximian.com>
authorAtsushi Eno <atsushieno@gmail.com>
Thu, 22 Apr 2010 10:18:48 +0000 (10:18 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Thu, 22 Apr 2010 10:18:48 +0000 (10:18 -0000)
* XamlObjectReader.cs
  XamlMember.cs
  TypeExtensionMethods.cs
  XamlType.cs : handle PositionalParameters, for Type type support.

* XamlObjectReaderTest.cs : add another MarkupExtension test.

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

mcs/class/System.Xaml/System.Xaml/ChangeLog
mcs/class/System.Xaml/System.Xaml/TypeExtensionMethods.cs
mcs/class/System.Xaml/System.Xaml/XamlMember.cs
mcs/class/System.Xaml/System.Xaml/XamlObjectReader.cs
mcs/class/System.Xaml/System.Xaml/XamlType.cs
mcs/class/System.Xaml/Test/System.Xaml/ChangeLog
mcs/class/System.Xaml/Test/System.Xaml/XamlObjectReaderTest.cs

index 3c6c1256ac0d246593b125ccb93f6cb2d546756f..ac419d39656296e7b2d697856a04eb0181250601 100644 (file)
@@ -1,3 +1,10 @@
+2010-04-22  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * XamlObjectReader.cs
+         XamlMember.cs
+         TypeExtensionMethods.cs
+         XamlType.cs : handle PositionalParameters, for Type type support.
+
 2010-04-20  Atsushi Enomoto  <atsushi@ximian.com>
 
        * TypeExtensionMethods.cs : add IsContentValue() for member and
index a08c1c41eea4feb4264470ce0c64969fd60990fc..c1cb02d7839acabafc0bfdd0d728ff1ba8cb0401 100644 (file)
@@ -85,15 +85,15 @@ namespace System.Xaml
                
                #region type conversion and member value retrieval
                
-               public static object GetStringValue (this XamlType xt, object obj)
+               public static string GetStringValue (this XamlType xt, object obj)
                {
                        if (obj == null)
                                return String.Empty;
                        if (obj is DateTime)
                                // FIXME: DateTimeValueSerializer should apply
-                               return TypeDescriptor.GetConverter (typeof (DateTime)).ConvertToInvariantString (obj);
+                               return (string) TypeDescriptor.GetConverter (typeof (DateTime)).ConvertToInvariantString (obj);
                        else
-                               return xt.ConvertObject (obj, typeof (string));
+                               return (string) xt.ConvertObject (obj, typeof (string));
                }
 
                public static object ConvertObject (this XamlType xt, object target, Type explicitTargetType)
@@ -101,11 +101,11 @@ namespace System.Xaml
                        return DoConvert (xt.TypeConverter, target, explicitTargetType ?? xt.UnderlyingType);
                }
                
-               public static object GetMemberValue (this XamlMember xm, object target)
+               public static object GetMemberValue (this XamlMember xm, XamlType xt, object target)
                {
-                       object native = GetPropertyOrFieldValue (xm, target);
-                       var targetRType = xm.TargetType == null ? null : xm.TargetType.UnderlyingType;
-                       return DoConvert (xm.TypeConverter, native, targetRType);
+                       object native = GetPropertyOrFieldValue (xm, xt, target);
+                       var memberRType = xm.Type == null ? null : xm.Type.UnderlyingType;
+                       return DoConvert (xm.TypeConverter, native, memberRType);
                }
                
                static object DoConvert (XamlValueConverter<TypeConverter> converter, object value, Type targetType)
@@ -117,11 +117,20 @@ namespace System.Xaml
                        return value;
                }
 
-               static object GetPropertyOrFieldValue (this XamlMember xm, object target)
+               static object GetPropertyOrFieldValue (this XamlMember xm, XamlType xt, object target)
                {
                        // FIXME: should this be done here??
                        if (xm == XamlLanguage.Initialization)
                                return target;
+                       if (xm == XamlLanguage.PositionalParameters) {
+                               var argdefs = xt.GetConstructorArguments ().ToArray ();
+                               string [] args = new string [argdefs.Length];
+                               for (int i = 0; i < args.Length; i++) {
+                                       var am = argdefs [i];
+                                       args [i] = GetStringValue (am.Type, GetMemberValue (am, xt, target));
+                               }
+                               return String.Join (", ", args);
+                       }
 
                        var mi = xm.UnderlyingMember;
                        var fi = mi as FieldInfo;
@@ -129,9 +138,9 @@ namespace System.Xaml
                                return fi.GetValue (target);
                        var pi = mi as PropertyInfo;
                        if (pi != null)
-                               return ((PropertyInfo) mi).GetValue (target, null);
+                               return pi.GetValue (target, null);
 
-                       throw new NotImplementedException ();
+                       throw new NotImplementedException (String.Format ("Cannot get value for {0}", xm));
                }
                
                #endregion
@@ -140,6 +149,8 @@ namespace System.Xaml
                {
                        if (member == XamlLanguage.Initialization)
                                return true;
+                       if (member == XamlLanguage.PositionalParameters)
+                               return true;
                        return IsContentValue (member.Type);
                }
 
@@ -155,8 +166,15 @@ namespace System.Xaml
 
                public static IEnumerable<XamlMember> GetAllReadWriteMembers (this XamlType type)
                {
+                       // FIXME: find out why only TypeExtension yields this directive. Seealso XamlObjectReaderTest
+                       if (type == XamlLanguage.Type) {
+                               yield return XamlLanguage.PositionalParameters;
+                               yield break;
+                       }
+
                        if (type.IsContentValue ())
                                yield return XamlLanguage.Initialization;
+
                        foreach (var m in type.GetAllMembers ())
                                yield return m;
                }
index 1a719056fd29a63db008fe9fa0873da379479b20..ea48357d582c7d8ad9295145963566a63b614a9d 100644 (file)
@@ -150,6 +150,10 @@ namespace System.Xaml
                bool is_predefined_directive = XamlLanguage.InitializingDirectives;
                string directive_ns;
 
+               internal ICustomAttributeProvider CustomAttributeProvider {
+                       get { return LookupCustomAttributeProvider (); }
+               }
+
                internal MethodInfo UnderlyingGetter {
                        get { return LookupUnderlyingGetter (); }
                        private set { underlying_getter = value; }
index 080018b7a55331d2abd2cc8b47557329947de373..59f87d22a0e2c70f50a2f653f9bc2f90efd5c0ed 100644 (file)
@@ -274,8 +274,10 @@ namespace System.Xaml
                        var ns = xt.PreferredXamlNamespace;
                        if (!l.Contains (ns))
                                l.Add (ns);
-                       foreach (var xm in xt.GetAllMembers ()) {
+                       foreach (var xm in xt.GetAllReadWriteMembers ()) {
                                ns = xm.PreferredXamlNamespace;
+                               if (xm is XamlDirective && ns == XamlLanguage.Xaml2006Namespace)
+                                       continue;
                                if (xm.Type.IsCollection || xm.Type.IsDictionary || xm.Type.IsArray)
                                        continue; // FIXME: process them too.
                                CollectNamespaces (l, xm.Invoker.GetValue (o), xm.Type);
@@ -312,9 +314,10 @@ namespace System.Xaml
 
                        var xm = members_stack.Peek ().Current;
                        var obj = objects.Peek ();
+                       var xt = types.Peek ();
                        if (xm == XamlLanguage.Initialization)
-                               return types.Peek ().GetStringValue (obj);
-                       return xm != null ? xm.GetMemberValue (obj) : instance;
+                               return xt.GetStringValue (obj);
+                       return xm != null ? xm.GetMemberValue (xt, obj) : instance;
                }
        }
 }
index 3625d6137f96f551e9d49a9a27b4a1484ba2c499..9113484f23c45ec5def562d62cc0ef8a6f8fda3e 100644 (file)
@@ -597,8 +597,7 @@ namespace System.Xaml
                        // If there is, then return its type.
                        if (parameterCount == 1) {
                                foreach (var xm in GetAllMembers ()) {
-                                       // not sure if we can ignore xm's CustomAttributeProvider, but it's a default lookup implementation anyways...
-                                       var ca = xm.UnderlyingMember.GetCustomAttribute<ConstructorArgumentAttribute> (false);
+                                       var ca = xm.CustomAttributeProvider.GetCustomAttribute<ConstructorArgumentAttribute> (false);
                                        if (ca != null)
                                                return new XamlType [] {xm.Type};
                                }
@@ -708,5 +707,10 @@ namespace System.Xaml
 
                        return null;
                }
+
+               internal IEnumerable<XamlMember> GetConstructorArguments ()
+               {
+                       return GetAllMembers ().Where (m => m.UnderlyingMember != null && m.CustomAttributeProvider.GetCustomAttribute<ConstructorArgumentAttribute> (false) != null);
+               }
        }
 }
index 996ee63a6af71211e5dd632da3807fb96e80f7ac..bbee007589dd09232d902cdfeda173d1d81f1dd4 100644 (file)
@@ -1,3 +1,7 @@
+2010-04-22  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * XamlObjectReaderTest.cs : add another MarkupExtension test.
+
 2010-04-20  Atsushi Enomoto  <atsushi@ximian.com>
 
        * XamlObjectReaderTest.cs : added a bunch of read detail tests (lots
index c00a4329b9463564f66440dfac8448a310998961..2fd18a5d047b46ba00312cef24b60339ff7bdb70 100644 (file)
@@ -41,6 +41,7 @@ using Category = NUnit.Framework.CategoryAttribute;
 // - Reference: [ConstructorArgument], [ContentProperty] -> only ordinal member.
 // - ArrayExtension: [ConstrutorArgument], [ContentProperty] -> no PositionalParameters, Items.
 // - NullExtension: no member.
+// - MyExtension: [ConstructorArgument] -> only ordinal members...hmm?
 
 namespace MonoTests.System.Xaml
 {
@@ -623,6 +624,30 @@ namespace MonoTests.System.Xaml
                        SimpleReadStandardType (new TypeExtension ());
                }
 
+               [Test]
+               public void Read_CustomMarkupExtension ()
+               {
+                       var r = new XamlObjectReader (new MyExtension () { Foo = typeof (int), Bar = "v2"});
+                       while (!r.IsEof) {
+                               r.Read ();
+                               if (r.Type != null && r.Type.UnderlyingType == typeof (MyExtension))
+                                       break;
+                       }
+                       Assert.IsFalse (r.IsEof, "#1");
+                       var xt = r.Type;
+                       while (!r.IsEof) {
+                               r.Read ();
+                               if (r.Member != null && r.Member.Name == "Foo")
+                                       break;
+                       }
+                       Assert.IsFalse (r.IsEof, "#2");
+                       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");
+               }
+
                void SimpleReadStandardType (object instance)
                {
                        var r = new XamlObjectReader (instance);
@@ -699,4 +724,29 @@ namespace MonoTests.System.Xaml
        {
                public TestClass3 Nested { get; set; }
        }
+
+       [MarkupExtensionReturnType (typeof (Type))]
+       public class MyExtension : MarkupExtension
+       {
+               public MyExtension ()
+               {
+               }
+
+               public MyExtension (Type arg1, string arg2)
+               {
+                       Foo = arg1;
+                       Bar = arg2;
+               }
+
+               [ConstructorArgument ("arg1")]
+               public Type Foo { get; set; }
+               
+               [ConstructorArgument ("arg2")]
+               public string Bar { get; set; }
+
+               public override object ProvideValue (IServiceProvider provider)
+               {
+                       return "provided_value";
+               }
+       }
 }