From 2a17b6cdb6903b7a3f7734d2408d46ead4d4cf77 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 7 Nov 2023 16:29:13 +0200 Subject: [PATCH 1/3] fix(hr): Fix RegisterAttribute generation for nested/generic types --- .../Helpers/SymbolExtensions.cs | 20 +++++++++++-- .../NativeCtor/NativeCtorsGenerator.cs | 9 +++--- .../NestedGenericClasses.Android.cs | 28 +++++++++++++++++++ 3 files changed, 49 insertions(+), 8 deletions(-) create mode 100644 src/Uno.UI.RuntimeTests/Tests/NativeCtorGeneratorTests/NestedGenericClasses.Android.cs diff --git a/src/SourceGenerators/SourceGeneratorHelpers/Helpers/SymbolExtensions.cs b/src/SourceGenerators/SourceGeneratorHelpers/Helpers/SymbolExtensions.cs index bfbb046e7883..2c7354bdcecf 100644 --- a/src/SourceGenerators/SourceGeneratorHelpers/Helpers/SymbolExtensions.cs +++ b/src/SourceGenerators/SourceGeneratorHelpers/Helpers/SymbolExtensions.cs @@ -8,6 +8,7 @@ using Uno; using Uno.Roslyn; using Microsoft.CodeAnalysis.PooledObjects; +using System.Diagnostics; namespace Microsoft.CodeAnalysis { @@ -398,7 +399,10 @@ ITypeSymbol ts when ts.ContainingType is ISymbol pt return type?.GetFullyQualifiedTypeExcludingGlobal(); } - public static string GetFullMetadataName(this ITypeSymbol symbol) + // forRegisterAttributeDotReplacement is used specifically by NativeCtorsGenerator to generate for the Android/iOS RegisterAttribute + // A non-null value means we are generating for RegisterAttribute, and we replace invalid characters with '_'. + // The '.' is special cased to be replaced by the value of forRegisterAttributeDotReplacement, whether it's '_' or '/' + public static string GetFullMetadataName(this ITypeSymbol symbol, char? forRegisterAttributeDotReplacement = null) { ISymbol s = symbol; var sb = new StringBuilder(s.MetadataName); @@ -428,9 +432,19 @@ public static string GetFullMetadataName(this ITypeSymbol symbol) var namedType = symbol as INamedTypeSymbol; - if (namedType?.TypeArguments.Any() ?? false) + // When generating for RegisterAttribute, the name we pass to the attribute is used by Xamarin tooling for generating Java files, specifically, it's used for the class name. + // The characters '.', '+', and '`' are not valid characters for a class name. + // On Android, we use '/' as replacement for '.' to match Jni name: + // https://github.com/xamarin/java.interop/blob/38c8a827e78ffe9c80ad2313a9e0e0d4f8215184/src/Java.Interop.Tools.TypeNameMappings/Java.Interop.Tools.TypeNameMappings/JavaNativeTypeManager.cs#L693-L699 + if (forRegisterAttributeDotReplacement.HasValue) { - var genericArgs = namedType.TypeArguments.Select(GetFullMetadataName).JoinBy(","); + var replacement = forRegisterAttributeDotReplacement.Value; + sb.Replace('.', replacement).Replace('+', '_').Replace('`', '_'); + } + else if (namedType?.TypeArguments.Any() ?? false) + { + // We don't append type arguments when generating for RegisterAttribute because '[' and ']' are invalid characters for a class name. + var genericArgs = namedType.TypeArguments.Select(a => GetFullMetadataName(a, null)).JoinBy(","); sb.Append($"[{genericArgs}]"); } diff --git a/src/SourceGenerators/Uno.UI.SourceGenerators/NativeCtor/NativeCtorsGenerator.cs b/src/SourceGenerators/Uno.UI.SourceGenerators/NativeCtor/NativeCtorsGenerator.cs index 712b32026036..499ae96e4c7b 100644 --- a/src/SourceGenerators/Uno.UI.SourceGenerators/NativeCtor/NativeCtorsGenerator.cs +++ b/src/SourceGenerators/Uno.UI.SourceGenerators/NativeCtor/NativeCtorsGenerator.cs @@ -5,7 +5,6 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Uno.UI.SourceGenerators.Helpers; -using System.Diagnostics; using Uno.Extensions; using Uno.Roslyn; @@ -37,7 +36,7 @@ private class SerializationMethodsGenerator : SymbolVisitor private readonly INamedTypeSymbol? _androidViewSymbol; private readonly INamedTypeSymbol? _intPtrSymbol; private readonly INamedTypeSymbol? _jniHandleOwnershipSymbol; - private readonly INamedTypeSymbol?[]? _javaCtorParams; + private readonly INamedTypeSymbol?[] _javaCtorParams; private readonly string _configuration; private readonly bool _isDebug; private readonly bool _isHotReloadEnabled; @@ -129,7 +128,7 @@ private void ProcessType(INamedTypeSymbol typeSymbol) if (isAndroidView) { - Func predicate = m => m.Parameters.Select(p => p.Type).SequenceEqual(_javaCtorParams ?? Array.Empty()); + Func predicate = m => m.Parameters.Select(p => p.Type).SequenceEqual(_javaCtorParams); var nativeCtor = GetNativeCtor(typeSymbol, predicate, considerAllBaseTypes: false); if (nativeCtor == null && GetNativeCtor(typeSymbol.BaseType, predicate, considerAllBaseTypes: true) != null) @@ -164,7 +163,7 @@ string GetGeneratedCode(INamedTypeSymbol typeSymbol) // generated at runtime var registerParamApple = _isHotReloadEnabled - ? $"\"{typeSymbol.GetFullMetadataName().Replace(".", "_")}\"" + ? $"\"{typeSymbol.GetFullMetadataName(forRegisterAttributeDotReplacement: '_')}\"" : ""; builder.AppendLineIndented($"[global::Foundation.Register({registerParamApple})]"); @@ -175,7 +174,7 @@ string GetGeneratedCode(INamedTypeSymbol typeSymbol) { builder.AppendLineIndented("#if __ANDROID__"); - var registerParamAndroid = $"\"{typeSymbol.GetFullMetadataName().Replace(".", "/")}\""; + var registerParamAndroid = $"\"{typeSymbol.GetFullMetadataName(forRegisterAttributeDotReplacement: '/')}\""; builder.AppendLineIndented($"[global::Android.Runtime.Register({registerParamAndroid})]"); diff --git a/src/Uno.UI.RuntimeTests/Tests/NativeCtorGeneratorTests/NestedGenericClasses.Android.cs b/src/Uno.UI.RuntimeTests/Tests/NativeCtorGeneratorTests/NestedGenericClasses.Android.cs new file mode 100644 index 000000000000..cae29ef09671 --- /dev/null +++ b/src/Uno.UI.RuntimeTests/Tests/NativeCtorGeneratorTests/NestedGenericClasses.Android.cs @@ -0,0 +1,28 @@ +using Android.Content; + +namespace Uno.UI.RuntimeTests.Tests.NativeCtorGeneratorTests +{ + public partial class GenericClass : Android.Views.View + { + public GenericClass(Context context) : base(context) { } + public GenericClass(Context context, Android.Util.IAttributeSet attributeSet) : base(context, attributeSet) { } + + public partial class NestedGenericClass : Android.Views.View + { + public NestedGenericClass(Context context) : base(context) { } + public NestedGenericClass(Context context, Android.Util.IAttributeSet attributeSet) : base(context, attributeSet) { } + } + } +} + +public partial class GenericClassGlobalNamespace : Android.Views.View +{ + public GenericClassGlobalNamespace(Context context) : base(context) { } + public GenericClassGlobalNamespace(Context context, Android.Util.IAttributeSet attributeSet) : base(context, attributeSet) { } + + public partial class NestedGenericClassGlobalNamespace : Android.Views.View + { + public NestedGenericClassGlobalNamespace(Context context) : base(context) { } + public NestedGenericClassGlobalNamespace(Context context, Android.Util.IAttributeSet attributeSet) : base(context, attributeSet) { } + } +} From b5b44787c89ad09fb4e25ca8a0544e6793fabb24 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 7 Nov 2023 16:49:18 +0200 Subject: [PATCH 2/3] Revert "fix: Avoid using nested View class in Given_Border" This reverts commit 262c4c3bd8736ad7c05259a265349b3d96d5202a. --- .../Windows_UI_XAML_Controls/BorderTests/Given_Border.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Uno.UI.Tests/Windows_UI_XAML_Controls/BorderTests/Given_Border.cs b/src/Uno.UI.Tests/Windows_UI_XAML_Controls/BorderTests/Given_Border.cs index 1676ebc348c3..de89827bebfc 100644 --- a/src/Uno.UI.Tests/Windows_UI_XAML_Controls/BorderTests/Given_Border.cs +++ b/src/Uno.UI.Tests/Windows_UI_XAML_Controls/BorderTests/Given_Border.cs @@ -23,6 +23,10 @@ namespace Uno.UI.Tests.BorderTests #endif public partial class Given_Border : Context { + private partial class View : FrameworkElement + { + } + [TestMethod] public void When_Border_Has_Fixed_Size() { @@ -297,9 +301,5 @@ public void When_Child_Is_Stretch_With_MaxSize_And_MinSize() } } } - - public partial class View : FrameworkElement - { - } } #endif From a5362ab70188d4730c593e62585c003d92f614d9 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 7 Nov 2023 16:52:19 +0200 Subject: [PATCH 3/3] Revert "fix: Avoid nested UI classes in runtime tests" This reverts commit e40221ae1d6c3d6e7d261183d7d024ca64082e26. --- .../Repeater/ViewportTests.cs | 204 +++++++++--------- .../Tests/Windows_UI_Xaml/Given_Control.cs | 94 ++++---- .../Windows_UI_Xaml/Given_FrameworkElement.cs | 20 +- .../Tests/Windows_UI_Xaml/Given_UIElement.cs | 86 ++++---- .../Windows_UI_Xaml_Controls/Given_Border.cs | 46 ++-- .../Given_ListViewBase.cs | 16 +- .../Given_StackPanel.cs | 42 ++-- .../Given_ObjectAnimationUsingKeyFrames.cs | 17 +- 8 files changed, 262 insertions(+), 263 deletions(-) diff --git a/src/Uno.UI.RuntimeTests/MUX/Microsoft_UI_Xaml_Controls/Repeater/ViewportTests.cs b/src/Uno.UI.RuntimeTests/MUX/Microsoft_UI_Xaml_Controls/Repeater/ViewportTests.cs index cc3c352fb27c..eb228835ec46 100644 --- a/src/Uno.UI.RuntimeTests/MUX/Microsoft_UI_Xaml_Controls/Repeater/ViewportTests.cs +++ b/src/Uno.UI.RuntimeTests/MUX/Microsoft_UI_Xaml_Controls/Repeater/ViewportTests.cs @@ -1353,145 +1353,145 @@ private static VirtualizingLayout GetMonitoringLayout(Size desiredSize, List finalSize }; } - } - - internal partial class TestScrollingSurface : ContentControl, IRepeaterScrollingSurface - { - private bool _isHorizontallyScrollable; - private bool _isVerticallyScrollable; - private ConfigurationChangedEventHandler _configurationChangedTokenTable; - public bool InMeasure { get; set; } - public bool InArrange { get; set; } - public bool InPostArrange { get; private set; } + private partial class TestScrollingSurface : ContentControl, IRepeaterScrollingSurface + { + private bool _isHorizontallyScrollable; + private bool _isVerticallyScrollable; + private ConfigurationChangedEventHandler _configurationChangedTokenTable; - public Action ConfigurationChangedAddFunc { get; set; } - public Action ConfigurationChangedRemoveFunc { get; set; } + public bool InMeasure { get; set; } + public bool InArrange { get; set; } + public bool InPostArrange { get; private set; } - public Action RegisterAnchorCandidateFunc { get; set; } - public Action UnregisterAnchorCandidateFunc { get; set; } - public Func GetRelativeViewportFunc { get; set; } + public Action ConfigurationChangedAddFunc { get; set; } + public Action ConfigurationChangedRemoveFunc { get; set; } - public UIElement AnchorElement { get; set; } + public Action RegisterAnchorCandidateFunc { get; set; } + public Action UnregisterAnchorCandidateFunc { get; set; } + public Func GetRelativeViewportFunc { get; set; } - public bool IsHorizontallyScrollable - { - get { return _isHorizontallyScrollable; } - set - { - _isHorizontallyScrollable = value; - RaiseConfigurationChanged(); - InvalidateMeasure(); - } - } + public UIElement AnchorElement { get; set; } - public bool IsVerticallyScrollable - { - get { return _isVerticallyScrollable; } - set + public bool IsHorizontallyScrollable { - _isVerticallyScrollable = value; - RaiseConfigurationChanged(); - InvalidateMeasure(); + get { return _isHorizontallyScrollable; } + set + { + _isHorizontallyScrollable = value; + RaiseConfigurationChanged(); + InvalidateMeasure(); + } } - } - public event ConfigurationChangedEventHandler ConfigurationChanged - { - add + public bool IsVerticallyScrollable { - if (ConfigurationChangedAddFunc != null) + get { return _isVerticallyScrollable; } + set { - ConfigurationChangedAddFunc(); + _isVerticallyScrollable = value; + RaiseConfigurationChanged(); + InvalidateMeasure(); } - - _configurationChangedTokenTable += value; } - remove + + public event ConfigurationChangedEventHandler ConfigurationChanged { - if (ConfigurationChangedRemoveFunc != null) + add { - ConfigurationChangedRemoveFunc(); + if (ConfigurationChangedAddFunc != null) + { + ConfigurationChangedAddFunc(); + } + + _configurationChangedTokenTable += value; } + remove + { + if (ConfigurationChangedRemoveFunc != null) + { + ConfigurationChangedRemoveFunc(); + } - _configurationChangedTokenTable -= value; + _configurationChangedTokenTable -= value; + } } - } - public event PostArrangeEventHandler PostArrange; + public event PostArrangeEventHandler PostArrange; #pragma warning disable CS0067 - // Warning CS0067: The event 'ViewportTests.TestScrollingSurface.ViewportChanged' is never used. - public event ViewportChangedEventHandler ViewportChanged; + // Warning CS0067: The event 'ViewportTests.TestScrollingSurface.ViewportChanged' is never used. + public event ViewportChangedEventHandler ViewportChanged; #pragma warning restore CS0067 - public void RegisterAnchorCandidate(UIElement element) - { - RegisterAnchorCandidateFunc(element); - } + public void RegisterAnchorCandidate(UIElement element) + { + RegisterAnchorCandidateFunc(element); + } - public void UnregisterAnchorCandidate(UIElement element) - { - UnregisterAnchorCandidateFunc(element); - } + public void UnregisterAnchorCandidate(UIElement element) + { + UnregisterAnchorCandidateFunc(element); + } - public Rect GetRelativeViewport(UIElement child) - { - return GetRelativeViewportFunc(child); - } + public Rect GetRelativeViewport(UIElement child) + { + return GetRelativeViewportFunc(child); + } - protected override Size MeasureOverride(Size availableSize) - { - InMeasure = true; - var result = base.MeasureOverride(availableSize); - InMeasure = false; - return result; - } + protected override Size MeasureOverride(Size availableSize) + { + InMeasure = true; + var result = base.MeasureOverride(availableSize); + InMeasure = false; + return result; + } - protected override Size ArrangeOverride(Size finalSize) - { - InArrange = true; + protected override Size ArrangeOverride(Size finalSize) + { + InArrange = true; - var result = base.ArrangeOverride(finalSize); + var result = base.ArrangeOverride(finalSize); - InArrange = false; - InPostArrange = true; + InArrange = false; + InPostArrange = true; - if (PostArrange != null) - { - PostArrange(this); - } + if (PostArrange != null) + { + PostArrange(this); + } - InPostArrange = false; + InPostArrange = false; - return result; - } + return result; + } - private void RaiseConfigurationChanged() - { - _configurationChangedTokenTable?.Invoke(this); + private void RaiseConfigurationChanged() + { + _configurationChangedTokenTable?.Invoke(this); + } } - } - internal partial class TestStackLayout : StackLayout - { - public UIElement SuggestedAnchor { get; private set; } - - protected internal override Size MeasureOverride(VirtualizingLayoutContext context, Size availableSize) + private partial class TestStackLayout : StackLayout { - var anchorIndex = context.RecommendedAnchorIndex; - SuggestedAnchor = anchorIndex < 0 ? null : context.GetOrCreateElementAt(anchorIndex); - return base.MeasureOverride(context, availableSize); - } - } + public UIElement SuggestedAnchor { get; private set; } - internal partial class TestGridLayout : UniformGridLayout - { - public UIElement SuggestedAnchor { get; private set; } + protected internal override Size MeasureOverride(VirtualizingLayoutContext context, Size availableSize) + { + var anchorIndex = context.RecommendedAnchorIndex; + SuggestedAnchor = anchorIndex < 0 ? null : context.GetOrCreateElementAt(anchorIndex); + return base.MeasureOverride(context, availableSize); + } + } - protected internal override Size MeasureOverride(VirtualizingLayoutContext context, Size availableSize) + private partial class TestGridLayout : UniformGridLayout { - var anchorIndex = context.RecommendedAnchorIndex; - SuggestedAnchor = anchorIndex < 0 ? null : context.GetOrCreateElementAt(anchorIndex); - return base.MeasureOverride(context, availableSize); + public UIElement SuggestedAnchor { get; private set; } + + protected internal override Size MeasureOverride(VirtualizingLayoutContext context, Size availableSize) + { + var anchorIndex = context.RecommendedAnchorIndex; + SuggestedAnchor = anchorIndex < 0 ? null : context.GetOrCreateElementAt(anchorIndex); + return base.MeasureOverride(context, availableSize); + } } } } diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_Control.cs b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_Control.cs index d73b51eb615f..01435c2e0dfe 100644 --- a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_Control.cs +++ b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_Control.cs @@ -18,6 +18,53 @@ namespace Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml [TestClass] public partial class Given_Control { + private partial class CustomControl : Control + { + public Size AvailableSizePassedToMeasureOverride { get; private set; } + protected override Size MeasureOverride(Size availableSize) + { + AvailableSizePassedToMeasureOverride = availableSize; + return new(2000, 2000); + } + } + +#if HAS_UNO + private partial class OnApplyTemplateCounterControl : Control + { + public OnApplyTemplateCounterControl() : base() + { + Loading += (_, _) => OnControlLoading(); + } + + private ControlTemplate _template; + public int OnApplyTemplateCalls { get; private set; } + + protected override void OnApplyTemplate() + { + // OnApplyTemplate should be called when the Template changes, so we only care + // about (unnecessary) calls that happen when the Template doesn't change + if (_template != Template) + { + _template = Template; + OnApplyTemplateCalls = 0; + } + + OnApplyTemplateCalls++; + } + + private void OnControlLoading() => Style = new Style + { + Setters = + { + new Setter(TemplateProperty, new ControlTemplate(() => new Grid()) + { + TargetType = typeof(OnApplyTemplateCounterControl), + }) + } + }; + } +#endif + [TestMethod] [RunsOnUIThread] public async Task When_Limited_By_Available_Size_Before_Margin_Application() @@ -238,51 +285,4 @@ public async Task When_Padding_Set_In_SizeChanged() Assert.AreEqual(0, ((UIElement)VisualTreeHelper.GetChild(SUT, 0)).ActualOffset.Y); } } - -#if HAS_UNO - public partial class OnApplyTemplateCounterControl : Control - { - public OnApplyTemplateCounterControl() : base() - { - Loading += (_, _) => OnControlLoading(); - } - - private ControlTemplate _template; - public int OnApplyTemplateCalls { get; private set; } - - protected override void OnApplyTemplate() - { - // OnApplyTemplate should be called when the Template changes, so we only care - // about (unnecessary) calls that happen when the Template doesn't change - if (_template != Template) - { - _template = Template; - OnApplyTemplateCalls = 0; - } - - OnApplyTemplateCalls++; - } - - private void OnControlLoading() => Style = new Style - { - Setters = - { - new Setter(TemplateProperty, new ControlTemplate(() => new Grid()) - { - TargetType = typeof(OnApplyTemplateCounterControl), - }) - } - }; - } -#endif - - public partial class CustomControl : Control - { - public Size AvailableSizePassedToMeasureOverride { get; private set; } - protected override Size MeasureOverride(Size availableSize) - { - AvailableSizePassedToMeasureOverride = availableSize; - return new(2000, 2000); - } - } } diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_FrameworkElement.cs b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_FrameworkElement.cs index 2a8d6d7055a4..ff95ad1189bd 100644 --- a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_FrameworkElement.cs +++ b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_FrameworkElement.cs @@ -331,6 +331,16 @@ public Task When_Grid_Measure_And_Invalidate() => }); #endif + public partial class MyGrid : Grid + { + public Size AvailableSizeUsedForMeasure { get; private set; } + protected override Size MeasureOverride(Size availableSize) + { + AvailableSizeUsedForMeasure = availableSize; + return base.MeasureOverride(availableSize); + } + } + [TestMethod] [RunsOnUIThread] #if __MACOS__ @@ -765,16 +775,6 @@ public async Task When_Add_Element_While_Parent_Loaded_Then_Load_Raised() #endif } - public partial class MyGrid : Grid - { - public Size AvailableSizeUsedForMeasure { get; private set; } - protected override Size MeasureOverride(Size availableSize) - { - AvailableSizeUsedForMeasure = availableSize; - return base.MeasureOverride(availableSize); - } - } - public partial class MyControl01 : FrameworkElement { public List MeasureOverrides { get; } = new List(); diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_UIElement.cs b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_UIElement.cs index 0c23c2686b20..69785e9e513c 100644 --- a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_UIElement.cs +++ b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_UIElement.cs @@ -580,6 +580,49 @@ public async Task When_InvalidatingMeasureAndArrangeByChangingSizeTwice() return (ctl1, ctl2, ctl3); } + private partial class MeasureAndArrangeCounter : Panel + { + internal int MeasureCount; + internal int ArrangeCount; + protected override Size MeasureOverride(Size availableSize) + { + MeasureCount++; + + // copied from FrameworkElement.MeasureOverride and modified to compile on Windows + var child = Children.Count > 0 ? Children[0] : null; +#if NETFX_CORE + if (child != null) + { + child.Measure(availableSize); + return child.DesiredSize; + } + + return new Size(0, 0); +#else + return child != null ? MeasureElement(child, availableSize) : new Size(0, 0); +#endif + } + + protected override Size ArrangeOverride(Size finalSize) + { + ArrangeCount++; + + // copied from FrameworkElement.ArrangeOverride and modified to compile on Windows + var child = Children.Count > 0 ? Children[0] : null; + + if (child != null) + { +#if NETFX_CORE + child.Arrange(new Rect(0, 0, finalSize.Width, finalSize.Height)); +#else + ArrangeElement(child, new Rect(0, 0, finalSize.Width, finalSize.Height)); +#endif + } + + return finalSize; + } + } + #if __CROSSRUNTIME__ [TestMethod] [RunsOnUIThread] @@ -652,49 +695,6 @@ public async Task When_Explicit_Size_Clip_Changes() #endif } - internal partial class MeasureAndArrangeCounter : Panel - { - internal int MeasureCount; - internal int ArrangeCount; - protected override Size MeasureOverride(Size availableSize) - { - MeasureCount++; - - // copied from FrameworkElement.MeasureOverride and modified to compile on Windows - var child = Children.Count > 0 ? Children[0] : null; -#if NETFX_CORE - if (child != null) - { - child.Measure(availableSize); - return child.DesiredSize; - } - - return new Size(0, 0); -#else - return child != null ? MeasureElement(child, availableSize) : new Size(0, 0); -#endif - } - - protected override Size ArrangeOverride(Size finalSize) - { - ArrangeCount++; - - // copied from FrameworkElement.ArrangeOverride and modified to compile on Windows - var child = Children.Count > 0 ? Children[0] : null; - - if (child != null) - { -#if NETFX_CORE - child.Arrange(new Rect(0, 0, finalSize.Width, finalSize.Height)); -#else - ArrangeElement(child, new Rect(0, 0, finalSize.Width, finalSize.Height)); -#endif - } - - return finalSize; - } - } - internal partial class When_UpdateLayout_Then_ReentrancyNotAllowed_Element : FrameworkElement { private bool _isMeasuring, _isArranging; diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_Border.cs b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_Border.cs index a287a41a166b..2d8acbc6462c 100644 --- a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_Border.cs +++ b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_Border.cs @@ -30,6 +30,29 @@ namespace Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml_Controls [RunsOnUIThread] public partial class Given_Border { + private partial class CustomControl : Control + { + public Border Child { get; set; } + public Size AvailableSizePassedToMeasureOverride { get; private set; } + public Size SizeReturnedFromMeasureOverride { get; private set; } + public Size FinalSizePassedToArrangeOverride { get; private set; } + public Size SizeReturnedFromArrangeOverride { get; private set; } + + protected override Size MeasureOverride(Size availableSize) + { + AvailableSizePassedToMeasureOverride = availableSize; + Child.Measure(availableSize); + return SizeReturnedFromMeasureOverride = Child.DesiredSize; + } + + protected override Size ArrangeOverride(Size finalSize) + { + FinalSizePassedToArrangeOverride = finalSize; + Child.Arrange(new(0, 0, finalSize.Width, finalSize.Height)); + return SizeReturnedFromArrangeOverride = new(Child.ActualSize.X, Child.ActualSize.Y); + } + } + [TestMethod] [DataRow(true)] [DataRow(false)] @@ -739,27 +762,4 @@ private async Task TakeScreenshot(FrameworkElement SUT) return await UITestHelper.ScreenShot(SUT); } } - - internal partial class CustomControl : Control - { - public Border Child { get; set; } - public Size AvailableSizePassedToMeasureOverride { get; private set; } - public Size SizeReturnedFromMeasureOverride { get; private set; } - public Size FinalSizePassedToArrangeOverride { get; private set; } - public Size SizeReturnedFromArrangeOverride { get; private set; } - - protected override Size MeasureOverride(Size availableSize) - { - AvailableSizePassedToMeasureOverride = availableSize; - Child.Measure(availableSize); - return SizeReturnedFromMeasureOverride = Child.DesiredSize; - } - - protected override Size ArrangeOverride(Size finalSize) - { - FinalSizePassedToArrangeOverride = finalSize; - Child.Arrange(new(0, 0, finalSize.Width, finalSize.Height)); - return SizeReturnedFromArrangeOverride = new(Child.ActualSize.X, Child.ActualSize.Y); - } - } } diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_ListViewBase.cs b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_ListViewBase.cs index c6e6b1657a29..ee781d013d65 100644 --- a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_ListViewBase.cs +++ b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_ListViewBase.cs @@ -4595,16 +4595,16 @@ private async Task AssertCollectedReference(WeakReference reference) Assert.IsFalse(reference.IsAlive); } - } - - public partial class OnItemsChangedListView : ListView - { - public Action ItemsChangedAction; - protected override void OnItemsChanged(object e) + public partial class OnItemsChangedListView : ListView { - base.OnItemsChanged(e); - ItemsChangedAction?.Invoke(); + public Action ItemsChangedAction; + + protected override void OnItemsChanged(object e) + { + base.OnItemsChanged(e); + ItemsChangedAction?.Invoke(); + } } } } diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_StackPanel.cs b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_StackPanel.cs index 86fd9b054170..e65082ad3282 100644 --- a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_StackPanel.cs +++ b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_StackPanel.cs @@ -25,6 +25,27 @@ namespace Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml_Controls #endif public partial class Given_StackPanel { + private partial class MyStackPanel : StackPanel + { + public int MeasureCount { get; private set; } + public int ArrangeCount { get; private set; } + + public Size LastMeasureOverrideReturn { get; private set; } + public Size LastArrangeOverrideReturn { get; private set; } + + protected override Size MeasureOverride(Size availableSize) + { + MeasureCount++; + return LastMeasureOverrideReturn = base.MeasureOverride(availableSize); + } + + protected override Size ArrangeOverride(Size arrangeSize) + { + ArrangeCount++; + return LastArrangeOverrideReturn = base.ArrangeOverride(arrangeSize); + } + } + [TestMethod] [RunsOnUIThread] #if __IOS__ @@ -386,25 +407,4 @@ public async Task When_No_Children_SnapPoints() SUT.GetIrregularSnapPoints(Orientation.Vertical, SnapPointsAlignment.Center).ToList().Should().BeEmpty(); } } - - internal partial class MyStackPanel : StackPanel - { - public int MeasureCount { get; private set; } - public int ArrangeCount { get; private set; } - - public Size LastMeasureOverrideReturn { get; private set; } - public Size LastArrangeOverrideReturn { get; private set; } - - protected override Size MeasureOverride(Size availableSize) - { - MeasureCount++; - return LastMeasureOverrideReturn = base.MeasureOverride(availableSize); - } - - protected override Size ArrangeOverride(Size arrangeSize) - { - ArrangeCount++; - return LastArrangeOverrideReturn = base.ArrangeOverride(arrangeSize); - } - } } diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Media_Animation/Given_ObjectAnimationUsingKeyFrames.cs b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Media_Animation/Given_ObjectAnimationUsingKeyFrames.cs index 1a5e60102d98..740ca673f77f 100644 --- a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Media_Animation/Given_ObjectAnimationUsingKeyFrames.cs +++ b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Media_Animation/Given_ObjectAnimationUsingKeyFrames.cs @@ -338,17 +338,16 @@ public void When_FirstFrameTimeIsZero_Then_ItsAppliedSyncOnStart() /// Ensure Fluent styles are available for the course of a single test. /// private IDisposable UseFluentStyles() => StyleHelper.UseFluentStyles(); - } - // TODO: Reintroduce nesting of this class once #13893 is fixed. - // Intentionally nested to test NativeCtorsGenerator handling of nested classes. - public partial class MyCheckBox : CheckBox - { - public ContentPresenter ContentPresenter { get; set; } - protected override void OnApplyTemplate() + // Intentionally nested to test NativeCtorsGenerator handling of nested classes. + public partial class MyCheckBox : CheckBox { - base.OnApplyTemplate(); - ContentPresenter = GetTemplateChild("ContentPresenter") as ContentPresenter; // This is a ContentPresenter + public ContentPresenter ContentPresenter { get; set; } + protected override void OnApplyTemplate() + { + base.OnApplyTemplate(); + ContentPresenter = GetTemplateChild("ContentPresenter") as ContentPresenter; // This is a ContentPresenter + } } }