[XamlBuild] Remove the reference of Tizen.NUI.XamlBuild in NUITizenGallery
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.XamlBuild / src / public / EXamlBuild / EXamlCreateObjectVisitor.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.Generic;
19 using System.Globalization;
20 using System.Linq;
21 using Mono.Cecil;
22 using Mono.Cecil.Cil;
23 using Tizen.NUI.Xaml;
24 using System.Xml;
25
26 using static Mono.Cecil.Cil.Instruction;
27 using static Mono.Cecil.Cil.OpCodes;
28 using Tizen.NUI.Xaml.Build.Tasks;
29 using ArrayExtension = Tizen.NUI.Xaml.Build.Tasks.ArrayExtension;
30
31 namespace Tizen.NUI.EXaml.Build.Tasks
32 {
33     class EXamlCreateObjectVisitor : IXamlNodeVisitor
34     {
35         public EXamlCreateObjectVisitor(EXamlContext context)
36         {
37             Context = context;
38             Module = context.Module;
39         }
40
41         public EXamlContext Context { get; }
42
43         ModuleDefinition Module { get; }
44
45         public TreeVisitingMode VisitingMode => TreeVisitingMode.BottomUp;
46         public bool StopOnDataTemplate => true;
47         public bool StopOnResourceDictionary => false;
48         public bool VisitNodeOnDataTemplate => false;
49         public bool SkipChildren(INode node, INode parentNode) => false;
50
51         public bool IsResourceDictionary(ElementNode node)
52         {
53             var parentVar = Context.Variables[(IElementNode)node];
54             return parentVar.VariableType.FullName == "Tizen.NUI.Binding.ResourceDictionary"
55                 || parentVar.VariableType.Resolve().BaseType?.FullName == "Tizen.NUI.Binding.ResourceDictionary";
56         }
57
58         public void Visit(ValueNode node, INode parentNode)
59         {
60             Context.Values[node] = node.Value;
61         }
62
63         public void Visit(MarkupNode node, INode parentNode)
64         {
65             //At this point, all MarkupNodes are expanded to ElementNodes
66         }
67
68         public void Visit(ElementNode node, INode parentNode)
69         {
70             var typeref = Module.ImportReference(node.XmlType.GetTypeReference(XmlTypeExtensions.ModeOfGetType.Both, Module, node));
71
72             if (IsXaml2009LanguagePrimitive(node))
73             {
74                 var vardef = new VariableDefinition(typeref);
75                 Context.Variables[node] = vardef;
76
77                 var value = GetValueFromLanguagePrimitive(typeref, node);
78
79                 Context.Values[node] = value;
80                 return;
81             }
82
83             TypeDefinition typedef = typeref.ResolveCached();
84
85             //if this is a MarkupExtension that can be compiled directly, compile and returns the value
86             var compiledMarkupExtensionName = typeref
87                 .GetCustomAttribute(Module, (XamlTask.xamlAssemblyName, XamlTask.xamlNameSpace, "ProvideCompiledAttribute"))
88                 ?.ConstructorArguments?[0].Value as string;
89             Type compiledMarkupExtensionType;
90             ICompiledMarkupExtension markupProvider;
91             if (compiledMarkupExtensionName != null &&
92                 (compiledMarkupExtensionType = Type.GetType(compiledMarkupExtensionName)) != null &&
93                 (markupProvider = Activator.CreateInstance(compiledMarkupExtensionType) as ICompiledMarkupExtension) != null)
94             {
95
96                 Context.Values[node] = markupProvider.ProvideValue(node, Module, Context);
97
98                 VariableDefinition vardef = new VariableDefinition(typeref);
99                 Context.Variables[node] = vardef;
100
101                 //clean the node as it has been fully exhausted
102                 foreach (var prop in node.Properties)
103                     if (!node.SkipProperties.Contains(prop.Key))
104                         node.SkipProperties.Add(prop.Key);
105                 node.CollectionItems.Clear();
106                 return;
107             }
108
109             MethodDefinition factoryCtorInfo = null;
110             MethodDefinition factoryMethodInfo = null;
111             MethodDefinition parameterizedCtorInfo = null;
112             MethodDefinition ctorInfo = null;
113
114             if (node.Properties.ContainsKey(XmlName.xArguments) && !node.Properties.ContainsKey(XmlName.xFactoryMethod))
115             {
116                 factoryCtorInfo = typedef.AllMethods().FirstOrDefault(md => md.IsConstructor &&
117                                                                             !md.IsStatic &&
118                                                                             md.HasParameters &&
119                                                                             md.MatchXArguments(node, typeref, Module, Context));
120                 if (factoryCtorInfo == null)
121                 {
122                     throw new XamlParseException(
123                         string.Format("No constructors found for {0} with matching x:Arguments", typedef.FullName), node);
124                 }
125                 ctorInfo = factoryCtorInfo;
126                 if (!typedef.IsValueType) //for ctor'ing typedefs, we first have to ldloca before the params
127                 {
128                     VariableDefinition vardef = new VariableDefinition(typeref);
129                     Context.Variables[node] = vardef;
130
131                     var argumentList = GetCtorXArguments(node, factoryCtorInfo.Parameters.Count, true);
132                     Context.Values[node] = new EXamlCreateObject(Context, null, typedef, argumentList.ToArray());
133                     return;
134                 }
135             }
136             else if (node.Properties.ContainsKey(XmlName.xFactoryMethod))
137             {
138                 var factoryMethod = (string)(node.Properties[XmlName.xFactoryMethod] as ValueNode).Value;
139                 factoryMethodInfo = typedef.AllMethods().FirstOrDefault(md => !md.IsConstructor &&
140                                                                               md.Name == factoryMethod &&
141                                                                               md.IsStatic &&
142                                                                               md.MatchXArguments(node, typeref, Module, Context));
143
144                 if (factoryMethodInfo == null)
145                 {
146                     var typeExtensionRef = Module.ImportReference(node.XmlType.GetTypeReference(XmlTypeExtensions.ModeOfGetType.OnlyGetTypeExtension, Module, node));
147                     typeExtensionRef = typeExtensionRef?.ResolveCached();
148
149                     if (null != typeExtensionRef)
150                     {
151                         factoryMethodInfo = typeExtensionRef.ResolveCached().AllMethods().FirstOrDefault(md => !md.IsConstructor &&
152                                                                               md.Name == factoryMethod &&
153                                                                               md.IsStatic &&
154                                                                               md.MatchXArguments(node, typeExtensionRef, Module, Context));
155                     }
156                 }
157
158                 if (factoryMethodInfo == null)
159                 {
160                     throw new XamlParseException(
161                         String.Format("No static method found for {0}::{1} ({2})", typedef.FullName, factoryMethod, null), node);
162                 }
163
164                 VariableDefinition vardef = new VariableDefinition(typeref);
165                 Context.Variables[node] = vardef;
166
167                 var argumentList = GetCtorXArguments(node, factoryMethodInfo.Parameters.Count, false);
168                 Context.Values[node] = new EXamlCreateObject(Context, null, typedef, factoryMethodInfo, argumentList?.ToArray());
169                 return;
170             }
171
172             if (ctorInfo == null && factoryMethodInfo == null)
173             {
174                 parameterizedCtorInfo = typedef.Methods.FirstOrDefault(md => md.IsConstructor &&
175                                                                              !md.IsStatic &&
176                                                                              md.HasParameters &&
177                                                                              md.Parameters.All(
178                                                                                  pd =>
179                                                                                      pd.CustomAttributes.Any(
180                                                                                          ca =>
181                                                                                              ca.AttributeType.FullName ==
182                                                                                              "Tizen.NUI.Binding.ParameterAttribute")));
183             }
184             string missingCtorParameter = null;
185             List<object> parameterizedCtorParams = null;
186
187             if (parameterizedCtorInfo != null && ValidateCtorArguments(parameterizedCtorInfo, node, out missingCtorParameter))
188             {
189                 ctorInfo = parameterizedCtorInfo;
190                 parameterizedCtorParams = GetCtorArguments(parameterizedCtorInfo, node, Context);
191                 //Fang
192                 //IL_0000:  ldstr "foo"
193                 //Context.IL.Append(PushCtorArguments(parameterizedCtorInfo, node));
194             }
195
196             ctorInfo = ctorInfo ?? typedef.Methods.FirstOrDefault(md => md.IsConstructor && !md.HasParameters && !md.IsStatic);
197
198             if (null == ctorInfo)
199             {
200                 foreach (var method in typedef.Methods)
201                 {
202                     if (method.IsConstructor && !method.IsStatic)
203                     {
204                         bool areAllParamsDefault = true;
205
206                         foreach (var param in method.Parameters)
207                         {
208                             if (!param.HasDefault)
209                             {
210                                 areAllParamsDefault = false;
211                                 break;
212                             }
213                         }
214
215                         if (areAllParamsDefault)
216                         {
217                             if (null == ctorInfo)
218                             {
219                                 ctorInfo = method;
220                             }
221                             else
222                             {
223                                 throw new XamlParseException($"{typedef.FullName} has more than one constructor which params are all default.", node);
224                             }
225                         }
226                     }
227                 }
228
229                 if (null == ctorInfo && !typedef.IsValueType)
230                 {
231                     throw new XamlParseException($"{typedef.FullName} has no constructor which params are all default.", node);
232                 }
233             }
234
235             if (parameterizedCtorInfo != null && ctorInfo == null)
236                 //there was a parameterized ctor, we didn't use it
237                 throw new XamlParseException($"The Property '{missingCtorParameter}' is required to create a '{typedef.FullName}' object.", node);
238             var ctorinforef = ctorInfo?.ResolveGenericParameters(typeref, Module);
239
240             var factorymethodinforef = factoryMethodInfo?.ResolveGenericParameters(typeref, Module);
241             var implicitOperatorref = typedef.Methods.FirstOrDefault(md =>
242                 md.IsPublic &&
243                 md.IsStatic &&
244                 md.IsSpecialName &&
245                 md.Name == "op_Implicit" && md.Parameters[0].ParameterType.FullName == "System.String");
246
247             if (ctorinforef != null || factorymethodinforef != null || typedef.IsValueType)
248             {
249                 VariableDefinition vardef = new VariableDefinition(typeref);
250                 Context.Variables[node] = vardef;
251
252                 ValueNode vnode = null;
253                 if (node.CollectionItems.Count == 1 && (vnode = node.CollectionItems.First() as ValueNode) != null &&
254                     vardef.VariableType.IsValueType)
255                 {
256                     Context.Values[node] = vnode.GetBaseValue(Context, typeref);
257                 }
258                 else if (node.CollectionItems.Count == 1 && (vnode = node.CollectionItems.First() as ValueNode) != null &&
259                            implicitOperatorref != null)
260                 {
261                     var converterType = vnode.GetConverterType(new ICustomAttributeProvider[] { typeref.ResolveCached() });
262                     if (null == converterType)
263                     {
264                         var realValue = vnode.GetBaseValue(Context, typeref);
265                         Context.Values[node] = new EXamlCreateObject(Context, realValue, typeref);
266                     }
267                     else
268                     {
269                         var converterValue = new EXamlValueConverterFromString(Context, converterType.Resolve(), vnode.Value as string);
270                         Context.Values[node] = new EXamlCreateObject(Context, converterValue, typeref);
271                     }
272                 }
273                 else if (factorymethodinforef != null)
274                 {
275                     //Fang
276                     //Context.IL.Emit(OpCodes.Call, Module.ImportReference(factorymethodinforef));
277                     //Context.IL.Emit(OpCodes.Stloc, vardef);
278                 }
279                 else if (!typedef.IsValueType)
280                 {
281                     var ctor = Module.ImportReference(ctorinforef);
282                     //IL_0001:  newobj instance void class [Tizen.NUI.Xaml.UIComponents]Tizen.NUI.Xaml.UIComponents.Button::'.ctor'()
283                     //IL_0006:  stloc.0
284                     //Context.IL.Emit(OpCodes.Newobj, ctor);
285                     //Context.IL.Emit(OpCodes.Stloc, vardef);
286                     if (typeref.FullName == "Tizen.NUI.Xaml.ArrayExtension")
287                     {
288                         typeref = Module.ImportReference(typeof(ArrayExtension));
289                     }
290
291                     var accordingType = this.GetType().Assembly.GetType(typeref.FullName);
292
293                     if (null != accordingType && accordingType != typeof(Binding.Setter))
294                     {
295                         Context.Values[node] = new EXamlCreateObject(Context, Activator.CreateInstance(accordingType), typeref);
296                     }
297                     else if (null != parameterizedCtorParams)
298                     {
299                         Context.Values[node] = new EXamlCreateObject(Context, null, typeref, parameterizedCtorParams.ToArray());
300                     }
301                     else
302                     {
303                         bool canConvertCollectionItem = false;
304
305                         if (!typeref.InheritsFromOrImplements(Context.Module.ImportReference(typeof(List<string>)).Resolve())
306                             &&
307                             node.CollectionItems.Count == 1 && (vnode = node.CollectionItems.First() as ValueNode) != null)
308                         {
309                             var valueNode = node.CollectionItems.First() as ValueNode;
310
311                             if (valueNode.CanConvertValue(Context.Module, typeref, (TypeReference)null))
312                             {
313                                 var converterType = valueNode.GetConverterType(new ICustomAttributeProvider[] { typeref.Resolve() });
314                                 if (null != converterType)
315                                 {
316                                     var converterValue = new EXamlValueConverterFromString(Context, converterType.Resolve(), valueNode.Value as string);
317                                     Context.Values[node] = new EXamlCreateObject(Context, converterValue, typeref);
318                                 }
319                                 else
320                                 {
321                                     var valueItem = valueNode.GetBaseValue(Context, typeref);
322                                     if (null == valueItem)
323                                     {
324                                         throw new XamlParseException($"Can't convert collection item \"{vnode.Value}\" to object", node);
325                                     }
326
327                                     Context.Values[node] = valueItem;
328                                 }
329
330                                 canConvertCollectionItem = true;
331                             }
332                         }
333
334                         if (false == canConvertCollectionItem)
335                         {
336                             if (!ctorInfo.HasParameters)
337                             {
338                                 Context.Values[node] = new EXamlCreateObject(Context, null, typeref);
339                             }
340                             else
341                             {
342                                 object[] @params = new object[ctorInfo.Parameters.Count];
343
344                                 for (int i = 0; i < ctorInfo.Parameters.Count; i++)
345                                 {
346                                     var param = ctorInfo.Parameters[i];
347
348                                     if (ctorInfo.Parameters[i].ParameterType.ResolveCached().IsEnum)
349                                     {
350                                         @params[i] = NodeILExtensions.GetParsedEnum(Context, param.ParameterType, param.Constant.ToString());
351                                     }
352                                     else
353                                     {
354                                         @params[i] = param.Constant;
355                                     }
356                                 }
357
358                                 Context.Values[node] = new EXamlCreateObject(Context, null, typeref, @params);
359                             }
360                         }
361                     }
362                 }
363                 else if (ctorInfo != null && node.Properties.ContainsKey(XmlName.xArguments) &&
364                          !node.Properties.ContainsKey(XmlName.xFactoryMethod) && ctorInfo.MatchXArguments(node, typeref, Module, Context))
365                 {
366                     //IL_0008:  ldloca.s 1
367                     //IL_000a:  ldc.i4.1 
368                     //IL_000b:  call instance void valuetype Test/Foo::'.ctor'(bool)
369
370                     //Fang
371                     //var ctor = Module.ImportReference(ctorinforef);
372                     //Context.IL.Emit(OpCodes.Ldloca, vardef);
373                     //Context.IL.Append(PushCtorXArguments(factoryCtorInfo, node));
374                     //Context.IL.Emit(OpCodes.Call, ctor);
375                 }
376                 else
377                 {
378                     //IL_0000:  ldloca.s 0
379                     //IL_0002:  initobj Test/Foo
380                     //Fang
381                     //Context.IL.Emit(OpCodes.Ldloca, vardef);
382                     //Context.IL.Emit(OpCodes.Initobj, Module.ImportReference(typedef));
383                 }
384
385                 if (typeref.FullName == "Tizen.NUI.Xaml.ArrayExtension")
386                 {
387                     //Fang
388                     //var visitor = new SetPropertiesVisitor(Context);
389                     //foreach (var cnode in node.Properties.Values.ToList())
390                     //    cnode.Accept(visitor, node);
391                     //foreach (var cnode in node.CollectionItems)
392                     //    cnode.Accept(visitor, node);
393
394                     //markupProvider = new ArrayExtension();
395
396                     //var il = markupProvider.ProvideValue(node, Module, Context, out typeref);
397
398                     //vardef = new VariableDefinition(typeref);
399                     //Context.Variables[node] = vardef;
400                     //Context.Body.Variables.Add(vardef);
401
402                     //Context.IL.Append(il);
403                     //Context.IL.Emit(OpCodes.Stloc, vardef);
404
405                     ////clean the node as it has been fully exhausted
406                     //foreach (var prop in node.Properties)
407                     //    if (!node.SkipProperties.Contains(prop.Key))
408                     //        node.SkipProperties.Add(prop.Key);
409                     //node.CollectionItems.Clear();
410
411                     return;
412                 }
413             }
414         }
415
416         public void Visit(RootNode node, INode parentNode)
417         {
418             //IL_0013:  ldarg.0 
419             //IL_0014:  stloc.3 
420
421             var ilnode = (ILRootNode)node;
422             var typeref = ilnode.TypeReference;
423             var vardef = new VariableDefinition(typeref);
424             Context.Variables[node] = vardef;
425             Context.Root = vardef;
426             Context.RootNode = node;
427             //Context.IL.Emit(OpCodes.Ldarg_0);
428             //Context.IL.Emit(OpCodes.Stloc, vardef);
429         }
430
431         public void Visit(ListNode node, INode parentNode)
432         {
433             XmlName name;
434             if (EXamlSetPropertiesVisitor.TryGetPropertyName(node, parentNode, out name))
435                 node.XmlName = name;
436         }
437
438         bool ValidateCtorArguments(MethodDefinition ctorinfo, ElementNode enode, out string firstMissingProperty)
439         {
440             firstMissingProperty = null;
441             foreach (var parameter in ctorinfo.Parameters)
442             {
443                 var propname =
444                     parameter.CustomAttributes.First(ca => ca.AttributeType.FullName == "Tizen.NUI.Binding.ParameterAttribute")
445                         .ConstructorArguments.First()
446                         .Value as string;
447                 if (!enode.Properties.ContainsKey(new XmlName("", propname)))
448                 {
449                     firstMissingProperty = propname;
450                     return false;
451                 }
452             }
453             return true;
454         }
455
456         List<object> GetCtorXArguments(ElementNode enode, int paramsCount, bool isConstructor)
457         {
458             if (!enode.Properties.ContainsKey(XmlName.xArguments))
459             {
460                 return null;
461             }
462
463             List<object> argumentList = new List<object>();
464
465             var arguments = new List<INode>();
466             var node = enode.Properties[XmlName.xArguments] as ElementNode;
467             if (node != null)
468             {
469                 node.Accept(new EXamlSetPropertiesVisitor(Context, true), null);
470                 arguments.Add(node);
471             }
472
473             var list = enode.Properties[XmlName.xArguments] as ListNode;
474             if (list != null)
475             {
476                 foreach (var n in list.CollectionItems)
477                     arguments.Add(n);
478             }
479
480             for (int i = 0; i < arguments.Count; i++)
481             {
482                 argumentList.Add(Context.Values[arguments[i]]);
483             }
484
485             if (!isConstructor)
486             {
487                 for (int i = arguments.Count; i < paramsCount; i++)
488                 {
489                     argumentList.Add(Type.Missing);
490                 }
491             }
492
493             return argumentList;
494         }
495
496         static bool IsXaml2009LanguagePrimitive(IElementNode node)
497         {
498             if (node.NamespaceURI == XamlParser.X2009Uri)
499             {
500                 var n = node.XmlType.Name.Split(':')[1];
501                 return n != "Array";
502             }
503             if (node.NamespaceURI != "clr-namespace:System;assembly=mscorlib")
504                 return false;
505             var name = node.XmlType.Name.Split(':')[1];
506             if (name == "SByte" ||
507                 name == "Int16" ||
508                 name == "Int32" ||
509                 name == "Int64" ||
510                 name == "Byte" ||
511                 name == "UInt16" ||
512                 name == "UInt32" ||
513                 name == "UInt64" ||
514                 name == "Single" ||
515                 name == "Double" ||
516                 name == "Boolean" ||
517                 name == "String" ||
518                 name == "Char" ||
519                 name == "Decimal" ||
520                 name == "TimeSpan" ||
521                 name == "Uri")
522                 return true;
523             return false;
524         }
525
526         object GetValueFromLanguagePrimitive(TypeReference typeRef, ElementNode node)
527         {
528             var module = Context.Module;
529             var hasValue = node.CollectionItems.Count == 1 && node.CollectionItems[0] is ValueNode &&
530                            ((ValueNode)node.CollectionItems[0]).Value is string;
531             var valueString = hasValue ? ((ValueNode)node.CollectionItems[0]).Value as string : string.Empty;
532             object ret = null;
533
534             TypeDefinition typedef = typeRef.ResolveCached();
535
536             switch (typedef.FullName)
537             {
538                 case "System.SByte":
539                     if (hasValue && sbyte.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out sbyte outsbyte))
540                         ret = outsbyte;
541                     else
542                         ret = 0;
543                     break;
544                 case "System.Int16":
545                     if (hasValue && short.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out short outshort))
546                         ret = outshort;
547                     else
548                         ret = 0;
549                     break;
550                 case "System.Int32":
551                     if (hasValue && int.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out int outint))
552                         ret = outint;
553                     else
554                         ret = 0;
555                     break;
556                 case "System.Int64":
557                     if (hasValue && long.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out long outlong))
558                         ret = outlong;
559                     else
560                         ret = 0;
561                     break;
562                 case "System.Byte":
563                     if (hasValue && byte.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out byte outbyte))
564                         ret = outbyte;
565                     else
566                         ret = 0;
567                     break;
568                 case "System.UInt16":
569                     if (hasValue && short.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out short outushort))
570                         ret = outushort;
571                     else
572                         ret = 0;
573                     break;
574                 case "System.UInt32":
575                     if (hasValue && uint.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out uint outuint))
576                         ret = outuint;
577                     else
578                         ret = 0;
579                     break;
580                 case "System.UInt64":
581                     if (hasValue && long.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out long outulong))
582                         ret = outulong;
583                     else
584                         ret = 0;
585                     break;
586                 case "System.Boolean":
587                     if (hasValue && bool.TryParse(valueString, out bool outbool))
588                         ret = outbool;
589                     else
590                         ret = false;
591                     break;
592                 case "System.String":
593                     ret = valueString;
594                     break;
595                 case "System.Object":
596                     var ctorinfo =
597                         module.TypeSystem.Object.ResolveCached()
598                             .Methods.FirstOrDefault(md => md.IsConstructor && !md.HasParameters);
599                     var ctor = module.ImportReference(ctorinfo);
600                     ret = Create(Newobj, ctor);
601                     break;
602                 case "System.Char":
603                     if (hasValue && char.TryParse(valueString, out char outchar))
604                         ret = outchar;
605                     else
606                         ret = (char)0;
607                     break;
608                 case "System.Decimal":
609                     decimal outdecimal;
610                     if (hasValue && decimal.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out outdecimal))
611                     {
612                         ret = outdecimal;
613                     }
614                     else
615                     {
616                         ret = (decimal)0;
617                     }
618                     break;
619                 case "System.Single":
620                     if (hasValue && float.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out float outfloat))
621                         ret = outfloat;
622                     else
623                         ret = 0f;
624                     break;
625                 case "System.Double":
626                     if (hasValue && double.TryParse(valueString, NumberStyles.Number, CultureInfo.InvariantCulture, out double outdouble))
627                         ret = outdouble;
628                     else
629                         ret = 0d;
630                     break;
631                 case "System.TimeSpan":
632                     if (hasValue && TimeSpan.TryParse(valueString, CultureInfo.InvariantCulture, out TimeSpan outspan))
633                     {
634                         ret = outspan;
635                     }
636                     else
637                     {
638                         ret = null;
639                     }
640                     break;
641                 case "System.Uri":
642                     if (hasValue && Uri.TryCreate(valueString, UriKind.RelativeOrAbsolute, out Uri outuri))
643                     {
644                         ret = outuri;
645                     }
646                     else
647                     {
648                         ret = null;
649                     };
650                     break;
651                 default:
652                     ret = new EXamlCreateObject(Context, null, typeRef);
653                     break;
654             }
655
656             return ret;
657         }
658
659         List<object> GetCtorArguments(MethodDefinition ctorinfo, ElementNode enode, EXamlContext context)
660         {
661             List<object> ret = null;
662
663             foreach (var parameter in ctorinfo.Parameters)
664             {
665                 var propname =
666                     parameter.CustomAttributes.First(ca => ca.AttributeType.FullName == "Tizen.NUI.Binding.ParameterAttribute")
667                         .ConstructorArguments.First()
668                         .Value as string;
669                 var node = enode.Properties[new XmlName("", propname)];
670                 if (!enode.SkipProperties.Contains(new XmlName("", propname)))
671                     enode.SkipProperties.Add(new XmlName("", propname));
672
673                 if (node is ValueNode valueNode)
674                 {
675                     var valueType = parameter.ParameterType;
676
677                     if ("System.Type" == valueType.FullName)
678                     {
679                         var typeRef = XmlTypeExtensions.GetTypeReference(valueNode.Value as string, Module, node as BaseNode, XmlTypeExtensions.ModeOfGetType.Both);
680                         context.Values[node] = new EXamlCreateObject(context, typeRef);
681                     }
682                     else
683                     {
684                         var converterType = valueNode.GetConverterType(new ICustomAttributeProvider[] { parameter, parameter.ParameterType.ResolveCached() });
685
686                         if (null != converterType)
687                         {
688                             var converterValue = new EXamlValueConverterFromString(context, converterType.Resolve(), valueNode.Value as string);
689                             context.Values[node] = new EXamlCreateObject(context, converterValue, valueType);
690                         }
691                         else
692                         {
693                             context.Values[node] = valueNode.GetBaseValue(context, valueType);
694                         }
695                     }
696
697                     if (null == ret)
698                     {
699                         ret = new List<object>();
700                     }
701
702                     ret.Add(context.Values[node]);
703                 }
704             }
705
706             return ret;
707         }
708     }
709 }
710