2 * Copyright(c) 2022 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;
19 using System.Reflection;
25 namespace Tizen.NUI.EXaml.Build.Tasks
27 internal class EXamlContext
29 public EXamlContext(TypeDefinition type, ModuleDefinition module, string embeddedResourceNameSpace, FieldDefinition parentContextValues = null)
31 Values = new Dictionary<INode, object>();
32 Variables = new Dictionary<IElementNode, VariableDefinition>();
33 Scopes = new Dictionary<INode, Tuple<VariableDefinition, IList<string>>>();
34 TypeExtensions = new Dictionary<INode, TypeReference>();
35 ParentContextValues = parentContextValues;
38 EmbeddedResourceNameSpace = embeddedResourceNameSpace;
41 public Dictionary<INode, object> Values { get; private set; }
43 public Dictionary<IElementNode, VariableDefinition> Variables { get; private set; }
45 public Dictionary<INode, Tuple<VariableDefinition, IList<string>>> Scopes { get; private set; }
47 public Dictionary<INode, TypeReference> TypeExtensions { get; }
49 public FieldDefinition ParentContextValues { get; private set; }
51 public object Root { get; set; } //FieldDefinition or VariableDefinition
53 public INode RootNode { get; set; }
55 public TypeDefinition Type { get; set; }
57 public ModuleDefinition Module { get; private set; }
59 public string EmbeddedResourceNameSpace { get; }
61 public List<EXamlOperation> eXamlOperations = new List<EXamlOperation>();
63 private string GetAssemblyName(AssemblyDefinition assembly)
65 string assemblyName = "";
66 if (assembly.FullName.StartsWith("Tizen.NUI.XamlBuild"))
68 assemblyName = "Tizen.NUI";
72 assemblyName = assembly.FullName;
74 if (assemblyName.EndsWith(".dll"))
76 assemblyName = assemblyName.Substring(0, assemblyName.Length - ".dll".Length);
78 else if (assemblyName.EndsWith(".exe"))
80 assemblyName = assemblyName.Substring(0, assemblyName.Length - ".exe".Length);
84 int firstIndex = assemblyName.IndexOf(',');
85 assemblyName = assemblyName.Substring(0, firstIndex);
88 if ("Tizen.NUI.Xaml" == assemblyName)
90 assemblyName = "Tizen.NUI";
94 return assemblyName + ", ";
97 private string GetAssemblyName(Assembly assembly)
99 string assemblyName = "";
100 if (assembly.FullName == typeof(EXamlOperation).Assembly.FullName)
102 assemblyName = "Tizen.NUI";
106 assemblyName = assembly.FullName;
108 if (assemblyName.Substring(assemblyName.Length - ".dll".Length) == ".dll")
110 assemblyName = assemblyName.Substring(0, assemblyName.Length - ".dll".Length);
112 else if (assemblyName.Substring(assemblyName.Length - ".exe".Length) == ".exe")
114 assemblyName = assemblyName.Substring(0, assemblyName.Length - ".exe".Length);
117 if ("Tizen.NUI.Xaml" == assemblyName)
119 assemblyName = "Tizen.NUI";
123 return assemblyName + ", ";
126 private List<string> definedAssemblies
129 } = new List<string>();
131 private List<TypeData> definedTypes
134 } = new List<TypeData>();
136 internal EXamlDefinitionList<PropertyDefinition> definedProperties
139 } = new EXamlDefinitionList<PropertyDefinition>();
141 internal EXamlDefinitionList<EventDefinition> definedEvents
144 } = new EXamlDefinitionList<EventDefinition>();
146 internal List<IMemberDefinition> definedBindableProperties
149 } = new List<IMemberDefinition>();
151 internal EXamlDefinitionList<MethodDefinition> definedMethods
154 } = new EXamlDefinitionList<MethodDefinition>();
156 #region Data of CreateObject
157 internal List<EXamlCreateObject> eXamlCreateObjects
160 } = new List<EXamlCreateObject>();
162 internal Dictionary<(TypeReference, MemberReference), EXamlCreateObject> StaticInstances
165 } = new Dictionary<(TypeReference, MemberReference), EXamlCreateObject>();
168 #region Data of AddObject
169 internal List<EXamlAddObject> eXamlAddObjectList
172 } = new List<EXamlAddObject>();
176 internal Dictionary<TypeDefinition, EXamlCreateObject> typeToInstance
179 } = new Dictionary<TypeDefinition, EXamlCreateObject>();
182 #region Data of AddEvent
183 internal List<EXamlAddEvent> eXamlAddEventList
186 } = new List<EXamlAddEvent>();
189 #region Data of Register XName
190 internal Dictionary<string, object> xNameToInstance
193 } = new Dictionary<string, object>();
195 internal object GetObjectByXName(string xName)
198 xNameToInstance.TryGetValue(xName, out ret);
203 #region Data of Add Resource to Dictionary
204 internal Dictionary<string, object> resourceDictionary
207 } = new Dictionary<string, object>();
210 #region Data of Get object by property
211 internal List<EXamlGetObjectByProperty> objectsAccordingToProperty = new List<EXamlGetObjectByProperty>();
213 private int GetIndex(EXamlGetObjectByProperty eXamlObjectFromProperty)
215 return objectsAccordingToProperty.IndexOf(eXamlObjectFromProperty);
219 public string GenerateEXamlString()
225 foreach (var examlOp in eXamlCreateObjects)
229 examlOp.Index = objectIndex++;
233 foreach (var examlOp in eXamlCreateObjects)
237 GatherType(examlOp.Type);
239 foreach (var property in examlOp.PropertyList)
241 GatherType(property.Item1);
243 definedProperties.Add(property.Item1, property.Item2);
245 if (true == property.Item1.Resolve()?.IsEnum)
247 GatherType(property.Item1.Resolve());
251 foreach (var eventDef in examlOp.EventList)
253 GatherType(eventDef.Item1);
255 definedEvents.Add(eventDef.Item1, eventDef.Item2);
258 foreach (var property in examlOp.BindableProperties)
260 if (!definedBindableProperties.Contains(property))
262 definedBindableProperties.Add(property);
265 var typeDef = property.DeclaringType;
266 if (-1 == GetTypeIndex(typeDef))
268 GatherType(property.DeclaringType);
272 foreach (var param in examlOp.paramsList)
274 if (null != param && param.GetType().IsEnum)
276 GatherType(param.GetType());
280 if (null != examlOp.XFactoryMethod)
282 GatherMethod((examlOp.XFactoryMethod.DeclaringType, examlOp.XFactoryMethod));
287 foreach (var op in eXamlAddObjectList)
289 if (op.Parent.IsValid && (!(op.Child is EXamlCreateObject eXamlCreateObject) || eXamlCreateObject.IsValid))
291 GatherMethod((op.Method.DeclaringType, op.Method));
295 foreach (var op in eXamlAddEventList)
297 if (op.Instance.IsValid)
299 GatherMethod((op.Value.DeclaringType, op.Value));
303 foreach (var ass in definedAssemblies)
305 ret += String.Format("({0} ({1}))\n",
306 GetValueString((int)EXamlOperationType.GatherAssembly),
307 GetValueString(ass));
310 foreach (var type in definedTypes)
312 ret += String.Format("({0} {1})\n",
313 GetValueString((int)EXamlOperationType.GatherType),
314 type.ConvertToString(definedAssemblies, definedTypes));
317 foreach (var property in definedProperties)
319 var typeDef = property.Item1;
320 int typeIndex = GetTypeIndex(typeDef);
321 ret += String.Format("({0} ({1} {2}))\n",
322 GetValueString((int)EXamlOperationType.GatherProperty),
323 GetValueString(typeIndex),
324 GetValueString(property.Item2.Name));
327 foreach (var eventDef in definedEvents)
329 var typeDef = eventDef.Item1;
330 int typeIndex = GetTypeIndex(typeDef);
331 ret += String.Format("({0} ({1} {2}))\n",
332 GetValueString((int)EXamlOperationType.GatherEvent),
333 GetValueString(typeIndex),
334 GetValueString(eventDef.Item2.Name));
337 foreach (var method in definedMethods)
339 var typeDef = method.Item1;
340 int typeIndex = GetTypeIndex(typeDef);
342 string strForParam = "(";
343 foreach (var param in method.Item2.Parameters)
345 int paramTypeIndex = GetTypeIndex(param.ParameterType);
347 if (-1 == paramTypeIndex)
349 throw new Exception($"Can't find index of param type {param.ParameterType.FullName}");
352 strForParam += GetValueString(paramTypeIndex) + " ";
356 ret += String.Format("({0} ({1} {2} {3}))\n",
357 GetValueString((int)EXamlOperationType.GatherMethod),
358 GetValueString(typeIndex),
359 GetValueString(method.Item2.Name),
363 foreach (var property in definedBindableProperties)
365 var typeDef = property.DeclaringType;
366 int typeIndex = GetTypeIndex(typeDef);
367 ret += String.Format("({0} ({1} {2}))\n",
368 GetValueString((int)EXamlOperationType.GatherBindableProperty),
369 GetValueString(typeIndex),
370 GetValueString(property.Name));
373 foreach (var op in eXamlOperations)
378 if (0 < longStrings.Length)
380 ret += String.Format("/{0}\n", longStrings);
386 private void GatherType(TypeReference typeRef)
388 if (-1 == GetTypeIndex(typeRef))
390 var assemblyName = GetAssemblyName(typeRef.Resolve().Module.Assembly);
391 if (!definedAssemblies.Contains(assemblyName))
393 definedAssemblies.Add(assemblyName);
396 var typeData = new TypeData(typeRef, GetAssemblyName(typeRef.Resolve().Module.Assembly));
398 if (typeRef is GenericInstanceType genericType)
400 foreach (var type in genericType.GenericArguments)
405 definedTypes.Add(typeData);
409 private void GatherType(Type type)
411 var assemblyName = GetAssemblyName(type.Assembly);
412 if (!definedAssemblies.Contains(assemblyName))
414 definedAssemblies.Add(assemblyName);
417 if (-1 == GetTypeIndex(type))
419 definedTypes.Add(new TypeData(type, GetAssemblyName(type.Assembly)));
423 private void GatherMethod((TypeReference, MethodDefinition) methodInfo)
425 GatherType(methodInfo.Item1);
427 foreach (var param in methodInfo.Item2.Parameters)
429 GatherType(param.ParameterType);
432 definedMethods.Add(methodInfo.Item1, methodInfo.Item2);
435 private int GetTypeIndex(TypeData typeData)
437 if (null != typeData.TypeReference)
439 return GetTypeIndex(typeData.TypeReference);
442 if (null != typeData.Type)
444 return GetTypeIndex(typeData.Type);
450 internal int GetTypeIndex(TypeReference typeReference)
452 for (int i = 0; i < definedTypes.Count; i++)
454 if (EXamlUtility.IsSameTypeReference(typeReference, definedTypes[i].TypeReference))
461 switch (typeReference.FullName)
478 case "System.UInt16":
481 case "System.UInt32":
484 case "System.UInt64":
487 case "System.Boolean":
490 case "System.String":
493 case "System.Object":
499 case "System.Decimal":
502 case "System.Single":
505 case "System.Double":
508 case "System.TimeSpan":
519 internal static int GetTypeIndex(TypeData type, List<TypeData> definedTypes)
521 for (int i = 0; i < definedTypes.Count; i++)
523 if (EXamlUtility.IsSameTypeReference(type.TypeReference, definedTypes[i].TypeReference))
530 switch (type.TypeReference.FullName)
547 case "System.UInt16":
550 case "System.UInt32":
553 case "System.UInt64":
556 case "System.Boolean":
559 case "System.String":
562 case "System.Object":
568 case "System.Decimal":
571 case "System.Single":
574 case "System.Double":
577 case "System.TimeSpan":
588 private int GetTypeIndex(Type type)
590 for (int i = 0; i < definedTypes.Count; i++)
592 if (type == definedTypes[i].Type)
601 internal (int, int) GetLongStringIndexs(string longString)
603 if (longStringToIndexPair.ContainsKey(longString))
605 return longStringToIndexPair[longString];
609 var indexPair = (longStrings.Length, 0);
610 longStrings += longString;
611 indexPair.Item2 = longStrings.Length - 1;
613 longStringToIndexPair.Add(longString, indexPair);
618 private string longStrings = "";
619 private Dictionary<string, (int, int)> longStringToIndexPair = new Dictionary<string, (int, int)>();
621 internal string GetValueString(object valueObject)
623 //Fang: How to deal the Enum
626 if (System.Type.Missing == valueObject)
630 else if (null == valueObject)
634 else if (valueObject is List<object> listObjects)
638 foreach (var obj in listObjects)
640 ret += GetValueString(obj);
649 var paramType = valueObject.GetType();
651 string signBegin = "a", signEnd = "a";
654 if (valueObject is EXamlCreateObject)
656 signBegin = signEnd = "a";
657 value = (valueObject as EXamlCreateObject).Index.ToString();
659 else if (valueObject is EXamlGetObjectByProperty)
661 return GetValueString(GetIndex(valueObject as EXamlGetObjectByProperty));
663 else if (paramType == typeof(string) || paramType == typeof(Uri))
665 signBegin = signEnd = "\"";
666 value = valueObject.ToString();
668 else if (paramType == typeof(char))
670 signBegin = signEnd = "\'";
671 value = valueObject.ToString();
673 else if (paramType == typeof(SByte))
675 signBegin = signEnd = "b";
676 value = valueObject.ToString();
678 else if (paramType == typeof(Int16))
680 signBegin = signEnd = "c";
681 value = valueObject.ToString();
683 else if (paramType == typeof(Int32))
685 signBegin = signEnd = "d";
686 value = valueObject.ToString();
688 else if (paramType == typeof(Int64))
690 signBegin = signEnd = "e";
691 value = valueObject.ToString();
693 else if (paramType == typeof(Byte))
695 signBegin = signEnd = "f";
696 value = valueObject.ToString();
698 else if (paramType == typeof(UInt16))
700 signBegin = signEnd = "g";
701 value = valueObject.ToString();
703 else if (paramType == typeof(UInt32))
705 signBegin = signEnd = "h";
706 value = valueObject.ToString();
708 else if (paramType == typeof(UInt64))
710 signBegin = signEnd = "i";
711 value = valueObject.ToString();
713 else if (paramType == typeof(Single))
715 signBegin = signEnd = "j";
716 value = valueObject.ToString();
718 else if (paramType == typeof(Double))
720 signBegin = signEnd = "k";
721 value = valueObject.ToString();
723 else if (paramType == typeof(TimeSpan))
725 signBegin = signEnd = "l";
726 value = valueObject.ToString();
728 else if (paramType == typeof(Boolean))
730 signBegin = signEnd = "m";
731 value = valueObject.ToString();
733 else if (paramType == typeof(decimal))
735 signBegin = signEnd = "n";
736 value = valueObject.ToString();
738 else if (paramType.IsEnum)
741 int typeIndex = GetTypeIndex(paramType);
742 value = String.Format("d{0}d \"{1}\"", typeIndex, valueObject.ToString());
745 else if (valueObject is EXamlValueConverterFromString)
749 value = (valueObject as EXamlValueConverterFromString).GetString();
752 ret += String.Format("{0}{1}{2} ", signBegin, value, signEnd);
759 internal class TypeData
761 internal TypeData(Type type, string assemblyName)
764 AssemblyName = assemblyName;
768 FullName = type.FullName.Replace('/', '+');
772 FullName = type.FullName;
776 internal TypeData(TypeReference typeReference, string assemblyName)
778 TypeReference = typeReference;
780 AssemblyName = assemblyName;
782 if (typeReference is GenericInstanceType genericType)
784 GenericArgumentTypes = new List<TypeData>();
785 foreach (var type in genericType.GenericArguments)
787 GenericArgumentTypes.Add(new TypeData(type, AssemblyName));
789 FullName = typeReference.Resolve().FullName;
793 FullName = typeReference.FullName;
796 if (typeReference.IsNested)
798 FullName = FullName.Replace('/', '+');
802 public string ConvertToString(List<string> definedAssemblies, List<TypeData> typeDatas)
805 int assemblyIndex = definedAssemblies.IndexOf(AssemblyName);
807 if (null == GenericArgumentTypes)
809 ret += String.Format("(d{0}d \"{1}\")", assemblyIndex, FullName);
813 string strForGenericTypes = "(";
815 foreach (var type in GenericArgumentTypes)
817 strForGenericTypes += "d" + EXamlContext.GetTypeIndex(type, typeDatas) + "d ";
820 strForGenericTypes += ")";
822 ret += String.Format("(d{0}d \"{1}\" {2})", assemblyIndex, FullName, strForGenericTypes);
828 internal TypeReference TypeReference
838 internal string AssemblyName
843 internal string FullName
848 internal List<TypeData> GenericArgumentTypes