summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Build.Tasks/BindablePropertyReferenceExtensions.cs
diff options
context:
space:
mode:
authorStephane Delcroix <stephane@delcroix.org>2016-09-23 09:01:22 +0200
committerJason Smith <jason.smith@xamarin.com>2016-09-23 00:01:22 -0700
commita5183bed8d38db411549733934b53380b93773b5 (patch)
tree51953e228a71cb59600c8c5ab001a959ee811a27 /Xamarin.Forms.Build.Tasks/BindablePropertyReferenceExtensions.cs
parent1076e735697d393c7b10654f8dc7d9a91c7c13e1 (diff)
downloadxamarin-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.cs61
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