diff options
author | Stephane Delcroix <stephane@delcroix.org> | 2017-01-18 13:04:13 +0100 |
---|---|---|
committer | Kangho Hur <kangho.hur@samsung.com> | 2017-03-24 13:12:23 +0900 |
commit | a003d578219a9c8832bdc6589dda4051ddfa9c3b (patch) | |
tree | f8e561568c8d8d2b567fc9b607a7c1602abffa32 | |
parent | 69561c121c55645fb05ace1f67b7636a5f2a2ec2 (diff) | |
download | xamarin-forms-a003d578219a9c8832bdc6589dda4051ddfa9c3b.tar.gz xamarin-forms-a003d578219a9c8832bdc6589dda4051ddfa9c3b.tar.bz2 xamarin-forms-a003d578219a9c8832bdc6589dda4051ddfa9c3b.zip |
[XamlC] compile ListStringTypeConverter (#660)
* [XamlC] compile ListStringTypeConverter
* remove debug statements
5 files changed, 53 insertions, 2 deletions
diff --git a/Xamarin.Forms.Build.Tasks/CompiledConverters/ListStringTypeConverter.cs b/Xamarin.Forms.Build.Tasks/CompiledConverters/ListStringTypeConverter.cs new file mode 100644 index 00000000..62d7d69d --- /dev/null +++ b/Xamarin.Forms.Build.Tasks/CompiledConverters/ListStringTypeConverter.cs @@ -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 diff --git a/Xamarin.Forms.Build.Tasks/Xamarin.Forms.Build.Tasks.csproj b/Xamarin.Forms.Build.Tasks/Xamarin.Forms.Build.Tasks.csproj index 6424c930..3a2929ea 100644 --- a/Xamarin.Forms.Build.Tasks/Xamarin.Forms.Build.Tasks.csproj +++ b/Xamarin.Forms.Build.Tasks/Xamarin.Forms.Build.Tasks.csproj @@ -109,6 +109,7 @@ <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"> diff --git a/Xamarin.Forms.Core/ListStringTypeConverter.cs b/Xamarin.Forms.Core/ListStringTypeConverter.cs index 647f0143..69aa53fc 100644 --- a/Xamarin.Forms.Core/ListStringTypeConverter.cs +++ b/Xamarin.Forms.Core/ListStringTypeConverter.cs @@ -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) diff --git a/Xamarin.Forms.Xaml.UnitTests/CompiledTypeConverter.xaml b/Xamarin.Forms.Xaml.UnitTests/CompiledTypeConverter.xaml index 296f9eeb..7118c5d8 100644 --- a/Xamarin.Forms.Xaml.UnitTests/CompiledTypeConverter.xaml +++ b/Xamarin.Forms.Xaml.UnitTests/CompiledTypeConverter.xaml @@ -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"/> diff --git a/Xamarin.Forms.Xaml.UnitTests/CompiledTypeConverter.xaml.cs b/Xamarin.Forms.Xaml.UnitTests/CompiledTypeConverter.xaml.cs index 1ef319a3..f74b5a73 100644 --- a/Xamarin.Forms.Xaml.UnitTests/CompiledTypeConverter.xaml.cs +++ b/Xamarin.Forms.Xaml.UnitTests/CompiledTypeConverter.xaml.cs @@ -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]); } } } |