Skip to content

Commit

Permalink
Fix OnPlatform + Setter when no match for current platform (#17061)
Browse files Browse the repository at this point in the history
* Fix OnPlatform + Setter when no match for current platform

When OnPlatforfm is used for a Setter value, and there's no match for the
current platform, fix so that the property isn't set (same behavior as Xamarin.Forms).
Previously, XamlC would report a "Missing Value For Setter" error when this happens
and non-compiled XAML would crash with an NRE. This PR contains fixes for both,
ensuring the XAML compiler doesn't show an error, then ensuring it doesn't crash
at runtime.

Fixes #12064

* Swtich to device tests for OnPlatform

* Remove test screenshot, no longer used
  • Loading branch information
BretJohnson committed Feb 12, 2024
1 parent 49be7e3 commit 7b07a83
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ public IEnumerable<Instruction> ProvideValue(VariableDefinitionReference vardefr
if (SetterValueIsCollection(bpRef, module, node, context))
yield break;

// valueNode is null, for example, when OnPlatform doesn't have a match for the current platform, so the property should not be set
if (valueNode == null)
throw new XamlParseException("Missing Value for Setter", (IXmlLineInfo)node);
yield break;

//if it's an elementNode, there's probably no need to convert it
if (valueNode is IElementNode)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,13 @@ public object ProvideValue(IServiceProvider serviceProvider)
if (!TryGetValueForPlatform(out var value))
{
if (bp != null)
return bp.GetDefaultValue(valueProvider.TargetObject as BindableObject);
{
object targetObject = valueProvider.TargetObject;

if (targetObject is Setter)
return null;
else return bp.GetDefaultValue(targetObject as BindableObject);
}
if (propertyType.IsValueType)
return Activator.CreateInstance(propertyType);
return null;
Expand Down
14 changes: 13 additions & 1 deletion src/Controls/tests/Xaml.UnitTests/OnPlatform.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,16 @@
<OnIdiom x:Key="fontSize" x:TypeArguments="x:Double"
Phone="{StaticResource phone}"
Tablet="{StaticResource tablet}"/>

<Style x:Key="ButtonStyle0" TargetType="Button">
<Setter Property="FontSize" Value="{OnPlatform iOS=36}" />
</Style>
<Style x:Key="ButtonStyle1" TargetType="Button">
<Setter Property="FontSize">
<OnPlatform x:TypeArguments="x:Double">
<On Platform="iOS">36</On>
</OnPlatform>
</Setter>
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout>
Expand Down Expand Up @@ -51,5 +60,8 @@
</OnPlatform>
</Label.HeightRequest>
</Label>
<Button x:Name="button0" Style="{StaticResource ButtonStyle0}" Text="Button label" />
<Button x:Name="button1" Style="{StaticResource ButtonStyle1}" Text="Button label" />
<Button x:Name="button2" FontSize="{OnPlatform iOS=36}" Text="Button label" />
</StackLayout>
</ContentPage>
53 changes: 52 additions & 1 deletion src/Controls/tests/Xaml.UnitTests/OnPlatform.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ public void DoubleToWidth(bool useCompiledXaml)
mockDeviceInfo.Platform = DevicePlatform.Android;
layout = new OnPlatform(useCompiledXaml);
Assert.AreEqual(30, layout.label0.WidthRequest);

mockDeviceInfo.Platform = DevicePlatform.MacCatalyst;
layout = new OnPlatform(useCompiledXaml);
Assert.AreEqual(0.0, layout.label0.WidthRequest);
}

[TestCase(false)]
Expand All @@ -74,6 +78,10 @@ public void StringToText(bool useCompiledXaml)
mockDeviceInfo.Platform = DevicePlatform.Android;
layout = new OnPlatform(useCompiledXaml);
Assert.AreEqual("Bar", layout.label0.Text);

mockDeviceInfo.Platform = DevicePlatform.MacCatalyst;
layout = new OnPlatform(useCompiledXaml);
Assert.AreEqual(null, layout.label0.Text);
}

[TestCase(false)]
Expand All @@ -87,7 +95,8 @@ public void OnPlatformAsResource(bool useCompiledXaml)
Assert.AreEqual(FontAttributes.Bold, (FontAttributes)onplat);
mockDeviceInfo.Platform = DevicePlatform.Android;
Assert.AreEqual(FontAttributes.Italic, (FontAttributes)onplat);

mockDeviceInfo.Platform = DevicePlatform.MacCatalyst;
Assert.AreEqual(FontAttributes.None, (FontAttributes)onplat);
}

[TestCase(false)]
Expand Down Expand Up @@ -119,6 +128,9 @@ public void OnPlatform2Syntax(bool useCompiledXaml)
layout = new OnPlatform(useCompiledXaml);
Assert.AreEqual(21, layout.label0.HeightRequest);

mockDeviceInfo.Platform = DevicePlatform.MacCatalyst;
layout = new OnPlatform(useCompiledXaml);
Assert.AreEqual(63.0, layout.label0.HeightRequest);

mockDeviceInfo.Platform = DevicePlatform.Create("FooBar");
layout = new OnPlatform(useCompiledXaml);
Expand All @@ -133,6 +145,45 @@ public void OnPlatformDefault(bool useCompiledXaml)
var layout = new OnPlatform(useCompiledXaml);
Assert.AreEqual(63, layout.label0.HeightRequest);
}

[TestCase(false)]
[TestCase(true)]
public void OnPlatformInStyle0(bool useCompiledXaml)
{
mockDeviceInfo.Platform = DevicePlatform.iOS;
var layout = new OnPlatform(useCompiledXaml);
Assert.AreEqual(36, layout.button0.FontSize);

mockDeviceInfo.Platform = DevicePlatform.MacCatalyst;
layout = new OnPlatform(useCompiledXaml);
Assert.AreEqual(0.0, layout.button0.FontSize);
}

[TestCase(false)]
[TestCase(true)]
public void OnPlatformInStyle1(bool useCompiledXaml)
{
mockDeviceInfo.Platform = DevicePlatform.iOS;
var layout = new OnPlatform(useCompiledXaml);
Assert.AreEqual(36, layout.button1.FontSize);

mockDeviceInfo.Platform = DevicePlatform.MacCatalyst;
layout = new OnPlatform(useCompiledXaml);
Assert.AreEqual(0.0, layout.button1.FontSize);
}

[TestCase(false)]
[TestCase(true)]
public void OnPlatformInline(bool useCompiledXaml)
{
mockDeviceInfo.Platform = DevicePlatform.iOS;
var layout = new OnPlatform(useCompiledXaml);
Assert.AreEqual(36, layout.button2.FontSize);

mockDeviceInfo.Platform = DevicePlatform.MacCatalyst;
layout = new OnPlatform(useCompiledXaml);
Assert.AreEqual(0.0, layout.button2.FontSize);
}
}
}
}

0 comments on commit 7b07a83

Please sign in to comment.