2 * Copyright(c) 2021 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 using System.Collections.Generic;
23 using Tizen.NUI.Xaml.Build.Tasks;
25 namespace Tizen.NUI.EXaml.Build.Tasks
27 class EXamlSetNamescopesAndRegisterNamesVisitor : IXamlNodeVisitor
29 public EXamlSetNamescopesAndRegisterNamesVisitor(EXamlContext context)
34 EXamlContext Context { get; }
36 public TreeVisitingMode VisitingMode => TreeVisitingMode.TopDown;
37 public bool StopOnDataTemplate => true;
38 public bool StopOnResourceDictionary => false;
39 public bool VisitNodeOnDataTemplate => false;
40 public bool SkipChildren(INode node, INode parentNode) => false;
42 public bool IsResourceDictionary(ElementNode node)
44 var parentVar = Context.Variables[(IElementNode)node];
45 return parentVar.VariableType.FullName == "Tizen.NUI.Binding.ResourceDictionary"
46 || parentVar.VariableType.Resolve().BaseType?.FullName == "Tizen.NUI.Binding.ResourceDictionary";
49 public void Visit(ValueNode node, INode parentNode)
51 Context.Scopes[node] = Context.Scopes[parentNode];
52 if (!IsXNameProperty(node, parentNode))
54 new EXaml.EXamlRegisterXName(Context, Context.Values[parentNode], node.Value as string);
55 //RegisterName((string)node.Value, Context.Scopes[node].Item1, Context.Scopes[node].Item2, Context.Variables[(IElementNode)parentNode], node);
56 //SetStyleId((string)node.Value, Context.Variables[(IElementNode)parentNode]);
59 public void Visit(MarkupNode node, INode parentNode)
61 Context.Scopes[node] = Context.Scopes[parentNode];
64 public void Visit(ElementNode node, INode parentNode)
66 VariableDefinition namescopeVarDef;
67 IList<string> namesInNamescope;
68 var setNameScope = false;
69 if (parentNode == null || IsDataTemplate(node, parentNode) || IsStyle(node, parentNode) || IsVisualStateGroupList(node)) {
70 namescopeVarDef = CreateNamescope();
71 namesInNamescope = new List<string>();
74 namescopeVarDef = Context.Scopes[parentNode].Item1;
75 namesInNamescope = Context.Scopes[parentNode].Item2;
77 if (setNameScope && Context.Variables[node].VariableType.InheritsFromOrImplements(Context.Module.ImportReference((XamlTask.xamlAssemblyName, XamlTask.bindingNameSpace, "BindableObject"))))
78 SetNameScope(node, namescopeVarDef);
79 Context.Scopes[node] = new Tuple<VariableDefinition, IList<string>>(namescopeVarDef, namesInNamescope);
82 public void Visit(RootNode node, INode parentNode)
84 var namescopeVarDef = CreateNamescope();
85 IList<string> namesInNamescope = new List<string>();
86 if (Context.Variables[node].VariableType.InheritsFromOrImplements(Context.Module.ImportReference((XamlTask.xamlAssemblyName, XamlTask.bindingNameSpace, "BindableObject"))))
87 SetNameScope(node, namescopeVarDef);
88 Context.Scopes[node] = new System.Tuple<VariableDefinition, IList<string>>(namescopeVarDef, namesInNamescope);
91 public void Visit(ListNode node, INode parentNode)
93 Context.Scopes[node] = Context.Scopes[parentNode];
96 static bool IsDataTemplate(INode node, INode parentNode)
98 var parentElement = parentNode as IElementNode;
100 if (parentElement != null && parentElement.Properties.TryGetValue(XmlName._CreateContent, out createContent) &&
101 createContent == node)
106 static bool IsStyle(INode node, INode parentNode)
108 var pnode = parentNode as ElementNode;
109 return pnode != null && pnode.XmlType.Name == "Style";
112 static bool IsVisualStateGroupList(ElementNode node)
114 return node != null && node.XmlType.Name == "VisualStateGroup" && node.Parent is IListNode;
117 static bool IsXNameProperty(ValueNode node, INode parentNode)
119 var parentElement = parentNode as IElementNode;
121 if (parentElement != null && parentElement.Properties.TryGetValue(XmlName.xName, out xNameNode) && xNameNode == node)
126 VariableDefinition CreateNamescope()
128 var module = Context.Module;
129 var vardef = new VariableDefinition(module.ImportReference((XamlTask.bindingAssemblyName, XamlTask.bindingInternalNameSpace, "NameScope")));
130 //Context.IL.Emit(OpCodes.Newobj, module.ImportCtorReference((XamlTask.bindingAssemblyName, XamlTask.bindingInternalNameSpace, "NameScope"), parameterTypes: null));
131 //Context.IL.Emit(OpCodes.Stloc, vardef);
135 void SetNameScope(ElementNode node, VariableDefinition ns)
137 var module = Context.Module;
138 //Context.IL.Emit(OpCodes.Ldloc, Context.Variables[node]);
139 //Context.IL.Emit(OpCodes.Ldloc, ns);
140 //Context.IL.Emit(OpCodes.Call, module.ImportMethodReference((XamlTask.bindingAssemblyName, XamlTask.bindingInternalNameSpace, "NameScope"),
141 // methodName: "SetNameScope",
142 // parameterTypes: new[] {
143 // (XamlTask.bindingAssemblyName, XamlTask.bindingNameSpace, "BindableObject"),
144 // (XamlTask.bindingAssemblyName, XamlTask.bindingInternalNameSpace, "INameScope"),
149 void RegisterName(string str, VariableDefinition namescopeVarDef, IList<string> namesInNamescope, VariableDefinition element, INode node)
151 if (namesInNamescope.Contains(str))
152 throw new XamlParseException($"An element with the name \"{str}\" already exists in this NameScope", node as IXmlLineInfo);
153 namesInNamescope.Add(str);
155 var module = Context.Module;
156 //Context.IL.Emit(OpCodes.Ldloc, namescopeVarDef);
157 //Context.IL.Emit(OpCodes.Ldstr, str);
158 //Context.IL.Emit(OpCodes.Ldloc, element);
159 //Context.IL.Emit(OpCodes.Callvirt, module.ImportMethodReference((XamlTask.bindingAssemblyName, XamlTask.bindingInternalNameSpace, "INameScope"),
160 // methodName: "RegisterName",
161 // parameterTypes: new[] {
162 // ("mscorlib", "System", "String"),
163 // ("mscorlib", "System", "Object"),
167 void SetStyleId(string str, VariableDefinition element)
169 if (!element.VariableType.InheritsFromOrImplements(Context.Module.ImportReference((XamlTask.bindingAssemblyName, XamlTask.bindingNameSpace, "Element"))))
172 var module = Context.Module;
174 var nop = Instruction.Create(OpCodes.Nop);
175 //Context.IL.Emit(OpCodes.Ldloc, element);
176 //Context.IL.Emit(OpCodes.Callvirt, module.ImportPropertyGetterReference((XamlTask.bindingAssemblyName, XamlTask.bindingNameSpace, "Element"), propertyName: "StyleId"));
177 //Context.IL.Emit(OpCodes.Brtrue, nop);
178 //Context.IL.Emit(OpCodes.Ldloc, element);
179 //Context.IL.Emit(OpCodes.Ldstr, str);
180 //Context.IL.Emit(OpCodes.Callvirt, module.ImportPropertySetterReference((XamlTask.bindingAssemblyName, XamlTask.bindingNameSpace, "Element"), propertyName: "StyleId"));
181 //Context.IL.Append(nop);