using System.Reflection;
using System.Windows.Markup;
using System.Xaml.Schema;
+using System.Xml.Serialization;
namespace System.Xaml
{
XamlType xt;
if (XamlLanguage.InitializingTypes) {
- Name = GetXamlName (type);
+ // These are special. Only XamlLanguage members are with shorthand name.
+ if (type == typeof (PropertyDefinition))
+ Name = "Property";
+ else if (type == typeof (MemberDefinition))
+ Name = "Member";
+ else
+ Name = GetXamlName (type);
PreferredXamlNamespace = XamlLanguage.Xaml2006Namespace;
} else if ((xt = XamlLanguage.AllTypes.FirstOrDefault (t => t.UnderlyingType == type)) != null) {
Name = xt.Name;
PreferredXamlNamespace = XamlLanguage.Xaml2006Namespace;
} else {
Name = GetXamlName (type);
- PreferredXamlNamespace = String.Format ("clr-namespace:{0};assembly={1}", type.Namespace, type.Assembly.GetName ().Name);
+ PreferredXamlNamespace = schemaContext.GetXamlNamespace (type.Namespace) ?? String.Format ("clr-namespace:{0};assembly={1}", type.Namespace, type.Assembly.GetName ().Name);
}
if (type.IsGenericType) {
TypeArguments = new List<XamlType> ();
Name = unknownTypeName;
PreferredXamlNamespace = unknownTypeNamespace;
TypeArguments = typeArguments != null && typeArguments.Count == 0 ? null : typeArguments;
- explicit_ns = unknownTypeNamespace;
+// explicit_ns = unknownTypeNamespace;
}
protected XamlType (string typeName, IList<XamlType> typeArguments, XamlSchemaContext schemaContext)
Type type, underlying_type;
- string explicit_ns;
+// string explicit_ns;
// populated properties
XamlType base_type;
public bool Equals (XamlType other)
{
+ // It does not compare XamlSchemaContext.
return !IsNull (other) &&
UnderlyingType == other.UnderlyingType &&
Name == other.Name &&
public virtual bool CanAssignTo (XamlType xamlType)
{
- throw new NotImplementedException ();
+ if (this.UnderlyingType == null)
+ return xamlType == XamlLanguage.Object;
+ var ut = xamlType.UnderlyingType ?? typeof (object);
+ return ut.IsAssignableFrom (UnderlyingType);
}
public XamlMember GetAliasedProperty (XamlDirective directive)
protected virtual IEnumerable<XamlMember> LookupAllAttachableMembers ()
{
if (UnderlyingType == null)
- return BaseType != null ? BaseType.GetAllAttachableMembers () : null;
- return DoLookupAllAttachableMembers ();
+ return BaseType != null ? BaseType.GetAllAttachableMembers () : empty_array;
+ if (all_attachable_members_cache == null) {
+ all_attachable_members_cache = new List<XamlMember> (DoLookupAllAttachableMembers ());
+ all_attachable_members_cache.Sort (TypeExtensionMethods.CompareMembers);
+ }
+ return all_attachable_members_cache;
}
IEnumerable<XamlMember> DoLookupAllAttachableMembers ()
{
- yield break; // FIXME: what to return here?
+ // based on http://msdn.microsoft.com/en-us/library/ff184560.aspx
+ var bf = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
+
+ var gl = new Dictionary<string,MethodInfo> ();
+ var sl = new Dictionary<string,MethodInfo> ();
+ var al = new Dictionary<string,MethodInfo> ();
+ //var rl = new Dictionary<string,MethodInfo> ();
+ var nl = new List<string> ();
+ foreach (var mi in UnderlyingType.GetMethods (bf)) {
+ string name = null;
+ if (mi.Name.StartsWith ("Get", StringComparison.Ordinal)) {
+ if (mi.ReturnType == typeof (void))
+ continue;
+ var args = mi.GetParameters ();
+ if (args.Length != 1)
+ continue;
+ name = mi.Name.Substring (3);
+ gl.Add (name, mi);
+ } else if (mi.Name.StartsWith ("Set", StringComparison.Ordinal)) {
+ // looks like the return type is *ignored*
+ //if (mi.ReturnType != typeof (void))
+ // continue;
+ var args = mi.GetParameters ();
+ if (args.Length != 2)
+ continue;
+ name = mi.Name.Substring (3);
+ sl.Add (name, mi);
+ } else if (mi.Name.EndsWith ("Handler", StringComparison.Ordinal)) {
+ var args = mi.GetParameters ();
+ if (args.Length != 2)
+ continue;
+ if (mi.Name.StartsWith ("Add", StringComparison.Ordinal)) {
+ name = mi.Name.Substring (3, mi.Name.Length - 3 - 7);
+ al.Add (name, mi);
+ }/* else if (mi.Name.StartsWith ("Remove", StringComparison.Ordinal)) {
+ name = mi.Name.Substring (6, mi.Name.Length - 6 - 7);
+ rl.Add (name, mi);
+ }*/
+ }
+ if (name != null && !nl.Contains (name))
+ nl.Add (name);
+ }
+
+ foreach (var name in nl) {
+ MethodInfo m;
+ var g = gl.TryGetValue (name, out m) ? m : null;
+ var s = sl.TryGetValue (name, out m) ? m : null;
+ if (g != null || s != null)
+ yield return new XamlMember (name, g, s, SchemaContext);
+ var a = al.TryGetValue (name, out m) ? m : null;
+ //var r = rl.TryGetValue (name, out m) ? m : null;
+ if (a != null)
+ yield return new XamlMember (name, a, SchemaContext);
+ }
}
static readonly XamlMember [] empty_array = new XamlMember [0];
}
List<XamlMember> all_members_cache;
+ List<XamlMember> all_attachable_members_cache;
IEnumerable<XamlMember> DoLookupAllMembers ()
{
var bf = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
- foreach (var pi in UnderlyingType.GetProperties (bf))
- if (pi.CanRead && (pi.CanWrite && pi.GetIndexParameters ().Length == 0 || IsCollectionType (pi.PropertyType)))
+ foreach (var pi in UnderlyingType.GetProperties (bf)) {
+ if (pi.Name.Contains ('.')) // exclude explicit interface implementations.
+ continue;
+ if (pi.CanRead && (pi.CanWrite || IsCollectionType (pi.PropertyType) || typeof (IXmlSerializable).IsAssignableFrom (pi.PropertyType)) && pi.GetIndexParameters ().Length == 0)
yield return new XamlMember (pi, SchemaContext);
+ }
foreach (var ei in UnderlyingType.GetEvents (bf))
yield return new XamlMember (ei, SchemaContext);
}
protected virtual XamlMember LookupAttachableMember (string name)
{
- throw new NotImplementedException ();
+ return GetAllAttachableMembers ().FirstOrDefault (m => m.Name == name);
}
- [MonoTODO]
protected virtual XamlType LookupBaseType ()
{
if (base_type == null) {
if (UnderlyingType == null)
- // FIXME: probably something advanced is needed here.
- base_type = new XamlType (typeof (object), SchemaContext, Invoker);
+ base_type = SchemaContext.GetXamlType (typeof (object));
else
- base_type = type.BaseType == null || type.BaseType == typeof (object) ? null : new XamlType (type.BaseType, SchemaContext, Invoker);
+ base_type = type.BaseType == null || type.BaseType == typeof (object) ? null : SchemaContext.GetXamlType (type.BaseType);
}
return base_type;
}
// This implementation is not verified. (No place to use.)
- protected virtual XamlCollectionKind LookupCollectionKind ()
+ protected internal virtual XamlCollectionKind LookupCollectionKind ()
{
if (UnderlyingType == null)
return BaseType != null ? BaseType.LookupCollectionKind () : XamlCollectionKind.None;
protected virtual bool LookupIsNullable ()
{
- return !type.IsValueType || type.ImplementsInterface (typeof (Nullable<>));
+ return !type.IsValueType || type.IsGenericType && type.GetGenericTypeDefinition () == typeof (Nullable<>);
}
protected virtual bool LookupIsPublic ()
protected virtual bool LookupIsXData ()
{
- // huh? XamlLanguage.XData.IsXData returns false(!)
- // return typeof (XData).IsAssignableFrom (UnderlyingType);
- return false;
+ return CanAssignTo (SchemaContext.GetXamlType (typeof (IXmlSerializable)));
}
protected virtual XamlType LookupItemType ()
if (t == typeof (Type))
t = typeof (TypeExtension);
- var a = GetCustomAttributeProvider ().GetCustomAttribute<TypeConverterAttribute> (false);
- if (a != null)
- return SchemaContext.GetValueConverter<TypeConverter> (Type.GetType (a.ConverterTypeName), this);
+ var a = GetCustomAttributeProvider ();
+ var ca = a != null ? a.GetCustomAttribute<TypeConverterAttribute> (false) : null;
+ if (ca != null)
+ return SchemaContext.GetValueConverter<TypeConverter> (Type.GetType (ca.ConverterTypeName), this);
if (t == typeof (object)) // This is a special case. ConverterType is null.
return SchemaContext.GetValueConverter<TypeConverter> (null, this);
// It's still not decent to check CollectionConverter.
- var tct = TypeDescriptor.GetConverter (t).GetType ();
+ var tct = t.GetTypeConverter ().GetType ();
if (tct != typeof (TypeConverter) && tct != typeof (CollectionConverter) && tct != typeof (ReferenceConverter))
return SchemaContext.GetValueConverter<TypeConverter> (tct, this);
return null;
static string GetXamlName (Type type)
{
string n;
- if (!type.IsNested)
+ if (!type.IsNestedPublic && !type.IsNestedAssembly && !type.IsNestedPrivate)
n = type.Name;
else
n = GetXamlName (type.DeclaringType) + "+" + type.Name;