[Xaml[C]] do not use implicit operator if the variable is assignable (#1372)
authorStephane Delcroix <stephane@delcroix.org>
Wed, 13 Dec 2017 08:06:31 +0000 (09:06 +0100)
committerGitHub <noreply@github.com>
Wed, 13 Dec 2017 08:06:31 +0000 (09:06 +0100)
Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs
Xamarin.Forms.Core/Xaml/TypeConversionExtensions.cs
Xamarin.Forms.Xaml.UnitTests/Issues/Gh1346.xaml [new file with mode: 0644]
Xamarin.Forms.Xaml.UnitTests/Issues/Gh1346.xaml.cs [new file with mode: 0644]
Xamarin.Forms.Xaml.UnitTests/Xamarin.Forms.Xaml.UnitTests.csproj

index 0189990..9d9b51c 100644 (file)
@@ -1011,10 +1011,10 @@ namespace Xamarin.Forms.Build.Tasks
                        var propertyType = property.ResolveGenericPropertyType(declaringTypeReference, module);
                        var implicitOperator = vardef.VariableType.GetImplicitOperatorTo(propertyType, module);
 
-                       if (implicitOperator != null)
-                               return true;
                        if (vardef.VariableType.InheritsFromOrImplements(propertyType))
                                return true;
+                       if (implicitOperator != null)
+                               return true;
                        if (propertyType.FullName == "System.Object")
                                return true;
 
@@ -1060,7 +1060,7 @@ namespace Xamarin.Forms.Build.Tasks
                                var vardef = context.Variables [elementNode];
                                var implicitOperator = vardef.VariableType.GetImplicitOperatorTo(propertyType, module);
                                yield return Instruction.Create(OpCodes.Ldloc, vardef);
-                               if (implicitOperator != null) {
+                               if (!vardef.VariableType.InheritsFromOrImplements(propertyType) && implicitOperator != null) {
 //                                     IL_000f:  call !0 class [Xamarin.Forms.Core]Xamarin.Forms.OnPlatform`1<bool>::op_Implicit(class [Xamarin.Forms.Core]Xamarin.Forms.OnPlatform`1<!0>)
                                        yield return Instruction.Create(OpCodes.Call, module.ImportReference(implicitOperator));
                                } else if (!vardef.VariableType.IsValueType && propertyType.IsValueType)
index dd0641a..2af8286 100644 (file)
@@ -171,8 +171,8 @@ namespace Xamarin.Forms.Xaml
                                        return Decimal.Parse(str, CultureInfo.InvariantCulture);
                        }
 
-                       //if there's an implicit conversion, convert
-                       if (value != null) {
+                       //if the value is not assignable and there's an implicit conversion, convert
+                       if (value != null && !toType.IsAssignableFrom(value.GetType())) {
                                var opImplicit =   value.GetType().GetImplicitConversionOperator(fromType: value.GetType(), toType: toType)
                                                                ?? toType.GetImplicitConversionOperator(fromType: value.GetType(), toType: toType);
 
diff --git a/Xamarin.Forms.Xaml.UnitTests/Issues/Gh1346.xaml b/Xamarin.Forms.Xaml.UnitTests/Issues/Gh1346.xaml
new file mode 100644 (file)
index 0000000..7003dbe
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
+             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+             xmlns:local="clr-namespace:Xamarin.Forms.Xaml.UnitTests"
+
+             x:Class="Xamarin.Forms.Xaml.UnitTests.Gh1346">
+  <ContentPage.Resources>
+    <ResourceDictionary>
+      <Style x:Key="TestIconStyle" TargetType="local:Gh1346FontIcon">
+        <Setter Property="Icon" Value="{x:Static local:Gh1346FontAwesome.SnowflakeO}" />
+      </Style>         
+    </ResourceDictionary>
+  </ContentPage.Resources>
+  <local:Gh1346FontIcon x:Name="fontIcon" Style="{StaticResource TestIconStyle}" />
+</ContentPage>
\ No newline at end of file
diff --git a/Xamarin.Forms.Xaml.UnitTests/Issues/Gh1346.xaml.cs b/Xamarin.Forms.Xaml.UnitTests/Issues/Gh1346.xaml.cs
new file mode 100644 (file)
index 0000000..4daa7f5
--- /dev/null
@@ -0,0 +1,100 @@
+using System;
+using NUnit.Framework;
+using Xamarin.Forms.Core.UnitTests;
+
+namespace Xamarin.Forms.Xaml.UnitTests
+{
+       public partial class Gh1346 : ContentPage
+       {
+               public static string DefaultText = "Gh1346DefaultText";
+               public Gh1346()
+               {
+                       InitializeComponent();
+               }
+
+               public Gh1346(bool useCompiledXaml)
+               {
+                       //this stub will be replaced at compile time
+               }
+
+               [TestFixture]
+               class Tests
+               {
+
+                       [SetUp]
+                       public void Setup()
+                       {
+                               Device.PlatformServices = new MockPlatformServices();
+                       }
+
+                       [TearDown]
+                       public void TearDown()
+                       {
+                               Device.PlatformServices = null;
+                       }
+
+                       [TestCase(true), TestCase(false)]
+                       public void xStaticInStyle(bool useCompiledXaml)
+                       {
+                               var layout = new Gh1346(useCompiledXaml);
+                               var style = layout.Resources["TestIconStyle"] as Style;
+                               var setter = style.Setters[0];
+                               Assert.That(setter.Property, Is.EqualTo(Gh1346FontIcon.IconProperty));
+                               Assert.That(setter.Value, Is.TypeOf<Gh1346FontAwesome>());
+                               Assert.That(layout.fontIcon.Icon.Icon, Is.EqualTo("\uf2dc"));
+                       }
+               }
+       }
+
+       public class Gh1346FontIcon : View
+       {
+               public static readonly BindableProperty IconProperty = BindableProperty.Create(nameof(Icon), typeof(IGh1346FontIcon), typeof(Gh1346FontIcon));
+
+               public IGh1346FontIcon Icon {
+                       get => (IGh1346FontIcon)GetValue(IconProperty);
+                       set => SetValue(IconProperty, value);
+               }
+       }
+
+       public interface IGh1346FontIcon
+       {
+               string Icon { get; }
+       }
+
+       public sealed class Gh1346FontAwesome : IGh1346FontIcon
+       {
+               public string Icon { get; }
+
+               Gh1346FontAwesome(char c)
+               {
+                       Icon = c.ToString();
+               }
+
+               //public static implicit operator FontIconOptions(FontAwesome @this)
+               //{
+               //      return new FontIconOptions(@this);
+               //}
+
+               public static implicit operator Gh1346FontIconOptions(Gh1346FontAwesome @this)
+               {
+                       return new Gh1346FontIconOptions(@this);
+               }
+
+               public static readonly Gh1346FontAwesome SnowflakeO = new Gh1346FontAwesome('\uf2dc');
+       }
+
+       public sealed class Gh1346FontIconOptions
+       {
+               public IGh1346FontIcon FontIcon { get; set; }
+
+               public Color Color { get; set; } = Color.White;
+
+               public Gh1346FontIconOptions() { }
+
+               public Gh1346FontIconOptions(IGh1346FontIcon icon)
+               {
+                       FontIcon = icon ?? throw new ArgumentNullException(nameof(icon));
+               }
+       }
+
+}
\ No newline at end of file
index b8849d9..14ea815 100644 (file)
     <Compile Include="Issues\Bz60788.xaml.cs">
       <DependentUpon>Bz60788.xaml</DependentUpon>
     </Compile>
+    <Compile Include="Issues\Gh1346.xaml.cs">
+      <DependentUpon>Gh1346.xaml</DependentUpon>
+    </Compile>
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <Import Project="..\.nuspec\Xamarin.Forms.Debug.targets" />
     <EmbeddedResource Include="Issues\Bz60788.xaml">
       <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
     </EmbeddedResource>
+    <EmbeddedResource Include="Issues\Gh1346.xaml">
+      <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
+    </EmbeddedResource>
   </ItemGroup>
   <ItemGroup>
     <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />