summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs
diff options
context:
space:
mode:
authorStephane Delcroix <stephane@delcroix.org>2016-12-14 13:25:42 +0100
committerGitHub <noreply@github.com>2016-12-14 13:25:42 +0100
commitd4792dc98dfca29849bedc21519d9cf9ae6f2cb6 (patch)
treed63399bcc3c99abf141944ebd4f8ff15b32b2f6f /Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs
parentf2fe64ac235871dbed5f1f09812cb5cfc11864e3 (diff)
downloadxamarin-forms-d4792dc98dfca29849bedc21519d9cf9ae6f2cb6.tar.gz
xamarin-forms-d4792dc98dfca29849bedc21519d9cf9ae6f2cb6.tar.bz2
xamarin-forms-d4792dc98dfca29849bedc21519d9cf9ae6f2cb6.zip
[XamlC] Allow compilation of IValueProviders (#622)
* [XamlC] Allow compilation of IValueProviders `IValueProvider`s tagged with the appropriate attribute will be bypassed and the compiled version, if found, will be used. This first version contains a compiled version of Setter's IValueProvider and it already reduces the amount of generated IL by 39% in, e.g. StyleTests. It's a huge gain because XamlC no longer have to generate ServiceProviders for those, so the methodbody is smaller, takes less time to jit, less time to execute and nothing is invoked at runtime, which probably saves a tons of time as well, as most IValueProvider implementation heavily uses reflection. * name bool parameters
Diffstat (limited to 'Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs')
-rw-r--r--Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs24
1 files changed, 21 insertions, 3 deletions
diff --git a/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs b/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs
index 6a7a3bef..9cf62221 100644
--- a/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs
+++ b/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs
@@ -242,7 +242,8 @@ namespace Xamarin.Forms.Build.Tasks
}
public static IEnumerable<Instruction> ProvideValue(VariableDefinitionReference vardefref, ILContext context,
- ModuleDefinition module, ElementNode node, FieldReference bpRef = null, PropertyReference propertyRef = null, TypeReference propertyDeclaringTypeRef = null)
+ ModuleDefinition module, ElementNode node, FieldReference bpRef = null,
+ PropertyReference propertyRef = null, TypeReference propertyDeclaringTypeRef = null)
{
GenericInstanceType markupExtension;
IList<TypeReference> genericArguments;
@@ -306,8 +307,25 @@ namespace Xamarin.Forms.Build.Tasks
}
else if (context.Variables[node].VariableType.ImplementsInterface(module.Import(typeof (IValueProvider))))
{
- var markExt = module.Import(typeof (IValueProvider)).Resolve();
- var provideValueInfo = markExt.Methods.First(md => md.Name == "ProvideValue");
+ var valueProviderType = context.Variables[node].VariableType;
+ //If the IValueProvider has a ProvideCompiledAttribute that can be resolved, shortcut this
+ var compiledValueProviderName = valueProviderType?.GetCustomAttribute(module.Import(typeof(ProvideCompiledAttribute)))?.ConstructorArguments?[0].Value as string;
+ Type compiledValueProviderType;
+ if (compiledValueProviderName != null && (compiledValueProviderType = Type.GetType(compiledValueProviderName)) != null) {
+ var compiledValueProvider = Activator.CreateInstance(compiledValueProviderType);
+ var cProvideValue = typeof(ICompiledValueProvider).GetMethods().FirstOrDefault(md => md.Name == "ProvideValue");
+ var instructions = (IEnumerable<Instruction>)cProvideValue.Invoke(compiledValueProvider, new object[] {
+ vardefref,
+ context.Body.Method.Module,
+ node as BaseNode,
+ context});
+ foreach (var i in instructions)
+ yield return i;
+ yield break;
+ }
+
+ var valueProviderDef = module.Import(typeof (IValueProvider)).Resolve();
+ var provideValueInfo = valueProviderDef.Methods.First(md => md.Name == "ProvideValue");
var provideValue = module.Import(provideValueInfo);
vardefref.VariableDefinition = new VariableDefinition(module.TypeSystem.Object);