summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Xamarin.Forms.Build.Tasks/NodeILExtensions.cs8
-rw-r--r--Xamarin.Forms.Xaml.UnitTests/SetValue.xaml4
-rw-r--r--Xamarin.Forms.Xaml.UnitTests/SetValue.xaml.cs28
-rw-r--r--Xamarin.Forms.Xaml/TypeConversionExtensions.cs33
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;
}
}