[XamlC] compile ListStringTypeConverter (#660)
authorStephane Delcroix <stephane@delcroix.org>
Wed, 18 Jan 2017 12:04:13 +0000 (13:04 +0100)
committerKangho Hur <kangho.hur@samsung.com>
Fri, 24 Mar 2017 04:12:23 +0000 (13:12 +0900)
* [XamlC] compile ListStringTypeConverter

* remove debug statements

Xamarin.Forms.Build.Tasks/CompiledConverters/ListStringTypeConverter.cs [new file with mode: 0644]
Xamarin.Forms.Build.Tasks/Xamarin.Forms.Build.Tasks.csproj
Xamarin.Forms.Core/ListStringTypeConverter.cs
Xamarin.Forms.Xaml.UnitTests/CompiledTypeConverter.xaml
Xamarin.Forms.Xaml.UnitTests/CompiledTypeConverter.xaml.cs

diff --git a/Xamarin.Forms.Build.Tasks/CompiledConverters/ListStringTypeConverter.cs b/Xamarin.Forms.Build.Tasks/CompiledConverters/ListStringTypeConverter.cs
new file mode 100644 (file)
index 0000000..62d7d69
--- /dev/null
@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+using Mono.Cecil;
+using Mono.Cecil.Cil;
+
+using Xamarin.Forms.Xaml;
+using Xamarin.Forms.Build.Tasks;
+
+namespace Xamarin.Forms.Core.XamlC
+{
+       class ListStringTypeConverter : ICompiledTypeConverter
+       {
+               public IEnumerable<Instruction> ConvertFromString(string value, ModuleDefinition module, BaseNode node)
+               {
+                       if (value == null) {
+                               yield return Instruction.Create(OpCodes.Ldnull);
+                               yield break;
+                       }
+                       var parts = value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()).ToList();
+
+                       var listCtor = module.Import(typeof(List<>)).Resolve().Methods.FirstOrDefault(md => md.IsConstructor && md.Parameters.Count == 1 && md.Parameters[0].ParameterType.FullName == "System.Int32");
+                       var listCtorRef = module.Import(listCtor);
+                       listCtorRef = module.Import(listCtorRef.ResolveGenericParameters(module.Import(typeof(List<string>)), module));
+
+                       var adder = module.Import(typeof(ICollection<>)).Resolve().Methods.FirstOrDefault(md => md.Name == "Add" && md.Parameters.Count == 1);
+                       var adderRef = module.Import(adder);
+                       adderRef = module.Import(adderRef.ResolveGenericParameters(module.Import(typeof(ICollection<string>)), module));
+
+                       yield return Instruction.Create(OpCodes.Ldc_I4, parts.Count);
+                       yield return Instruction.Create(OpCodes.Newobj, listCtorRef);
+
+                       foreach (var part in parts) {
+                               yield return Instruction.Create(OpCodes.Dup);
+                               yield return Instruction.Create(OpCodes.Ldstr, part);
+                               yield return Instruction.Create(OpCodes.Callvirt, adderRef);
+                       }
+               }
+       }
+}
\ No newline at end of file
index 6424c93..3a2929e 100644 (file)
     <Compile Include="CompiledValueProviders\ICompiledValueProvider.cs" />
     <Compile Include="CompiledValueProviders\TriggerValueProvider.cs" />
     <Compile Include="CompiledValueProviders\PassthroughValueProvider.cs" />
+    <Compile Include="CompiledConverters\ListStringTypeConverter.cs" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <Target Name="AfterBuild">
index 647f014..69aa53f 100644 (file)
@@ -3,6 +3,7 @@ using System.Linq;
 
 namespace Xamarin.Forms
 {
+       [Xaml.ProvideCompiled("Xamarin.Forms.Core.XamlC.ListStringTypeConverter")]
        public class ListStringTypeConverter : TypeConverter
        {
                public override object ConvertFromInvariantString(string value)
index 296f9ee..7118c5d 100644 (file)
@@ -4,7 +4,8 @@
                         x:Class="Xamarin.Forms.Xaml.UnitTests.CompiledTypeConverter"
                         RectangleP="0,1,2,4"
                         RectangleBP="4,8,16,32"
-                        BackgroundColor="Pink">
+                        BackgroundColor="Pink"
+                        List="Foo, Bar">
        <Label x:Name="label"
                HorizontalOptions="EndAndExpand"
                RelativeLayout.XConstraint="2" Margin="2,3"/>
index 1ef319a..f74b5a7 100644 (file)
@@ -1,4 +1,5 @@
-using NUnit.Framework;
+using System.Collections.Generic;
+using NUnit.Framework;
 
 namespace Xamarin.Forms.Xaml.UnitTests
 {
@@ -14,6 +15,10 @@ namespace Xamarin.Forms.Xaml.UnitTests
 
                public Rectangle RectangleP { get; set; }
 
+               [TypeConverter(typeof(ListStringTypeConverter))]
+               public IList<string> List { get; set; }
+
+
                public CompiledTypeConverter ()
                {
                        InitializeComponent ();
@@ -39,6 +44,8 @@ namespace Xamarin.Forms.Xaml.UnitTests
                                var xConstraint = RelativeLayout.GetXConstraint(p.label);
                                Assert.AreEqual(2, xConstraint.Compute(null));
                                Assert.AreEqual(new Thickness(2, 3), p.label.Margin);
+                               Assert.AreEqual(2, p.List.Count);
+                               Assert.AreEqual("Bar", p.List[1]);
                        }
                }
        }