From 64b63fa5d28ddba659d82f2d0342c58b06bfca5a Mon Sep 17 00:00:00 2001 From: Julien Lebosquain Date: Fri, 19 Dec 2025 12:45:30 +0100 Subject: [PATCH] Fix common warnings (#20311) --- .editorconfig | 3 --- samples/Directory.Build.props | 1 + samples/GpuInterop/GpuInterop.csproj | 7 ++++++- samples/MiniMvvm/MiniCommand.cs | 8 ++++---- samples/MiniMvvm/PropertyChangedExtensions.cs | 6 +++--- samples/TextTestApp/InteractiveLineControl.cs | 4 +--- samples/TextTestApp/MainWindow.axaml.cs | 14 +++++++++---- .../Avalonia.Android/Avalonia.Android.csproj | 3 +++ .../Avalonia.Android/ChoreographerTimer.cs | 3 +-- .../Storage/AndroidStorageProvider.cs | 2 +- src/Avalonia.Base/Controls/NameScope.cs | 8 ++++---- src/Avalonia.Base/Media/PolylineGeometry.cs | 1 - .../TextFormatting/TextParagraphProperties.cs | 2 +- .../Media/TextPathSegmentEllipsis.cs | 6 ------ .../Platform/Storage/FilePickerOpenOptions.cs | 4 ++-- .../Platform/Storage/NoopStorageProvider.cs | 2 +- .../Platform/Storage/SaveFilePickerResult.cs | 7 +------ .../Composition/CompositionDrawingSurface.cs | 4 +++- src/Avalonia.Base/Styling/Selector.cs | 6 +++++- .../Threading/DispatcherPriorityAwaitable.cs | 19 +++++++++++++++++- src/Avalonia.Controls/TextBlock.cs | 5 ----- src/Avalonia.DesignerSupport/Remote/Stubs.cs | 2 +- .../ManagedStorageProvider.cs | 2 +- src/Avalonia.FreeDesktop/DBusSystemDialog.cs | 2 +- src/Avalonia.Native/GpuHandleWrapFeature.cs | 2 ++ src/Avalonia.Native/StorageProviderImpl.cs | 2 +- .../NativeDialogs/GtkNativeFileDialogs.cs | 2 +- .../Storage/BrowserStorageProvider.cs | 2 +- .../Avalonia.Markup.Xaml.Loader.csproj | 4 ---- .../Avalonia.Win32/Win32StorageProvider.cs | 2 +- .../Storage/IOSStorageProvider.cs | 2 +- .../Input/PointerTestsBase.cs | 2 +- .../CompileAvaloniaXamlTaskTest.cs | 2 +- .../GridSplitterTests.cs | 2 ++ .../Platform/ScreensTests.cs | 2 ++ .../Shapes/ShapeTests.cs | 16 ++++++++------- .../ToolTipTests.cs | 3 ++- .../IsolationTests.cs | 4 ++++ .../Avalonia.IntegrationTests.Appium.csproj | 6 ++++++ .../Avalonia.LeakTests/AvaloniaObjectTests.cs | 2 +- tests/Avalonia.LeakTests/ControlTests.cs | 16 +++++++-------- .../Data/BindingTests_Delay.cs | 2 +- .../CompiledBindingExtensionTests.cs | 2 +- .../CrossTests/Media/ImageScalingTests.cs | 2 ++ .../Media/CustomFontManagerImpl.cs | 8 +++++--- .../HarfBuzzFontManagerImpl.cs | 8 +++++--- tests/Avalonia.UnitTests/TestRoot.cs | 20 ++++++++++--------- tests/Avalonia.UnitTests/ThreadRunHelper.cs | 4 +++- tests/Directory.Build.props | 1 + 49 files changed, 140 insertions(+), 99 deletions(-) diff --git a/.editorconfig b/.editorconfig index 8c6ad717e4..7051372383 100644 --- a/.editorconfig +++ b/.editorconfig @@ -141,9 +141,6 @@ dotnet_analyzer_diagnostic.category-Performance.severity = none #error - Uncomme # CS0649: Field 'field' is never assigned to, and will always have its default value 'value' dotnet_diagnostic.CS0649.severity = error -# CS1591: Missing XML comment for publicly visible type or member -dotnet_diagnostic.CS1591.severity = suggestion - # CS0162: Remove unreachable code dotnet_diagnostic.CS0162.severity = error # CA1018: Mark attributes with AttributeUsageAttribute diff --git a/samples/Directory.Build.props b/samples/Directory.Build.props index 9814914977..983bb034fc 100644 --- a/samples/Directory.Build.props +++ b/samples/Directory.Build.props @@ -4,6 +4,7 @@ false $(MSBuildThisFileDirectory)..\src\tools\Avalonia.Designer.HostApp\bin\Debug\$(AvsCurrentTargetFramework)\Avalonia.Designer.HostApp.dll false + false 14.0 $(NoWarn);CS8002 diff --git a/samples/GpuInterop/GpuInterop.csproj b/samples/GpuInterop/GpuInterop.csproj index ebf1d38a73..c05ccb875c 100644 --- a/samples/GpuInterop/GpuInterop.csproj +++ b/samples/GpuInterop/GpuInterop.csproj @@ -5,9 +5,14 @@ $(AvsCurrentTargetFramework) true enable - false true true + + + $(NoWarn);NU1510 diff --git a/samples/MiniMvvm/MiniCommand.cs b/samples/MiniMvvm/MiniCommand.cs index b39ceced3d..57f6d6b4d8 100644 --- a/samples/MiniMvvm/MiniCommand.cs +++ b/samples/MiniMvvm/MiniCommand.cs @@ -58,10 +58,10 @@ namespace MiniMvvm { public static MiniCommand Create(Action cb) => new MiniCommand(_ => cb()); public static MiniCommand Create(Action cb) => new MiniCommand(cb); - public static MiniCommand CreateFromTask(Func cb) => new MiniCommand(_ => cb()); + public static MiniCommand CreateFromTask(Func cb) => new MiniCommand(_ => cb()); - public abstract bool CanExecute(object parameter); - public abstract void Execute(object parameter); - public abstract event EventHandler CanExecuteChanged; + public abstract bool CanExecute(object? parameter); + public abstract void Execute(object? parameter); + public abstract event EventHandler? CanExecuteChanged; } } diff --git a/samples/MiniMvvm/PropertyChangedExtensions.cs b/samples/MiniMvvm/PropertyChangedExtensions.cs index f51773810d..cc551d61d1 100644 --- a/samples/MiniMvvm/PropertyChangedExtensions.cs +++ b/samples/MiniMvvm/PropertyChangedExtensions.cs @@ -31,13 +31,13 @@ namespace MiniMvvm _info = info; _observer = observer; _target.PropertyChanged += OnPropertyChanged; - _observer.OnNext((T)_info.GetValue(_target)); + _observer.OnNext((T)_info.GetValue(_target)!); } - private void OnPropertyChanged(object sender, PropertyChangedEventArgs e) + private void OnPropertyChanged(object? sender, PropertyChangedEventArgs e) { if (e.PropertyName == _info.Name) - _observer.OnNext((T)_info.GetValue(_target)); + _observer.OnNext((T)_info.GetValue(_target)!); } public void Dispose() diff --git a/samples/TextTestApp/InteractiveLineControl.cs b/samples/TextTestApp/InteractiveLineControl.cs index f4e26e1415..362be52ac3 100644 --- a/samples/TextTestApp/InteractiveLineControl.cs +++ b/samples/TextTestApp/InteractiveLineControl.cs @@ -233,6 +233,7 @@ namespace TextTestApp } private GenericTextRunProperties? _textRunProperties; + public GenericTextRunProperties TextRunProperties { get @@ -241,9 +242,6 @@ namespace TextTestApp } set { - if (value == null) - throw new ArgumentNullException(nameof(value)); - _textRunProperties = value; SetCurrentValue(FontFamilyProperty, value.Typeface.FontFamily); SetCurrentValue(FontFeaturesProperty, value.FontFeatures); diff --git a/samples/TextTestApp/MainWindow.axaml.cs b/samples/TextTestApp/MainWindow.axaml.cs index 493bc3e9d4..2bc6ac4160 100644 --- a/samples/TextTestApp/MainWindow.axaml.cs +++ b/samples/TextTestApp/MainWindow.axaml.cs @@ -320,11 +320,17 @@ namespace TextTestApp private void OnBufferSelectionChanged(object? sender, SelectionChangedEventArgs e) { - List rectangles = new List(_buffer.Selection.Count); + if (_selectionAdorner is null) + return; - foreach (var row in _buffer.SelectedItems) - if (row is Control { Tag: Rect rect }) - rectangles.Add(rect); + var rectangles = new List(_buffer.Selection.Count); + + if (_buffer.SelectedItems is { } selectedItems) + { + foreach (var row in selectedItems) + if (row is Control { Tag: Rect rect }) + rectangles.Add(rect); + } _selectionAdorner.Rectangles = rectangles; } diff --git a/src/Android/Avalonia.Android/Avalonia.Android.csproj b/src/Android/Avalonia.Android/Avalonia.Android.csproj index 97acf3d012..dc1b5cd7dd 100644 --- a/src/Android/Avalonia.Android/Avalonia.Android.csproj +++ b/src/Android/Avalonia.Android/Avalonia.Android.csproj @@ -4,6 +4,9 @@ $(AvsMinSupportedAndroidVersion) true Avalonia.Android.Internal + + + $(NoWarn);CS8002 diff --git a/src/Android/Avalonia.Android/ChoreographerTimer.cs b/src/Android/Avalonia.Android/ChoreographerTimer.cs index 4d1d1e1c20..adca9c72ce 100644 --- a/src/Android/Avalonia.Android/ChoreographerTimer.cs +++ b/src/Android/Avalonia.Android/ChoreographerTimer.cs @@ -13,7 +13,6 @@ namespace Avalonia.Android { internal sealed class ChoreographerTimer : IRenderTimer { - private static readonly bool s_supports64Callback = OperatingSystem.IsAndroidVersionAtLeast(29); private readonly object _lock = new(); private readonly TaskCompletionSource _choreographer = new(); private readonly AutoResetEvent _event = new(false); @@ -126,7 +125,7 @@ namespace Avalonia.Android private static unsafe void PostFrameCallback(IntPtr choreographer, IntPtr data) { // AChoreographer_postFrameCallback is deprecated on 10.0+. - if (s_supports64Callback) + if (OperatingSystem.IsAndroidVersionAtLeast(29)) { AChoreographer_postFrameCallback64(choreographer, &FrameCallback64, data); } diff --git a/src/Android/Avalonia.Android/Platform/Storage/AndroidStorageProvider.cs b/src/Android/Avalonia.Android/Platform/Storage/AndroidStorageProvider.cs index 69329ea85f..b42d0f7aaa 100644 --- a/src/Android/Avalonia.Android/Platform/Storage/AndroidStorageProvider.cs +++ b/src/Android/Avalonia.Android/Platform/Storage/AndroidStorageProvider.cs @@ -202,7 +202,7 @@ internal class AndroidStorageProvider : IStorageProvider public async Task SaveFilePickerWithResultAsync(FilePickerSaveOptions options) { var file = await SaveFilePickerAsync(options).ConfigureAwait(false); - return new SaveFilePickerResult(file); + return new SaveFilePickerResult { File = file }; } public async Task> OpenFolderPickerAsync(FolderPickerOpenOptions options) diff --git a/src/Avalonia.Base/Controls/NameScope.cs b/src/Avalonia.Base/Controls/NameScope.cs index e373f7e634..f4154525df 100644 --- a/src/Avalonia.Base/Controls/NameScope.cs +++ b/src/Avalonia.Base/Controls/NameScope.cs @@ -14,8 +14,8 @@ namespace Avalonia.Controls /// /// Defines the NameScope attached property. /// - public static readonly AttachedProperty NameScopeProperty = - AvaloniaProperty.RegisterAttached("NameScope"); + public static readonly AttachedProperty NameScopeProperty = + AvaloniaProperty.RegisterAttached("NameScope"); /// public bool IsCompleted { get; private set; } @@ -30,7 +30,7 @@ namespace Avalonia.Controls /// /// The styled element. /// The value of the NameScope attached property. - public static INameScope GetNameScope(StyledElement styled) + public static INameScope? GetNameScope(StyledElement styled) { _ = styled ?? throw new ArgumentNullException(nameof(styled)); @@ -42,7 +42,7 @@ namespace Avalonia.Controls /// /// The styled element. /// The value to set. - public static void SetNameScope(StyledElement styled, INameScope value) + public static void SetNameScope(StyledElement styled, INameScope? value) { _ = styled ?? throw new ArgumentNullException(nameof(styled)); diff --git a/src/Avalonia.Base/Media/PolylineGeometry.cs b/src/Avalonia.Base/Media/PolylineGeometry.cs index f9b9c24be9..53c84741d5 100644 --- a/src/Avalonia.Base/Media/PolylineGeometry.cs +++ b/src/Avalonia.Base/Media/PolylineGeometry.cs @@ -44,7 +44,6 @@ namespace Avalonia.Media _fillRule = FillRule.EvenOdd; } - /// /// /// Initializes a new instance of the class. /// diff --git a/src/Avalonia.Base/Media/TextFormatting/TextParagraphProperties.cs b/src/Avalonia.Base/Media/TextFormatting/TextParagraphProperties.cs index cde63c02a6..b25daeb826 100644 --- a/src/Avalonia.Base/Media/TextFormatting/TextParagraphProperties.cs +++ b/src/Avalonia.Base/Media/TextFormatting/TextParagraphProperties.cs @@ -53,7 +53,7 @@ /// /// If not null, text decorations to apply to all runs in the line. This is in addition /// to any text decorations specified by the TextRunProperties for individual text runs. - /// + /// public virtual TextDecorationCollection? TextDecorations => null; /// diff --git a/src/Avalonia.Base/Media/TextPathSegmentEllipsis.cs b/src/Avalonia.Base/Media/TextPathSegmentEllipsis.cs index b3e4189ff9..700f861d4d 100644 --- a/src/Avalonia.Base/Media/TextPathSegmentEllipsis.cs +++ b/src/Avalonia.Base/Media/TextPathSegmentEllipsis.cs @@ -415,12 +415,6 @@ namespace Avalonia.Media return false; } - /// - /// Finds the index of the text run and the offset within that run corresponding to the specified character - /// index. - /// - /// If the specified character index does not fall within any run, the method returns - /// /// Calculates the total width of a specified segment within a sequence of text runs. /// diff --git a/src/Avalonia.Base/Platform/Storage/FilePickerOpenOptions.cs b/src/Avalonia.Base/Platform/Storage/FilePickerOpenOptions.cs index cbbd68d2d5..f96f3408e6 100644 --- a/src/Avalonia.Base/Platform/Storage/FilePickerOpenOptions.cs +++ b/src/Avalonia.Base/Platform/Storage/FilePickerOpenOptions.cs @@ -11,8 +11,8 @@ public class FilePickerOpenOptions : PickerOptions /// Gets or sets the file type that should be preselected when the dialog is opened. /// /// - /// This value should reference one of the items in . - /// If not set, the first file type in may be selected by default. + /// This value should reference one of the items in . + /// If not set, the first file type in may be selected by default. /// public FilePickerFileType? SuggestedFileType { get; set; } diff --git a/src/Avalonia.Base/Platform/Storage/NoopStorageProvider.cs b/src/Avalonia.Base/Platform/Storage/NoopStorageProvider.cs index 2488b58b30..4b056d104e 100644 --- a/src/Avalonia.Base/Platform/Storage/NoopStorageProvider.cs +++ b/src/Avalonia.Base/Platform/Storage/NoopStorageProvider.cs @@ -21,7 +21,7 @@ internal class NoopStorageProvider : BclStorageProvider public override Task SaveFilePickerWithResultAsync(FilePickerSaveOptions options) { - return Task.FromResult(new SaveFilePickerResult(null)); + return Task.FromResult(new SaveFilePickerResult()); } public override bool CanPickFolder => false; diff --git a/src/Avalonia.Base/Platform/Storage/SaveFilePickerResult.cs b/src/Avalonia.Base/Platform/Storage/SaveFilePickerResult.cs index e150fcd17b..222b4a4dbc 100644 --- a/src/Avalonia.Base/Platform/Storage/SaveFilePickerResult.cs +++ b/src/Avalonia.Base/Platform/Storage/SaveFilePickerResult.cs @@ -3,13 +3,8 @@ namespace Avalonia.Platform.Storage; /// /// Extended result of the operation. /// -public readonly struct SaveFilePickerResult +public readonly record struct SaveFilePickerResult { - internal SaveFilePickerResult(IStorageFile? file) - { - File = file; - } - /// /// Saved or null if user canceled the dialog. /// diff --git a/src/Avalonia.Base/Rendering/Composition/CompositionDrawingSurface.cs b/src/Avalonia.Base/Rendering/Composition/CompositionDrawingSurface.cs index 6d8562bb4a..0df5003458 100644 --- a/src/Avalonia.Base/Rendering/Composition/CompositionDrawingSurface.cs +++ b/src/Avalonia.Base/Rendering/Composition/CompositionDrawingSurface.cs @@ -41,13 +41,15 @@ public sealed class CompositionDrawingSurface : CompositionSurface, IDisposable var signal = (CompositionImportedGpuSemaphore)signalSemaphore; return Compositor.InvokeServerJobAsync(() => Server.UpdateWithSemaphores(img, wait, signal)); } - + /// /// Updates the surface contents using an imported memory image using a semaphore pair as the means of synchronization /// /// GPU image with new surface contents /// The semaphore to wait for before accessing the image + /// The value to wait for before accessing the image /// The semaphore to signal after accessing the image + /// The value to signal after accessing the image /// A task that completes when update operation is completed and user code is free to destroy or dispose the image public Task UpdateWithTimelineSemaphoresAsync(ICompositionImportedGpuImage image, ICompositionImportedGpuSemaphore waitForSemaphore, ulong waitForValue, diff --git a/src/Avalonia.Base/Styling/Selector.cs b/src/Avalonia.Base/Styling/Selector.cs index 9102d2e770..6e0a8a08b0 100644 --- a/src/Avalonia.Base/Styling/Selector.cs +++ b/src/Avalonia.Base/Styling/Selector.cs @@ -76,7 +76,11 @@ namespace Avalonia.Styling /// The owner style. public abstract string ToString(Style? owner); - /// + /// + /// Gets a string representing the selector, with the nesting separator (`^`) replaced with + /// the parent selector. + /// + /// The owner style. /// Whether there is a selector that comes after this one. internal virtual string ToString(Style? owner, bool hasNext) => ToString(owner); diff --git a/src/Avalonia.Base/Threading/DispatcherPriorityAwaitable.cs b/src/Avalonia.Base/Threading/DispatcherPriorityAwaitable.cs index ab4fb38b5a..700e1f5c22 100644 --- a/src/Avalonia.Base/Threading/DispatcherPriorityAwaitable.cs +++ b/src/Avalonia.Base/Threading/DispatcherPriorityAwaitable.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; @@ -8,6 +9,10 @@ namespace Avalonia.Threading; /// /// A simple awaitable type that will return a DispatcherPriorityAwaiter. /// +[UnconditionalSuppressMessage( + "Performance", + "CA1815:Override equals and operator equals on value types", + Justification = "This struct is not supposed to be used directly and should not be compared.")] public struct DispatcherPriorityAwaitable { private readonly Dispatcher _dispatcher; @@ -30,6 +35,10 @@ public struct DispatcherPriorityAwaitable /// /// This is returned from DispatcherPriorityAwaitable.GetAwaiter() /// +[UnconditionalSuppressMessage( + "Performance", + "CA1815:Override equals and operator equals on value types", + Justification = "This struct is not supposed to be used directly and should not be compared.")] public struct DispatcherPriorityAwaiter : INotifyCompletion { private readonly Dispatcher _dispatcher; @@ -72,6 +81,10 @@ public struct DispatcherPriorityAwaiter : INotifyCompletion /// /// A simple awaitable type that will return a DispatcherPriorityAwaiter<T>. /// +[UnconditionalSuppressMessage( + "Performance", + "CA1815:Override equals and operator equals on value types", + Justification = "This struct is not supposed to be used directly and should not be compared.")] public struct DispatcherPriorityAwaitable { private readonly Dispatcher _dispatcher; @@ -94,6 +107,10 @@ public struct DispatcherPriorityAwaitable /// /// This is returned from DispatcherPriorityAwaitable<T>.GetAwaiter() /// +[UnconditionalSuppressMessage( + "Performance", + "CA1815:Override equals and operator equals on value types", + Justification = "This struct is not supposed to be used directly and should not be compared.")] public struct DispatcherPriorityAwaiter : INotifyCompletion { private readonly Dispatcher _dispatcher; @@ -127,4 +144,4 @@ public struct DispatcherPriorityAwaiter : INotifyCompletion public bool IsCompleted => false; public void GetResult() => _task.GetAwaiter().GetResult(); -} \ No newline at end of file +} diff --git a/src/Avalonia.Controls/TextBlock.cs b/src/Avalonia.Controls/TextBlock.cs index c21b8c7cdc..55cbae773c 100644 --- a/src/Avalonia.Controls/TextBlock.cs +++ b/src/Avalonia.Controls/TextBlock.cs @@ -97,11 +97,6 @@ namespace Avalonia.Controls /// /// Defines the property. /// - /// - /// This property uses to share the same - /// definition as , ensuring consistent behavior across text - /// elements and templated controls. - /// public static readonly StyledProperty LetterSpacingProperty = TextElement.LetterSpacingProperty.AddOwner(); diff --git a/src/Avalonia.DesignerSupport/Remote/Stubs.cs b/src/Avalonia.DesignerSupport/Remote/Stubs.cs index 4be5e1aee9..a352b414fe 100644 --- a/src/Avalonia.DesignerSupport/Remote/Stubs.cs +++ b/src/Avalonia.DesignerSupport/Remote/Stubs.cs @@ -309,7 +309,7 @@ namespace Avalonia.DesignerSupport.Remote public override Task SaveFilePickerWithResultAsync(FilePickerSaveOptions options) { - return Task.FromResult(new SaveFilePickerResult(null)); + return Task.FromResult(new SaveFilePickerResult()); } public override bool CanPickFolder => false; diff --git a/src/Avalonia.Dialogs/ManagedStorageProvider.cs b/src/Avalonia.Dialogs/ManagedStorageProvider.cs index 38aefdd331..58edc32224 100644 --- a/src/Avalonia.Dialogs/ManagedStorageProvider.cs +++ b/src/Avalonia.Dialogs/ManagedStorageProvider.cs @@ -56,7 +56,7 @@ internal class ManagedStorageProvider : BclStorageProvider options.FileTypeChoices[index] : null; - return new SaveFilePickerResult(file) { SelectedFileType = filterType }; + return new SaveFilePickerResult { File = file, SelectedFileType = filterType }; } public override async Task> OpenFolderPickerAsync(FolderPickerOpenOptions options) diff --git a/src/Avalonia.FreeDesktop/DBusSystemDialog.cs b/src/Avalonia.FreeDesktop/DBusSystemDialog.cs index fd4f351302..b3b449cfd5 100644 --- a/src/Avalonia.FreeDesktop/DBusSystemDialog.cs +++ b/src/Avalonia.FreeDesktop/DBusSystemDialog.cs @@ -102,7 +102,7 @@ namespace Avalonia.FreeDesktop public override async Task SaveFilePickerWithResultAsync(FilePickerSaveOptions options) { var (file, selectedType) = await SaveFilePickerCoreAsync(options).ConfigureAwait(false); - return new SaveFilePickerResult(file) { SelectedFileType = selectedType }; + return new SaveFilePickerResult { File = file, SelectedFileType = selectedType }; } private async Task<(IStorageFile? file, FilePickerFileType? selectedType)> SaveFilePickerCoreAsync( diff --git a/src/Avalonia.Native/GpuHandleWrapFeature.cs b/src/Avalonia.Native/GpuHandleWrapFeature.cs index feb394f460..b490e6c9c1 100644 --- a/src/Avalonia.Native/GpuHandleWrapFeature.cs +++ b/src/Avalonia.Native/GpuHandleWrapFeature.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; using Avalonia.Native.Interop; using Avalonia.Platform; diff --git a/src/Avalonia.Native/StorageProviderImpl.cs b/src/Avalonia.Native/StorageProviderImpl.cs index 9703af99c8..e6e1fd7257 100644 --- a/src/Avalonia.Native/StorageProviderImpl.cs +++ b/src/Avalonia.Native/StorageProviderImpl.cs @@ -30,7 +30,7 @@ internal sealed class StorageProviderImpl(TopLevelImpl topLevel, StorageProvider public async Task SaveFilePickerWithResultAsync(FilePickerSaveOptions options) { var (file, selectedType) = await native.SaveFileDialog(topLevel, options).ConfigureAwait(false); - return new SaveFilePickerResult(file) { SelectedFileType = selectedType }; + return new SaveFilePickerResult { File = file, SelectedFileType = selectedType }; } public Task> OpenFolderPickerAsync(FolderPickerOpenOptions options) diff --git a/src/Avalonia.X11/NativeDialogs/GtkNativeFileDialogs.cs b/src/Avalonia.X11/NativeDialogs/GtkNativeFileDialogs.cs index 05a3c52c54..f70525b819 100644 --- a/src/Avalonia.X11/NativeDialogs/GtkNativeFileDialogs.cs +++ b/src/Avalonia.X11/NativeDialogs/GtkNativeFileDialogs.cs @@ -86,7 +86,7 @@ namespace Avalonia.X11.NativeDialogs ? new BclStorageFile(new FileInfo(path)) : null; - return new SaveFilePickerResult(file) { SelectedFileType = selectedFilter }; + return new SaveFilePickerResult { File = file, SelectedFileType = selectedFilter }; }); } diff --git a/src/Browser/Avalonia.Browser/Storage/BrowserStorageProvider.cs b/src/Browser/Avalonia.Browser/Storage/BrowserStorageProvider.cs index 0a3e298617..957642bfad 100644 --- a/src/Browser/Avalonia.Browser/Storage/BrowserStorageProvider.cs +++ b/src/Browser/Avalonia.Browser/Storage/BrowserStorageProvider.cs @@ -93,7 +93,7 @@ internal class BrowserStorageProvider : IStorageProvider public async Task SaveFilePickerWithResultAsync(FilePickerSaveOptions options) { var file = await SaveFilePickerAsync(options).ConfigureAwait(false); - return new SaveFilePickerResult(file); + return new SaveFilePickerResult { File = file }; } public async Task> OpenFolderPickerAsync(FolderPickerOpenOptions options) diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/Avalonia.Markup.Xaml.Loader.csproj b/src/Markup/Avalonia.Markup.Xaml.Loader/Avalonia.Markup.Xaml.Loader.csproj index 13f13ec9e5..0b63776370 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/Avalonia.Markup.Xaml.Loader.csproj +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/Avalonia.Markup.Xaml.Loader.csproj @@ -11,10 +11,6 @@ - - - - diff --git a/src/Windows/Avalonia.Win32/Win32StorageProvider.cs b/src/Windows/Avalonia.Win32/Win32StorageProvider.cs index ba5ffeab8b..a61af0de97 100644 --- a/src/Windows/Avalonia.Win32/Win32StorageProvider.cs +++ b/src/Windows/Avalonia.Win32/Win32StorageProvider.cs @@ -79,7 +79,7 @@ namespace Avalonia.Win32 options.FileTypeChoices[index - 1] : null; - return new SaveFilePickerResult(file) { SelectedFileType = selectedFileType }; + return new SaveFilePickerResult { File = file, SelectedFileType = selectedFileType }; } private unsafe Task<(IReadOnlyList items, int typeIndex)> ShowFilePicker( diff --git a/src/iOS/Avalonia.iOS/Storage/IOSStorageProvider.cs b/src/iOS/Avalonia.iOS/Storage/IOSStorageProvider.cs index 2b0cef4395..a4d993d540 100644 --- a/src/iOS/Avalonia.iOS/Storage/IOSStorageProvider.cs +++ b/src/iOS/Avalonia.iOS/Storage/IOSStorageProvider.cs @@ -232,7 +232,7 @@ internal class IOSStorageProvider : IStorageProvider public async Task SaveFilePickerWithResultAsync(FilePickerSaveOptions options) { var file = await SaveFilePickerAsync(options).ConfigureAwait(false); - return new SaveFilePickerResult(file); + return new SaveFilePickerResult { File = file }; } public async Task> OpenFolderPickerAsync(FolderPickerOpenOptions options) diff --git a/tests/Avalonia.Base.UnitTests/Input/PointerTestsBase.cs b/tests/Avalonia.Base.UnitTests/Input/PointerTestsBase.cs index 659ed1aaf1..02c67c5896 100644 --- a/tests/Avalonia.Base.UnitTests/Input/PointerTestsBase.cs +++ b/tests/Avalonia.Base.UnitTests/Input/PointerTestsBase.cs @@ -49,7 +49,7 @@ public abstract class PointerTestsBase : ScopedTestBase impl.DefaultValue = DefaultValue.Mock; impl.SetupAllProperties(); impl.SetupGet(r => r.RenderScaling).Returns(1); - impl.Setup(r => r.TryGetFeature(It.IsAny())).Returns(null); + impl.Setup(r => r.TryGetFeature(It.IsAny())).Returns((object?)null); impl.Setup(r => r.Compositor).Returns(RendererMocks.CreateDummyCompositor()); impl.Setup(r => r.PointToScreen(It.IsAny())).Returns(p => new PixelPoint((int)p.X, (int)p.Y)); impl.Setup(r => r.PointToClient(It.IsAny())).Returns(p => new Point(p.X, p.Y)); diff --git a/tests/Avalonia.Build.Tasks.UnitTest/CompileAvaloniaXamlTaskTest.cs b/tests/Avalonia.Build.Tasks.UnitTest/CompileAvaloniaXamlTaskTest.cs index c2a4b8f44e..2c1daf2e19 100644 --- a/tests/Avalonia.Build.Tasks.UnitTest/CompileAvaloniaXamlTaskTest.cs +++ b/tests/Avalonia.Build.Tasks.UnitTest/CompileAvaloniaXamlTaskTest.cs @@ -14,7 +14,7 @@ public class CompileAvaloniaXamlTaskTest public void Does_Not_Fail_When_Codebehind_Contains_DllImport() { using var engine = UnitTestBuildEngine.Start(); - var basePath = Path.Combine(Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath), "Assets"); + var basePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!, "Assets"); var assembly = new TaskItem(Path.Combine(basePath, "PInvoke.dll")); assembly.SetMetadata(CompileAvaloniaXamlTask.AvaloniaCompileOutputMetadataName, Path.Combine(basePath, "Avalonia", Path.GetFileName(assembly.ItemSpec))); var references = File.ReadAllLines(Path.Combine(basePath, "PInvoke.dll.refs")).Select(p => new TaskItem(p)).ToArray(); diff --git a/tests/Avalonia.Controls.UnitTests/GridSplitterTests.cs b/tests/Avalonia.Controls.UnitTests/GridSplitterTests.cs index c0974ea97b..5b57844cab 100644 --- a/tests/Avalonia.Controls.UnitTests/GridSplitterTests.cs +++ b/tests/Avalonia.Controls.UnitTests/GridSplitterTests.cs @@ -1,3 +1,5 @@ +#nullable enable + using System.Collections.Generic; using Avalonia.Controls.Presenters; using Avalonia.Controls.Primitives; diff --git a/tests/Avalonia.Controls.UnitTests/Platform/ScreensTests.cs b/tests/Avalonia.Controls.UnitTests/Platform/ScreensTests.cs index c389106de5..081b9e0611 100644 --- a/tests/Avalonia.Controls.UnitTests/Platform/ScreensTests.cs +++ b/tests/Avalonia.Controls.UnitTests/Platform/ScreensTests.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Threading.Tasks; using Avalonia.Platform; using Avalonia.Threading; @@ -102,6 +103,7 @@ public class ScreensTests : ScopedTestBase } [Fact] + [UnconditionalSuppressMessage("Usage", "xUnit1031:Do not use blocking task operations in test method", Justification = "Explicit threading test")] public void Should_Raise_Event_When_Screen_Changed_From_Another_Thread() { using var _ = UnitTestApplication.Start(TestServices.MockThreadingInterface); diff --git a/tests/Avalonia.Controls.UnitTests/Shapes/ShapeTests.cs b/tests/Avalonia.Controls.UnitTests/Shapes/ShapeTests.cs index 9aa1e1ac36..ac5dded8fc 100644 --- a/tests/Avalonia.Controls.UnitTests/Shapes/ShapeTests.cs +++ b/tests/Avalonia.Controls.UnitTests/Shapes/ShapeTests.cs @@ -1,3 +1,5 @@ +#nullable enable + using Avalonia.Collections; using Avalonia.Controls.Shapes; using Avalonia.Media; @@ -22,7 +24,7 @@ public class ShapeTests : ScopedTestBase }); Assert.NotNull(pen); - Assert.Equal(10, pen!.MiterLimit); + Assert.Equal(10, pen.MiterLimit); } [Fact] @@ -40,7 +42,7 @@ public class ShapeTests : ScopedTestBase var pen = RenderAndGetPen(shape); Assert.NotNull(pen); - Assert.Equal(2, pen!.MiterLimit); + Assert.Equal(2, pen.MiterLimit); } [Fact] @@ -54,7 +56,7 @@ public class ShapeTests : ScopedTestBase }); Assert.NotNull(pen); - Assert.Equal(6, pen!.Thickness); + Assert.Equal(6, pen.Thickness); } [Fact] @@ -70,7 +72,7 @@ public class ShapeTests : ScopedTestBase }); Assert.NotNull(pen); - Assert.Equal(PenLineCap.Round, pen!.LineCap); + Assert.Equal(PenLineCap.Round, pen.LineCap); Assert.Equal(PenLineJoin.Bevel, pen.LineJoin); } @@ -87,8 +89,8 @@ public class ShapeTests : ScopedTestBase }); Assert.NotNull(pen); - Assert.NotNull(pen!.DashStyle); - Assert.Equal(3, pen.DashStyle!.Dashes.Count); + Assert.NotNull(pen.DashStyle); + Assert.Equal(3, pen.DashStyle!.Dashes!.Count); Assert.Equal(1, pen.DashStyle.Dashes[0]); Assert.Equal(2, pen.DashStyle.Dashes[1]); Assert.Equal(3, pen.DashStyle.Dashes[2]); @@ -117,7 +119,7 @@ public class ShapeTests : ScopedTestBase private class TestShape : Shape { - protected override Geometry? CreateDefiningGeometry() => + protected override Geometry CreateDefiningGeometry() => new RectangleGeometry(new Rect(0, 0, 20, 20)); } diff --git a/tests/Avalonia.Controls.UnitTests/ToolTipTests.cs b/tests/Avalonia.Controls.UnitTests/ToolTipTests.cs index 7729d33d47..6c9eca6680 100644 --- a/tests/Avalonia.Controls.UnitTests/ToolTipTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ToolTipTests.cs @@ -42,9 +42,10 @@ namespace Avalonia.Controls.UnitTests })); } - public void Dispose() + public override void Dispose() { _toolTipOpenSubscription.Dispose(); + base.Dispose(); } protected override TestServices ConfigureServices(TestServices baseServices) => diff --git a/tests/Avalonia.Headless.UnitTests/IsolationTests.cs b/tests/Avalonia.Headless.UnitTests/IsolationTests.cs index 114b24ce92..1f3495a194 100644 --- a/tests/Avalonia.Headless.UnitTests/IsolationTests.cs +++ b/tests/Avalonia.Headless.UnitTests/IsolationTests.cs @@ -15,6 +15,10 @@ public class IsolationTests #elif XUNIT [AvaloniaTheory] [InlineData(1), InlineData(2), InlineData(3)] + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage( + "Usage", + "xUnit1026:Theory methods should use all of their parameters", + Justification = "Used to run the test several times with the proper isolation level")] #endif public void Application_Instance_Should_Match_Isolation_Level(int runIndex) { diff --git a/tests/Avalonia.IntegrationTests.Appium/Avalonia.IntegrationTests.Appium.csproj b/tests/Avalonia.IntegrationTests.Appium/Avalonia.IntegrationTests.Appium.csproj index 16dcc6445a..4ef730e426 100644 --- a/tests/Avalonia.IntegrationTests.Appium/Avalonia.IntegrationTests.Appium.csproj +++ b/tests/Avalonia.IntegrationTests.Appium/Avalonia.IntegrationTests.Appium.csproj @@ -7,6 +7,12 @@ false $(DefineConstants);APPIUM1 $(DefineConstants);APPIUM2 + + + $(NoWarn);NU1510 diff --git a/tests/Avalonia.LeakTests/AvaloniaObjectTests.cs b/tests/Avalonia.LeakTests/AvaloniaObjectTests.cs index ecaca2db07..3770f77886 100644 --- a/tests/Avalonia.LeakTests/AvaloniaObjectTests.cs +++ b/tests/Avalonia.LeakTests/AvaloniaObjectTests.cs @@ -54,7 +54,7 @@ namespace Avalonia.LeakTests Action completeSource = () => { - ((ISubject)weakSource.Target).OnCompleted(); + ((ISubject)weakSource.Target!).OnCompleted(); }; completeSource(); diff --git a/tests/Avalonia.LeakTests/ControlTests.cs b/tests/Avalonia.LeakTests/ControlTests.cs index 47d8417bd6..99707b54ce 100644 --- a/tests/Avalonia.LeakTests/ControlTests.cs +++ b/tests/Avalonia.LeakTests/ControlTests.cs @@ -294,7 +294,7 @@ namespace Avalonia.LeakTests { new FuncTreeDataTemplate( (x, _) => new TextBlock { Text = x.Name }, - x => x.Children) + x => x.Children ?? []) }, ItemsSource = nodes } @@ -409,7 +409,7 @@ namespace Avalonia.LeakTests screens.Setup(x => x.ScreenFromWindow(It.IsAny())).Returns(screen1.Object); var impl = new Mock(); - impl.Setup(r => r.TryGetFeature(It.IsAny())).Returns(null); + impl.Setup(r => r.TryGetFeature(It.IsAny())).Returns((object?)null); impl.SetupGet(x => x.RenderScaling).Returns(1); impl.SetupProperty(x => x.Closed); impl.Setup(x => x.Compositor).Returns(RendererMocks.CreateDummyCompositor()); @@ -516,7 +516,7 @@ namespace Avalonia.LeakTests Assert.True(weakMenuItem2.IsAlive); Assert.True(weakContextMenu.IsAlive); - Mock.Get(window.PlatformImpl).Invocations.Clear(); + Mock.Get(window.PlatformImpl!).Invocations.Clear(); CollectGarbage(); Assert.False(weakMenuItem1.IsAlive); @@ -605,7 +605,7 @@ namespace Avalonia.LeakTests Assert.True(weakMenuItem4.IsAlive); Assert.True(weakContextMenu2.IsAlive); - Mock.Get(window.PlatformImpl).Invocations.Clear(); + Mock.Get(window.PlatformImpl!).Invocations.Clear(); CollectGarbage(); Assert.False(weakMenuItem1.IsAlive); @@ -930,7 +930,7 @@ namespace Avalonia.LeakTests window.Content = null; // Mock keep reference on a Popup via InvocationsCollection. So let's clear it before. - Mock.Get(window.PlatformImpl).Invocations.Clear(); + Mock.Get(window.PlatformImpl!).Invocations.Clear(); return (new WeakReference(toolTip), new WeakReference(textBlock)); } @@ -984,7 +984,7 @@ namespace Avalonia.LeakTests window.Content = null; // Mock keep reference on a Popup via InvocationsCollection. So let's clear it before. - Mock.Get(window.PlatformImpl).Invocations.Clear(); + Mock.Get(window.PlatformImpl!).Invocations.Clear(); return (new WeakReference(flyout), new WeakReference(textBlock)); } @@ -1093,8 +1093,8 @@ namespace Avalonia.LeakTests private class Node { - public string Name { get; set; } - public IEnumerable Children { get; set; } + public string? Name { get; set; } + public IEnumerable? Children { get; set; } } } diff --git a/tests/Avalonia.Markup.UnitTests/Data/BindingTests_Delay.cs b/tests/Avalonia.Markup.UnitTests/Data/BindingTests_Delay.cs index d225ff2b73..a73fbd7bb4 100644 --- a/tests/Avalonia.Markup.UnitTests/Data/BindingTests_Delay.cs +++ b/tests/Avalonia.Markup.UnitTests/Data/BindingTests_Delay.cs @@ -36,7 +36,7 @@ public class BindingTests_Delay : ScopedTestBase, IDisposable Assert.Equal(_source.Foo, _target.Text); } - public void Dispose() + public override void Dispose() { _app.Dispose(); base.Dispose(); diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs index a263f6126a..9efc243f40 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs @@ -2520,7 +2520,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions public class NestedGeneric { - public T Value { get; set; } + public T? Value { get; set; } } } diff --git a/tests/Avalonia.RenderTests/CrossTests/Media/ImageScalingTests.cs b/tests/Avalonia.RenderTests/CrossTests/Media/ImageScalingTests.cs index a635227f44..192e6cd260 100644 --- a/tests/Avalonia.RenderTests/CrossTests/Media/ImageScalingTests.cs +++ b/tests/Avalonia.RenderTests/CrossTests/Media/ImageScalingTests.cs @@ -1,3 +1,5 @@ +#nullable enable + using System.IO; using System.Runtime.CompilerServices; using Avalonia.Media.Imaging; diff --git a/tests/Avalonia.Skia.UnitTests/Media/CustomFontManagerImpl.cs b/tests/Avalonia.Skia.UnitTests/Media/CustomFontManagerImpl.cs index 008f1eedbd..c240dacf9e 100644 --- a/tests/Avalonia.Skia.UnitTests/Media/CustomFontManagerImpl.cs +++ b/tests/Avalonia.Skia.UnitTests/Media/CustomFontManagerImpl.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; using System.Collections.Generic; using System.Globalization; using System.Linq; @@ -96,7 +98,7 @@ namespace Avalonia.Skia.UnitTests.Media } public bool TryCreateGlyphTypeface(string familyName, FontStyle style, FontWeight weight, - FontStretch stretch, [NotNullWhen(true)] out IGlyphTypeface glyphTypeface) + FontStretch stretch, [NotNullWhen(true)] out IGlyphTypeface? glyphTypeface) { if (SystemFonts.TryGetGlyphTypeface(familyName, style, weight, stretch, out glyphTypeface)) { @@ -111,7 +113,7 @@ namespace Avalonia.Skia.UnitTests.Media return true; } - public bool TryCreateGlyphTypeface(Stream stream, FontSimulations fontSimulations, [NotNullWhen(true)] out IGlyphTypeface glyphTypeface) + public bool TryCreateGlyphTypeface(Stream stream, FontSimulations fontSimulations, [NotNullWhen(true)] out IGlyphTypeface? glyphTypeface) { var skTypeface = SKTypeface.FromStream(stream); diff --git a/tests/Avalonia.UnitTests/HarfBuzzFontManagerImpl.cs b/tests/Avalonia.UnitTests/HarfBuzzFontManagerImpl.cs index 7ca32e2d3b..d96c7e7a42 100644 --- a/tests/Avalonia.UnitTests/HarfBuzzFontManagerImpl.cs +++ b/tests/Avalonia.UnitTests/HarfBuzzFontManagerImpl.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; @@ -33,7 +35,7 @@ namespace Avalonia.UnitTests string[] IFontManagerImpl.GetInstalledFontFamilyNames(bool checkForUpdates) { - return _customTypefaces.Select(x => x.FontFamily!.Name).ToArray(); + return _customTypefaces.Select(x => x.FontFamily.Name).ToArray(); } public bool TryMatchCharacter(int codepoint, FontStyle fontStyle, FontWeight fontWeight, @@ -66,7 +68,7 @@ namespace Avalonia.UnitTests } public bool TryCreateGlyphTypeface(string familyName, FontStyle style, FontWeight weight, - FontStretch stretch, [NotNullWhen(true)] out IGlyphTypeface glyphTypeface) + FontStretch stretch, [NotNullWhen(true)] out IGlyphTypeface? glyphTypeface) { glyphTypeface = null; diff --git a/tests/Avalonia.UnitTests/TestRoot.cs b/tests/Avalonia.UnitTests/TestRoot.cs index 49baeb87c7..2e5a05f47d 100644 --- a/tests/Avalonia.UnitTests/TestRoot.cs +++ b/tests/Avalonia.UnitTests/TestRoot.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; using System.Collections.Generic; using Avalonia.Controls; @@ -28,17 +30,17 @@ namespace Avalonia.UnitTests class NullHitTester : IHitTester { - public IEnumerable HitTest(Point p, Visual root, Func filter) => Array.Empty(); + public IEnumerable HitTest(Point p, Visual root, Func? filter) => Array.Empty(); - public Visual HitTestFirst(Point p, Visual root, Func filter) => null; + public Visual? HitTestFirst(Point p, Visual root, Func? filter) => null; } - public TestRoot(Control child) + public TestRoot(Control? child) : this(false, child) { } - public TestRoot(bool useGlobalStyles, Control child) + public TestRoot(bool useGlobalStyles, Control? child) : this() { if (useGlobalStyles) @@ -63,17 +65,17 @@ namespace Avalonia.UnitTests IRenderer IRenderRoot.Renderer => Renderer; IHitTester IRenderRoot.HitTester => HitTester; - public IKeyboardNavigationHandler KeyboardNavigationHandler => null; + public IKeyboardNavigationHandler? KeyboardNavigationHandler => null; public IFocusManager FocusManager => _focusManager ??= new FocusManager(this); - public IPlatformSettings PlatformSettings => AvaloniaLocator.Current.GetService(); + public IPlatformSettings? PlatformSettings => AvaloniaLocator.Current.GetService(); - public IInputElement PointerOverElement { get; set; } + public IInputElement? PointerOverElement { get; set; } public bool ShowAccessKeys { get; set; } - public IStyleHost StylingParent { get; set; } + public IStyleHost? StylingParent { get; set; } - IStyleHost IStyleHost.StylingParent => StylingParent; + IStyleHost? IStyleHost.StylingParent => StylingParent; public IRenderTarget CreateRenderTarget() { diff --git a/tests/Avalonia.UnitTests/ThreadRunHelper.cs b/tests/Avalonia.UnitTests/ThreadRunHelper.cs index d1391581c9..ba88c1c9e6 100644 --- a/tests/Avalonia.UnitTests/ThreadRunHelper.cs +++ b/tests/Avalonia.UnitTests/ThreadRunHelper.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; using System.Threading; using System.Threading.Tasks; @@ -31,4 +33,4 @@ public class ThreadRunHelper }); public static void RunOnDedicatedThreadAndWait(Action cb) => RunOnDedicatedThread(cb).GetAwaiter().GetResult(); -} \ No newline at end of file +} diff --git a/tests/Directory.Build.props b/tests/Directory.Build.props index 52af0f5ab2..5e8f5a6508 100644 --- a/tests/Directory.Build.props +++ b/tests/Directory.Build.props @@ -2,5 +2,6 @@ false + false