diff options
author | Stephane Delcroix <stephane@delcroix.org> | 2016-12-07 11:35:32 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-12-07 11:35:32 +0100 |
commit | 7851541ab67c1e3c1d38b3210a1153d08ce78ab2 (patch) | |
tree | 55efc79b32a427f5a4cc1674a3566ef2e2a507c3 | |
parent | 8181e6d4cbe8aac6eb29c5140262d8bc51dba7b7 (diff) | |
download | xamarin-forms-7851541ab67c1e3c1d38b3210a1153d08ce78ab2.tar.gz xamarin-forms-7851541ab67c1e3c1d38b3210a1153d08ce78ab2.tar.bz2 xamarin-forms-7851541ab67c1e3c1d38b3210a1153d08ce78ab2.zip |
[Xaml[C]] support op_implicit declared on Target (#585)
-rw-r--r-- | Xamarin.Forms.Build.Tasks/NodeILExtensions.cs | 8 | ||||
-rw-r--r-- | Xamarin.Forms.Xaml.UnitTests/SetValue.xaml | 4 | ||||
-rw-r--r-- | Xamarin.Forms.Xaml.UnitTests/SetValue.xaml.cs | 28 | ||||
-rw-r--r-- | Xamarin.Forms.Xaml/TypeConversionExtensions.cs | 33 |
4 files changed, 51 insertions, 22 deletions
diff --git a/Xamarin.Forms.Build.Tasks/NodeILExtensions.cs b/Xamarin.Forms.Build.Tasks/NodeILExtensions.cs index 86ef2688..0c9b9e6b 100644 --- a/Xamarin.Forms.Build.Tasks/NodeILExtensions.cs +++ b/Xamarin.Forms.Build.Tasks/NodeILExtensions.cs @@ -109,6 +109,9 @@ namespace Xamarin.Forms.Build.Tasks nullableCtor = originalTypeRef.GetMethods(md => md.IsConstructor && md.Parameters.Count == 1, module).Single().Item1; nullableCtor = nullableCtor.ResolveGenericParameters(nullableTypeRef, module); } + + var implicitOperator = module.TypeSystem.String.GetImplicitOperatorTo(targetTypeRef, module); + //Obvious Built-in conversions if (targetTypeRef.Resolve().BaseType != null && targetTypeRef.Resolve().BaseType.FullName == "System.Enum") yield return PushParsedEnum(targetTypeRef, str, node); @@ -203,10 +206,13 @@ namespace Xamarin.Forms.Build.Tasks context.Body.Method.Module.Import(typeof(decimal)) .Resolve() .Methods.FirstOrDefault( - md => md.IsConstructor && md.Parameters.Count == 1 && md.Parameters [0].ParameterType.FullName == "System.Int32"); + md => md.IsConstructor && md.Parameters.Count == 1 && md.Parameters[0].ParameterType.FullName == "System.Int32"); var decimalctor = context.Body.Method.Module.Import(decimalctorinfo); yield return Instruction.Create(OpCodes.Newobj, decimalctor); } + } else if (implicitOperator != null) { + yield return Instruction.Create(OpCodes.Ldstr, node.Value as string); + yield return Instruction.Create(OpCodes.Call, module.Import(implicitOperator)); } else yield return Instruction.Create(OpCodes.Ldnull); diff --git a/Xamarin.Forms.Xaml.UnitTests/SetValue.xaml b/Xamarin.Forms.Xaml.UnitTests/SetValue.xaml index 5ebc4f4f..cf5fe1dd 100644 --- a/Xamarin.Forms.Xaml.UnitTests/SetValue.xaml +++ b/Xamarin.Forms.Xaml.UnitTests/SetValue.xaml @@ -90,12 +90,12 @@ <local:SV_Foo Value="Bar"/> </local:MockViewWithValues.BPBar> </local:MockViewWithValues> - <!--<local:MockViewWithValues x:Name="implicit1" BPFoo="Foo" />--> + <local:MockViewWithValues x:Name="implicit1" BPFoo="Foo" /> <local:MockViewWithValues x:Name="implicit2"> <local:MockViewWithValues.Bar> <local:SV_Foo Value="Bar"/> </local:MockViewWithValues.Bar> </local:MockViewWithValues> - <!--<local:MockViewWithValues x:Name="implicit3" Foo="Foo" />--> + <local:MockViewWithValues x:Name="implicit3" Foo="Foo" /> </StackLayout> </ContentPage> diff --git a/Xamarin.Forms.Xaml.UnitTests/SetValue.xaml.cs b/Xamarin.Forms.Xaml.UnitTests/SetValue.xaml.cs index d8c7d2ce..6e3cdc1a 100644 --- a/Xamarin.Forms.Xaml.UnitTests/SetValue.xaml.cs +++ b/Xamarin.Forms.Xaml.UnitTests/SetValue.xaml.cs @@ -311,13 +311,13 @@ namespace Xamarin.Forms.Xaml.UnitTests Assert.AreEqual("Bar", page.implicit0.GetValue(MockViewWithValues.BPBarProperty)); } - //[TestCase(false)] - //[TestCase(true)] - //public void SetValueWithImplicitOperatorOnTarget(bool useCompiledXaml) - //{ - // var page = new SetValue(useCompiledXaml); - // Assert.AreEqual("Foo", ((SV_Foo)page.implicit1.GetValue(MockViewWithValues.BPFooProperty)).Value); - //} + [TestCase(false)] + [TestCase(true)] + public void SetValueWithImplicitOperatorOnTarget(bool useCompiledXaml) + { + var page = new SetValue(useCompiledXaml); + Assert.AreEqual("Foo", ((SV_Foo)page.implicit1.GetValue(MockViewWithValues.BPFooProperty)).Value); + } [TestCase(false)] [TestCase(true)] @@ -327,13 +327,13 @@ namespace Xamarin.Forms.Xaml.UnitTests Assert.AreEqual("Bar", page.implicit2.Bar); } - //[TestCase(false)] - //[TestCase(true)] - //public void SetWithImplicitOperatorOnTarget(bool useCompiledXaml) - //{ - // var page = new SetValue(useCompiledXaml); - // Assert.AreEqual("Foo", page.implicit3.Foo.Value); - //} + [TestCase(false)] + [TestCase(true)] + public void SetWithImplicitOperatorOnTarget(bool useCompiledXaml) + { + var page = new SetValue(useCompiledXaml); + Assert.AreEqual("Foo", page.implicit3.Foo.Value); + } } } } diff --git a/Xamarin.Forms.Xaml/TypeConversionExtensions.cs b/Xamarin.Forms.Xaml/TypeConversionExtensions.cs index a29b3af2..15a66f5d 100644 --- a/Xamarin.Forms.Xaml/TypeConversionExtensions.cs +++ b/Xamarin.Forms.Xaml/TypeConversionExtensions.cs @@ -170,11 +170,34 @@ namespace Xamarin.Forms.Xaml } //if there's an implicit conversion, convert - if (value != null) - { - var cast = value.GetType().GetRuntimeMethod("op_Implicit", new[] { value.GetType() }); - if (cast != null && cast.ReturnType == toType) { - value = cast.Invoke(null, new [] { value }); + if (value != null) { + MethodInfo opImplicit = null; + foreach (var mi in value.GetType().GetRuntimeMethods()) { + if (!mi.IsSpecialName) continue; + if (mi.Name != "op_Implicit") continue; + if (!mi.IsPublic) continue; + if (mi.ReturnType != toType) continue; + var parameters = mi.GetParameters(); + if (parameters.Length != 1) continue; + if (parameters[0].ParameterType != value.GetType()) continue; + opImplicit = mi; + break; + } + if (opImplicit == null) { + foreach (var mi in toType.GetRuntimeMethods()) { + if (!mi.IsSpecialName) continue; + if (mi.Name != "op_Implicit") continue; + if (!mi.IsPublic) continue; + if (mi.ReturnType != toType) continue; + var parameters = mi.GetParameters(); + if (parameters.Length != 1) continue; + if (parameters[0].ParameterType != value.GetType()) continue; + opImplicit = mi; + break; + } + } + if (opImplicit != null) { + value = opImplicit.Invoke(null, new[] { value }); return value; } } |