| File: SetResourcesVisitor.cs | Web Access |
| Project: src\src\Controls\src\Build.Tasks\Controls.Build.Tasks.csproj (Microsoft.Maui.Controls.Build.Tasks) |
using System; using System.Collections; using System.Linq; using Microsoft.Maui.Controls.Xaml; using Mono.Cecil; using Mono.Cecil.Cil; namespace Microsoft.Maui.Controls.Build.Tasks { class SetResourcesVisitor : IXamlNodeVisitor { public SetResourcesVisitor(ILContext context) { Context = context; Module = context.Body.Method.Module; } public ILContext Context { get; } ModuleDefinition Module { get; } public TreeVisitingMode VisitingMode => TreeVisitingMode.TopDown; public bool StopOnDataTemplate => true; public bool StopOnResourceDictionary => false; public bool VisitNodeOnDataTemplate => false; public void Visit(ValueNode node, INode parentNode) { if (!IsResourceDictionary((IElementNode)parentNode)) return; node.Accept(new SetPropertiesVisitor(Context, stopOnResourceDictionary: false), parentNode); } public void Visit(MarkupNode node, INode parentNode) { } public void Visit(ElementNode node, INode parentNode) { XmlName propertyName; //Set ResourcesDictionaries to their parents if (IsResourceDictionary(node) && SetPropertiesVisitor.TryGetPropertyName(node, parentNode, out propertyName)) { if ((propertyName.LocalName == "Resources" || propertyName.LocalName.EndsWith(".Resources", StringComparison.Ordinal))) { Context.IL.Append(SetPropertiesVisitor.SetPropertyValue(Context.Variables[(IElementNode)parentNode], propertyName, node, Context, node)); return; } } //Only proceed further if the node is a keyless RD if (parentNode is IElementNode && IsResourceDictionary((IElementNode)parentNode) && !((IElementNode)parentNode).Properties.ContainsKey(XmlName.xKey)) node.Accept(new SetPropertiesVisitor(Context, stopOnResourceDictionary: false), parentNode); else if (parentNode is ListNode && IsResourceDictionary((IElementNode)parentNode.Parent) && !((IElementNode)parentNode.Parent).Properties.ContainsKey(XmlName.xKey)) node.Accept(new SetPropertiesVisitor(Context, stopOnResourceDictionary: false), parentNode); } public void Visit(RootNode node, INode parentNode) { } public void Visit(ListNode node, INode parentNode) { } public bool IsResourceDictionary(ElementNode node) => IsResourceDictionary((IElementNode)node); bool IsResourceDictionary(IElementNode node) { var parentVar = Context.Variables[(IElementNode)node]; return parentVar.VariableType.FullName == "Microsoft.Maui.Controls.ResourceDictionary" || parentVar.VariableType.ResolveCached(Context.Cache).BaseType?.FullName == "Microsoft.Maui.Controls.ResourceDictionary"; } public bool SkipChildren(INode node, INode parentNode) { var enode = node as ElementNode; if (enode == null) return false; if (parentNode is IElementNode && IsResourceDictionary((IElementNode)parentNode) && !((IElementNode)parentNode).Properties.ContainsKey(XmlName.xKey)) return true; if (parentNode is ListNode && IsResourceDictionary((IElementNode)parentNode.Parent) && !((IElementNode)parentNode.Parent).Properties.ContainsKey(XmlName.xKey)) return true; return false; } } }