diff options
Diffstat (limited to 'Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs')
-rw-r--r-- | Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs b/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs index 64bc7585..8b2a25fb 100644 --- a/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs +++ b/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs @@ -279,6 +279,7 @@ namespace Xamarin.Forms.Build.Tasks else if (vardefref.VariableDefinition.VariableType.ImplementsGenericInterface("Xamarin.Forms.Xaml.IMarkupExtension`1", out markupExtension, out genericArguments)) { + var acceptEmptyServiceProvider = vardefref.VariableDefinition.VariableType.GetCustomAttribute(module.ImportReference(typeof(AcceptEmptyServiceProviderAttribute))) != null; if (vardefref.VariableDefinition.VariableType.FullName == "Xamarin.Forms.Xaml.BindingExtension") foreach (var instruction in CompileBindingPath(node, context, vardefref.VariableDefinition)) yield return instruction; @@ -291,26 +292,34 @@ namespace Xamarin.Forms.Build.Tasks vardefref.VariableDefinition = new VariableDefinition(module.ImportReference(genericArguments.First())); yield return Instruction.Create(OpCodes.Ldloc, context.Variables[node]); - foreach (var instruction in node.PushServiceProvider(context, bpRef, propertyRef, propertyDeclaringTypeRef)) - yield return instruction; + if (acceptEmptyServiceProvider) + yield return Instruction.Create(OpCodes.Ldnull); + else + foreach (var instruction in node.PushServiceProvider(context, bpRef, propertyRef, propertyDeclaringTypeRef)) + yield return instruction; yield return Instruction.Create(OpCodes.Callvirt, provideValue); yield return Instruction.Create(OpCodes.Stloc, vardefref.VariableDefinition); } else if (context.Variables[node].VariableType.ImplementsInterface(module.ImportReference(typeof (IMarkupExtension)))) { + var acceptEmptyServiceProvider = context.Variables[node].VariableType.GetCustomAttribute(module.ImportReference(typeof(AcceptEmptyServiceProviderAttribute))) != null; var markExt = module.ImportReference(typeof (IMarkupExtension)).Resolve(); var provideValueInfo = markExt.Methods.First(md => md.Name == "ProvideValue"); var provideValue = module.ImportReference(provideValueInfo); vardefref.VariableDefinition = new VariableDefinition(module.TypeSystem.Object); yield return Instruction.Create(OpCodes.Ldloc, context.Variables[node]); - foreach (var instruction in node.PushServiceProvider(context, bpRef, propertyRef, propertyDeclaringTypeRef)) - yield return instruction; + if (acceptEmptyServiceProvider) + yield return Instruction.Create(OpCodes.Ldnull); + else + foreach (var instruction in node.PushServiceProvider(context, bpRef, propertyRef, propertyDeclaringTypeRef)) + yield return instruction; yield return Instruction.Create(OpCodes.Callvirt, provideValue); yield return Instruction.Create(OpCodes.Stloc, vardefref.VariableDefinition); } else if (context.Variables[node].VariableType.ImplementsInterface(module.ImportReference(typeof (IValueProvider)))) { + var acceptEmptyServiceProvider = context.Variables[node].VariableType.GetCustomAttribute(module.ImportReference(typeof(AcceptEmptyServiceProviderAttribute))) != null; var valueProviderType = context.Variables[node].VariableType; //If the IValueProvider has a ProvideCompiledAttribute that can be resolved, shortcut this var compiledValueProviderName = valueProviderType?.GetCustomAttribute(module.ImportReference(typeof(ProvideCompiledAttribute)))?.ConstructorArguments?[0].Value as string; @@ -334,8 +343,11 @@ namespace Xamarin.Forms.Build.Tasks vardefref.VariableDefinition = new VariableDefinition(module.TypeSystem.Object); yield return Instruction.Create(OpCodes.Ldloc, context.Variables[node]); - foreach (var instruction in node.PushServiceProvider(context, bpRef, propertyRef, propertyDeclaringTypeRef)) - yield return instruction; + if (acceptEmptyServiceProvider) + yield return Instruction.Create(OpCodes.Ldnull); + else + foreach (var instruction in node.PushServiceProvider(context, bpRef, propertyRef, propertyDeclaringTypeRef)) + yield return instruction; yield return Instruction.Create(OpCodes.Callvirt, provideValue); yield return Instruction.Create(OpCodes.Stloc, vardefref.VariableDefinition); } |