diff options
Diffstat (limited to 'Xamarin.Forms.Build.Tasks/SetFieldVisitor.cs')
-rw-r--r-- | Xamarin.Forms.Build.Tasks/SetFieldVisitor.cs | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/Xamarin.Forms.Build.Tasks/SetFieldVisitor.cs b/Xamarin.Forms.Build.Tasks/SetFieldVisitor.cs new file mode 100644 index 00000000..1839cf7b --- /dev/null +++ b/Xamarin.Forms.Build.Tasks/SetFieldVisitor.cs @@ -0,0 +1,72 @@ +using System.Linq; +using Mono.Cecil.Cil; +using Xamarin.Forms.Xaml; + +namespace Xamarin.Forms.Build.Tasks +{ + class SetFieldVisitor : IXamlNodeVisitor + { + public SetFieldVisitor(ILContext context) + { + Context = context; + } + + public ILContext Context { get; } + + public bool VisitChildrenFirst + { + get { return false; } + } + + public bool StopOnDataTemplate + { + get { return true; } + } + + public bool StopOnResourceDictionary + { + get { return false; } + } + + public void Visit(ValueNode node, INode parentNode) + { + if (!IsXNameProperty(node, parentNode)) + return; + if (!(parentNode is RootNode)) + { + //no variable assigned for root + var field = Context.Body.Method.DeclaringType.Fields.SingleOrDefault(fd => fd.Name == (string)node.Value); + if (field == null) + return; + Context.IL.Emit(OpCodes.Ldarg_0); + Context.IL.Emit(OpCodes.Ldloc, Context.Variables[(IElementNode)parentNode]); + Context.IL.Emit(OpCodes.Stfld, field); + } + } + + public void Visit(MarkupNode node, INode parentNode) + { + } + + public void Visit(ElementNode node, INode parentNode) + { + } + + public void Visit(RootNode node, INode parentNode) + { + } + + public void Visit(ListNode node, INode parentNode) + { + } + + static bool IsXNameProperty(ValueNode node, INode parentNode) + { + var parentElement = parentNode as IElementNode; + INode xNameNode; + if (parentElement != null && parentElement.Properties.TryGetValue(XmlName.xName, out xNameNode) && xNameNode == node) + return true; + return false; + } + } +}
\ No newline at end of file |