[NUI] Add file comment and end empty line
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.XamlBuild / src / public / XamlBuild / SetResourcesVisitor.cs
1 /*
2  * Copyright(c) 2022 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 using System;
18 using System.Collections;
19 using System.Linq;
20 using Mono.Cecil;
21 using Mono.Cecil.Cil;
22 using Tizen.NUI.Xaml;
23
24 namespace Tizen.NUI.Xaml.Build.Tasks
25 {
26     class SetResourcesVisitor : IXamlNodeVisitor
27     {
28         public SetResourcesVisitor(ILContext context)
29         {
30             Context = context;
31             Module = context.Body.Method.Module;
32         }
33
34         public ILContext Context { get; }
35         ModuleDefinition Module { get; }
36         public TreeVisitingMode VisitingMode => TreeVisitingMode.TopDown;
37         public bool StopOnDataTemplate => true;
38         public bool StopOnResourceDictionary => false;
39         public bool VisitNodeOnDataTemplate => false;
40
41         public void Visit(ValueNode node, INode parentNode)
42         {
43             if (!IsResourceDictionary((IElementNode)parentNode))
44                 return;
45
46             node.Accept(new SetPropertiesVisitor(Context, stopOnResourceDictionary: false), parentNode);
47         }
48
49         public void Visit(MarkupNode node, INode parentNode)
50         {
51         }
52
53
54         public void Visit(ElementNode node, INode parentNode)
55         {
56             XmlName propertyName;
57             //Set ResourcesDictionaries to their parents
58             if (IsResourceDictionary(node) && SetPropertiesVisitor.TryGetPropertyName(node, parentNode, out propertyName)) {
59                 if ((propertyName.LocalName == "XamlResources" || propertyName.LocalName.EndsWith(".XamlResources", StringComparison.Ordinal))) {
60                     Context.IL.Append(SetPropertiesVisitor.SetPropertyValue(Context.Variables[(IElementNode)parentNode], propertyName, node, Context, node));
61                     return;
62                 }
63             }
64
65             //Only proceed further if the node is a keyless RD
66             if (   parentNode is IElementNode
67                 && IsResourceDictionary((IElementNode)parentNode)
68                 && !((IElementNode)parentNode).Properties.ContainsKey(XmlName.xKey))
69                 node.Accept(new SetPropertiesVisitor(Context, stopOnResourceDictionary: false), parentNode);
70             else if (   parentNode is ListNode
71                      && IsResourceDictionary((IElementNode)parentNode.Parent)
72                      && !((IElementNode)parentNode.Parent).Properties.ContainsKey(XmlName.xKey))
73                 node.Accept(new SetPropertiesVisitor(Context, stopOnResourceDictionary: false), parentNode);
74         }
75
76         public void Visit(RootNode node, INode parentNode)
77         {
78         }
79
80         public void Visit(ListNode node, INode parentNode)
81         {
82         }
83
84         public bool IsResourceDictionary(ElementNode node) => IsResourceDictionary((IElementNode)node);
85
86         bool IsResourceDictionary(IElementNode node)
87         {
88             var parentVar = Context.Variables[(IElementNode)node];
89             return parentVar.VariableType.FullName == "Tizen.NUI.Binding.ResourceDictionary"
90                 || parentVar.VariableType.ResolveCached().BaseType?.FullName == "Tizen.NUI.Binding.ResourceDictionary";
91         }
92
93         public bool SkipChildren(INode node, INode parentNode)
94         {
95             var enode = node as ElementNode;
96             if (enode == null)
97                 return false;
98             if (   parentNode is IElementNode
99                 && IsResourceDictionary((IElementNode)parentNode)
100                 && !((IElementNode)parentNode).Properties.ContainsKey(XmlName.xKey))
101                 return true;
102             if (   parentNode is ListNode
103                 && IsResourceDictionary((IElementNode)parentNode.Parent)
104                 && !((IElementNode)parentNode.Parent).Properties.ContainsKey(XmlName.xKey))
105                 return true;
106             return false;
107         }
108     }
109 }
110