+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
#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)
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)
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;
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
{
if (member == XamlLanguage.Initialization)
return true;
+ if (member == XamlLanguage.PositionalParameters)
+ return true;
return IsContentValue (member.Type);
}
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;
}
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; }
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);
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;
}
}
}
// 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};
}
return null;
}
+
+ internal IEnumerable<XamlMember> GetConstructorArguments ()
+ {
+ return GetAllMembers ().Where (m => m.UnderlyingMember != null && m.CustomAttributeProvider.GetCustomAttribute<ConstructorArgumentAttribute> (false) != null);
+ }
}
}
+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
// - 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
{
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);
{
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";
+ }
+ }
}