diff options
author | Stephane Delcroix <stephane@delcroix.org> | 2016-09-23 09:01:22 +0200 |
---|---|---|
committer | Jason Smith <jason.smith@xamarin.com> | 2016-09-23 00:01:22 -0700 |
commit | a5183bed8d38db411549733934b53380b93773b5 (patch) | |
tree | 51953e228a71cb59600c8c5ab001a959ee811a27 /Xamarin.Forms.Build.Tasks/BindablePropertyReferenceExtensions.cs | |
parent | 1076e735697d393c7b10654f8dc7d9a91c7c13e1 (diff) | |
download | xamarin-forms-a5183bed8d38db411549733934b53380b93773b5.tar.gz xamarin-forms-a5183bed8d38db411549733934b53380b93773b5.tar.bz2 xamarin-forms-a5183bed8d38db411549733934b53380b93773b5.zip |
[XamlC] Implement IValueProvider.PropertyType (#345)
Diffstat (limited to 'Xamarin.Forms.Build.Tasks/BindablePropertyReferenceExtensions.cs')
-rw-r--r-- | Xamarin.Forms.Build.Tasks/BindablePropertyReferenceExtensions.cs | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/Xamarin.Forms.Build.Tasks/BindablePropertyReferenceExtensions.cs b/Xamarin.Forms.Build.Tasks/BindablePropertyReferenceExtensions.cs new file mode 100644 index 00000000..159bbf5f --- /dev/null +++ b/Xamarin.Forms.Build.Tasks/BindablePropertyReferenceExtensions.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Xml; + +using Mono.Cecil; + +using Xamarin.Forms.Xaml; + +namespace Xamarin.Forms.Build.Tasks +{ + static class BindablePropertyReferenceExtensions + { + public static TypeReference GetBindablePropertyType(this FieldReference bpRef, IXmlLineInfo iXmlLineInfo, ModuleDefinition module) + { + if (!bpRef.Name.EndsWith("Property", StringComparison.InvariantCulture)) + throw new XamlParseException($"The name of the bindable property {bpRef.Name} does not ends with \"Property\". This is the kind of convention the world is build upon, a bit like Planck's constant.", iXmlLineInfo); + var bpName = bpRef.Name.Substring(0, bpRef.Name.Length - 8); + var owner = bpRef.DeclaringType; + TypeReference _; + + var getter = owner.GetProperty(pd => pd.Name == bpName, out _)?.GetMethod; + if (getter == null || getter.IsStatic || !getter.IsPublic) + getter = null; + getter = getter ?? owner.GetMethods(md => md.Name == $"Get{bpName}" && + md.IsStatic && + md.IsPublic && + md.Parameters.Count == 1 && + md.Parameters [0].ParameterType.FullName == "Xamarin.Forms.BindableObject", module).SingleOrDefault()?.Item1; + + if (getter == null) + throw new XamlParseException($"Missing a public static Get{bpName} or a public instance property getter for the attached property \"{bpRef.DeclaringType}.{bpRef.Name}\"", iXmlLineInfo); + return getter.ReturnType; + } + + public static TypeReference GetBindablePropertyTypeConverter(this FieldReference bpRef, ModuleDefinition module) + { + TypeReference _; + var owner = bpRef.DeclaringType; + var bpName = bpRef.Name.EndsWith("Property", StringComparison.Ordinal) ? bpRef.Name.Substring(0, bpRef.Name.Length - 8) : bpRef.Name; + var property = owner.GetProperty(pd => pd.Name == bpName, out _); + var staticGetter = owner.GetMethods(md => md.Name == $"Get{bpName}" && + md.IsStatic && + md.IsPublic && + md.Parameters.Count == 1 && + md.Parameters [0].ParameterType.FullName == "Xamarin.Forms.BindableObject", module).SingleOrDefault()?.Item1; + + var attributes = new List<CustomAttribute>(); + if (property != null && property.HasCustomAttributes) + attributes.AddRange(property.CustomAttributes); + if (property != null && property.PropertyType.Resolve().HasCustomAttributes) + attributes.AddRange(property.PropertyType.Resolve().CustomAttributes); + if (staticGetter != null && staticGetter.HasCustomAttributes) + attributes.AddRange(staticGetter.CustomAttributes); + if (staticGetter != null && staticGetter.ReturnType.Resolve().HasCustomAttributes) + attributes.AddRange(staticGetter.ReturnType.Resolve().CustomAttributes); + + return attributes.FirstOrDefault(cad => TypeConverterAttribute.TypeConvertersType.Contains(cad.AttributeType.FullName))?.ConstructorArguments [0].Value as TypeReference; + } + } +}
\ No newline at end of file |