summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Xaml/MarkupExtensionParser.cs
diff options
context:
space:
mode:
authorJason Smith <jason.smith@xamarin.com>2016-03-22 13:02:25 -0700
committerJason Smith <jason.smith@xamarin.com>2016-03-22 16:13:41 -0700
commit17fdde66d94155fc62a034fa6658995bef6fd6e5 (patch)
treeb5e5073a2a7b15cdbe826faa5c763e270a505729 /Xamarin.Forms.Xaml/MarkupExtensionParser.cs
downloadxamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.tar.gz
xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.tar.bz2
xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.zip
Initial import
Diffstat (limited to 'Xamarin.Forms.Xaml/MarkupExtensionParser.cs')
-rw-r--r--Xamarin.Forms.Xaml/MarkupExtensionParser.cs80
1 files changed, 80 insertions, 0 deletions
diff --git a/Xamarin.Forms.Xaml/MarkupExtensionParser.cs b/Xamarin.Forms.Xaml/MarkupExtensionParser.cs
new file mode 100644
index 00000000..cb62e1d1
--- /dev/null
+++ b/Xamarin.Forms.Xaml/MarkupExtensionParser.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Reflection;
+
+namespace Xamarin.Forms.Xaml
+{
+ internal sealed class MarkupExtensionParser : MarkupExpressionParser, IExpressionParser<object>
+ {
+ IMarkupExtension markupExtension;
+
+ public object Parse(string match, ref string remaining, IServiceProvider serviceProvider)
+ {
+ var typeResolver = serviceProvider.GetService(typeof (IXamlTypeResolver)) as IXamlTypeResolver;
+
+ //shortcut for Binding and StaticResource, to avoid too many reflection calls.
+ if (match == "Binding")
+ markupExtension = new BindingExtension();
+ else if (match == "TemplateBinding")
+ markupExtension = new TemplateBindingExtension();
+ else if (match == "StaticResource")
+ markupExtension = new StaticResourceExtension();
+ else
+ {
+ if (typeResolver == null)
+ return null;
+ Type type;
+
+ //The order of lookup is to look for the Extension-suffixed class name first and then look for the class name without the Extension suffix.
+ if (!typeResolver.TryResolve(match + "Extension", out type) && !typeResolver.TryResolve(match, out type))
+ {
+ var lineInfoProvider = serviceProvider.GetService(typeof (IXmlLineInfoProvider)) as IXmlLineInfoProvider;
+ var lineInfo = (lineInfoProvider != null) ? lineInfoProvider.XmlLineInfo : new XmlLineInfo();
+ throw new XamlParseException(String.Format("MarkupExtension not found for {0}", match), lineInfo);
+ }
+ markupExtension = Activator.CreateInstance(type) as IMarkupExtension;
+ }
+
+ if (markupExtension == null)
+ {
+ var lineInfoProvider = serviceProvider.GetService(typeof (IXmlLineInfoProvider)) as IXmlLineInfoProvider;
+ var lineInfo = (lineInfoProvider != null) ? lineInfoProvider.XmlLineInfo : new XmlLineInfo();
+ throw new XamlParseException(String.Format("Missing public default constructor for MarkupExtension {0}", match),
+ lineInfo);
+ }
+
+ char next;
+ if (remaining == "}")
+ return markupExtension.ProvideValue(serviceProvider);
+
+ string piece;
+ while ((piece = GetNextPiece(ref remaining, out next)) != null)
+ HandleProperty(piece, serviceProvider, ref remaining, next != '=');
+
+ return markupExtension.ProvideValue(serviceProvider);
+ }
+
+ protected override void SetPropertyValue(string prop, string strValue, object value, IServiceProvider serviceProvider)
+ {
+ MethodInfo setter;
+ if (prop == null)
+ {
+ //implicit property
+ var t = markupExtension.GetType();
+ prop = ApplyPropertiesVisitor.GetContentPropertyName(t.GetTypeInfo());
+ if (prop == null)
+ return;
+ setter = t.GetRuntimeProperty(prop).SetMethod;
+ }
+ else
+ setter = markupExtension.GetType().GetRuntimeProperty(prop).SetMethod;
+
+ if (value == null && strValue != null)
+ {
+ value = strValue.ConvertTo(markupExtension.GetType().GetRuntimeProperty(prop).PropertyType,
+ (Func<TypeConverter>)null, serviceProvider);
+ }
+
+ setter.Invoke(markupExtension, new[] { value });
+ }
+ }
+} \ No newline at end of file