[NUI] Add Tizen.NUI.XamlBuild module
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.XamlBuild / src / public / EXamlBuild / EXamlSetResourcesVisitor.cs
1 /*
2  * Copyright(c) 2021 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.EXaml;
23 using Tizen.NUI.Xaml;
24 using Tizen.NUI.Xaml.Build.Tasks;
25
26 namespace Tizen.NUI.EXaml.Build.Tasks
27 {
28     class EXamlSetResourcesVisitor : IXamlNodeVisitor
29     {
30         public EXamlSetResourcesVisitor(EXamlContext context)
31         {
32             Context = context;
33             Module = context.Module;
34         }
35
36         public EXamlContext Context { get; }
37         ModuleDefinition Module { get; }
38         public TreeVisitingMode VisitingMode => TreeVisitingMode.TopDown;
39         public bool StopOnDataTemplate => true;
40         public bool StopOnResourceDictionary => false;
41         public bool VisitNodeOnDataTemplate => false;
42
43         public void Visit(ValueNode node, INode parentNode)
44         {
45             if (!IsResourceDictionary((IElementNode)parentNode))
46                 return;
47
48             node.Accept(new EXamlSetPropertiesVisitor(Context, stopOnResourceDictionary: false), parentNode);
49         }
50
51         public void Visit(MarkupNode node, INode parentNode)
52         {
53         }
54
55
56         public void Visit(ElementNode node, INode parentNode)
57         {
58             XmlName propertyName;
59             //Set ResourcesDictionaries to their parents
60             if (IsResourceDictionary(node) && EXamlSetPropertiesVisitor.TryGetPropertyName(node, parentNode, out propertyName))
61             {
62                 string realPropertyName;
63                 if (propertyName.LocalName.EndsWith(".XamlResources", StringComparison.Ordinal))
64                 {
65                     realPropertyName = propertyName.LocalName.Substring(propertyName.LocalName.Length - ".XamlResources".Length);
66                 }
67                 else
68                 {
69                     realPropertyName = propertyName.LocalName;
70                 }
71
72                 if (realPropertyName == "XamlResources")
73                 {
74                     new EXamlSetProperty(Context, Context.Values[parentNode] as EXamlCreateObject, realPropertyName, Context.Values[node]);
75                     //Context.IL.Append(SetPropertiesVisitor.SetPropertyValue(Context.Variables[(IElementNode)parentNode], propertyName, node, Context, node));
76                     return;
77                 }
78             }
79
80             //Only proceed further if the node is a keyless RD
81             if (   parentNode is IElementNode
82                 && IsResourceDictionary((IElementNode)parentNode)
83                 && !((IElementNode)parentNode).Properties.ContainsKey(XmlName.xKey))
84                 node.Accept(new EXamlSetPropertiesVisitor(Context, stopOnResourceDictionary: false), parentNode);
85             else if (   parentNode is ListNode
86                      && IsResourceDictionary((IElementNode)parentNode.Parent)
87                      && !((IElementNode)parentNode.Parent).Properties.ContainsKey(XmlName.xKey))
88                 node.Accept(new EXamlSetPropertiesVisitor(Context, stopOnResourceDictionary: false), parentNode);
89         }
90
91         public void Visit(RootNode node, INode parentNode)
92         {
93         }
94
95         public void Visit(ListNode node, INode parentNode)
96         {
97         }
98
99         public bool IsResourceDictionary(ElementNode node) => IsResourceDictionary((IElementNode)node);
100
101         bool IsResourceDictionary(IElementNode node)
102         {
103             var instance = Context.Values[node] as EXamlCreateObject;
104
105             if (null != instance)
106             {
107                 return instance.Type.InheritsFromOrImplements("Tizen.NUI.Binding.ResourceDictionary");
108             }
109             else
110             {
111                 return false;
112             }
113         }
114
115         public bool SkipChildren(INode node, INode parentNode)
116         {
117             var enode = node as ElementNode;
118             if (enode == null)
119                 return false;
120             if (   parentNode is IElementNode
121                 && IsResourceDictionary((IElementNode)parentNode)
122                 && !((IElementNode)parentNode).Properties.ContainsKey(XmlName.xKey))
123                 return true;
124             if (   parentNode is ListNode
125                 && IsResourceDictionary((IElementNode)parentNode.Parent)
126                 && !((IElementNode)parentNode.Parent).Properties.ContainsKey(XmlName.xKey))
127                 return true;
128             return false;
129         }
130     }
131 }