Browse Source

Merge branch 'master' into x11-mate-clipboard

pull/12002/head
Vitaliy Orazov 3 years ago
parent
commit
57f4087ef6
  1. 28
      .nuke/build.schema.json
  2. 31
      Documentation/build.md
  3. 64
      api/Avalonia.Controls.ColorPicker.nupkg.xml
  4. 418
      api/Avalonia.Themes.Fluent.nupkg.xml
  5. 406
      api/Avalonia.Themes.Simple.nupkg.xml
  6. 153
      nukebuild/ApiDiffValidation.cs
  7. 19
      nukebuild/Build.cs
  8. 22
      nukebuild/BuildParameters.cs
  9. 4
      nukebuild/Shims.cs
  10. 2
      nukebuild/_build.csproj
  11. 6
      readme.md
  12. 5
      samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml
  13. 4
      samples/ControlCatalog/Pages/DataGridPage.xaml
  14. 5
      src/Avalonia.Base/Interactivity/EventRoute.cs
  15. 2
      src/Avalonia.Base/Platform/Storage/PickerOptions.cs
  16. 3
      src/Avalonia.Base/Rendering/Composition/CompositionExternalMemory.cs
  17. 6
      src/Avalonia.Base/Rendering/Composition/CompositionInterop.cs
  18. 21
      src/Avalonia.Base/Rendering/Composition/Drawing/ServerCompositionRenderData.cs
  19. 6
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionDrawingSurface.cs
  20. 8
      src/Avalonia.Base/Threading/Dispatcher.Invoke.cs
  21. 4
      src/Avalonia.Base/Threading/DispatcherTimer.cs
  22. 16
      src/Avalonia.Base/Utilities/SmallDictionary.cs
  23. 39
      src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs
  24. 2
      src/Avalonia.Controls.DataGrid/DataGridCheckBoxColumn.cs
  25. 2
      src/Avalonia.Controls.DataGrid/DataGridColumnCollection.cs
  26. 2
      src/Avalonia.Controls.DataGrid/DataGridLength.cs
  27. 11
      src/Avalonia.Controls/AutoCompleteBox/AutoCompleteBox.cs
  28. 2
      src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs
  29. 3
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/EventTreeNode.cs
  30. 5
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/FiredEvent.cs
  31. 10
      src/Avalonia.Diagnostics/Diagnostics/Views/EventsPageView.xaml
  32. 23
      src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaXamlIlRuntimeCompiler.cs
  33. 6
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompiler.cs
  34. 20
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/GroupTransformers/XamlMergeResourceGroupTransformer.cs
  35. 4
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/IXamlDocumentResource.cs
  36. 34
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlDocumentResource.cs
  37. 23
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlDocumentTypeBuilderProvider.cs
  38. 8
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlDocumentUsage.cs
  39. 16
      src/Windows/Avalonia.Win32/OpenGl/WglDisplay.cs
  40. 4
      src/Windows/Avalonia.Win32/Win32GlManager.cs
  41. 8
      src/tools/Avalonia.Generators/NameGenerator/AvaloniaNameGenerator.cs
  42. 15
      src/tools/Avalonia.Generators/NameGenerator/AvaloniaNameSourceGenerator.cs
  43. 3
      src/tools/Avalonia.Generators/NameGenerator/INameGenerator.cs
  44. 53
      tests/Avalonia.Base.UnitTests/Utilities/InlineDictionaryTests.cs
  45. 37
      tests/Avalonia.Controls.UnitTests/AutoCompleteBoxTests.cs
  46. 1
      tests/Avalonia.UnitTests/TestRoot.cs

28
.nuke/build.schema.json

@ -6,17 +6,18 @@
"build": {
"type": "object",
"properties": {
"Configuration": {
"type": "string",
"description": "configuration"
"api-baseline": {
"type": "string"
},
"configuration": {
"type": "string"
},
"Continue": {
"type": "boolean",
"description": "Indicates to continue a previously failed build attempt"
},
"ForceNugetVersion": {
"type": "string",
"description": "force-nuget-version"
"force-nuget-version": {
"type": "string"
},
"Help": {
"type": "boolean",
@ -89,17 +90,16 @@
"RunRenderTests",
"RunTests",
"RunToolsTests",
"ValidateApiDiff",
"ZipFiles"
]
}
},
"SkipPreviewer": {
"type": "boolean",
"description": "skip-previewer"
"skip-previewer": {
"type": "boolean"
},
"SkipTests": {
"type": "boolean",
"description": "skip-tests"
"skip-tests": {
"type": "boolean"
},
"Target": {
"type": "array",
@ -124,10 +124,14 @@
"RunRenderTests",
"RunTests",
"RunToolsTests",
"ValidateApiDiff",
"ZipFiles"
]
}
},
"update-api-suppression": {
"type": "boolean"
},
"Verbosity": {
"type": "string",
"description": "Logging verbosity during build execution. Default is 'Normal'",

31
Documentation/build.md

@ -14,6 +14,18 @@ git submodule update --init
Go to https://dotnet.microsoft.com/download/visual-studio-sdks and install the latest version of the .NET Core SDK compatible with Avalonia UI. Make sure to download the SDK (not just the "runtime") package. The version compatible is indicated within the [global.json](https://github.com/AvaloniaUI/Avalonia/blob/master/global.json) file. Note that Avalonia UI does not always use the latest version and is hardcoded to use the last version known to be compatible (SDK releases may break the builds from time-to-time).
### Installing necessary .NET Workloads
.NET SDK requires developers to install workloads for each platform they are targeting.
Since Avalonia targets pretty much every supported .NET platform, you need to install these workloads as well.
Running it from the command line:
```
dotnet workload install android ios wasm-tools wasm-experimental
```
macOS workloads are not required to build Avalonia.
Note: on Unix OS you need to run this command from sudo.
## Build and Run Avalonia
```
@ -43,6 +55,25 @@ Build and run `ControlCatalog.NetCore` project to see the sample application.
>CSC : error CS0006: Metadata file 'C:\...\Avalonia\packages\Avalonia\bin\Debug\netcoreapp2.0\Avalonia.dll' could not be found
```
To correct this, right click on the `Avalonia.DesktopRuntime` project then press `Build` to build the project manually. Afterwards the solution should build normally and the ControlCatalog can be run.
* **Error MSB4062 GenerateAvaloniaResourcesTask**
Same as previous one, you need to manually build `Avalonia.Build.Tasks` project at least once.
Alternatively, you can build the solution once with Nuke.
## Building packages with Nuke
Install Nuke
`dotnet tool install --global Nuke.GlobalTool --version 6.2.1`
Build project:
`nuke --target Compile --configuration Release`
And run tests:
`nuke --target RunTests --configuration Release`
Or if you need to create nuget packages as well (it will compile and run tests automatically):
`nuke --target Package --configuration Release`
# Linux/macOS

64
api/Avalonia.Controls.ColorPicker.nupkg.xml

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://learn.microsoft.com/en-us/dotnet/fundamentals/package-validation/diagnostic-ids -->
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Fluent/ColorPicker.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Fluent/ColorPreviewer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Fluent/ColorSlider.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Fluent/ColorSpectrum.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Fluent/ColorView.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Simple/ColorPicker.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Simple/ColorPreviewer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Simple/ColorSlider.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Simple/ColorSpectrum.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Themes/Simple/ColorView.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Left>
<Right>target/netstandard2.0/Avalonia.Controls.ColorPicker.dll</Right>
</Suppression>
</Suppressions>

418
api/Avalonia.Themes.Fluent.nupkg.xml

@ -0,0 +1,418 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://learn.microsoft.com/en-us/dotnet/fundamentals/package-validation/diagnostic-ids -->
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Accents/BaseResources.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Accents/FluentControlResources.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/AdornerLayer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/AutoCompleteBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Button.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ButtonSpinner.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Calendar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CalendarButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CalendarDatePicker.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CalendarDayButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CalendarItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CaptionButtons.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Carousel.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CheckBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ComboBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ComboBoxItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ContentControl.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ContextMenu.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/DataValidationErrors.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/DatePicker.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/DateTimePickerShared.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/DropDownButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/EmbeddableControlRoot.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Expander.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/FlyoutPresenter.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/GridSplitter.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ItemsControl.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Label.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ListBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ListBoxItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ManagedFileChooser.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Menu.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/MenuFlyoutPresenter.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/MenuItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/MenuScrollViewer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/NativeMenuBar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/NotificationCard.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/NumericUpDown.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/OverlayPopupHost.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/PathIcon.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/PopupRoot.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ProgressBar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/RadioButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/RefreshContainer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/RefreshVisualizer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/RepeatButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ScrollBar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ScrollViewer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/SelectableTextBlock.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Separator.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Slider.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/SplitButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/SplitView.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TabControl.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TabItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TabStrip.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TabStripItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TextBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ThemeVariantScope.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TimePicker.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TitleBar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ToggleButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ToggleSwitch.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ToolTip.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TransitioningContentControl.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TreeView.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TreeViewItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Window.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/WindowNotificationManager.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Fluent.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Fluent.dll</Right>
</Suppression>
</Suppressions>

406
api/Avalonia.Themes.Simple.nupkg.xml

@ -0,0 +1,406 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://learn.microsoft.com/en-us/dotnet/fundamentals/package-validation/diagnostic-ids -->
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Accents/Base.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/AdornerLayer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/AutoCompleteBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Button.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ButtonSpinner.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Calendar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CalendarButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CalendarDatePicker.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CalendarDayButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CalendarItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CaptionButtons.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Carousel.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/CheckBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ComboBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ComboBoxItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ContentControl.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ContextMenu.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/DataValidationErrors.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/DatePicker.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/DateTimePickerShared.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/DropDownButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/EmbeddableControlRoot.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Expander.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/FlyoutPresenter.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/GridSplitter.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ItemsControl.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Label.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ListBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ListBoxItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ManagedFileChooser.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Menu.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/MenuFlyoutPresenter.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/MenuItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/NativeMenuBar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/NotificationCard.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/NumericUpDown.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/OverlayPopupHost.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/PathIcon.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/PopupRoot.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ProgressBar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/RadioButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/RefreshContainer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/RefreshVisualizer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/RepeatButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ScrollBar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ScrollViewer.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/SelectableTextBlock.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Separator.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Slider.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/SplitButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/SplitView.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TabControl.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TabItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TabStrip.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TabStripItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TextBox.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ThemeVariantScope.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TimePicker.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TitleBar.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ToggleButton.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ToggleSwitch.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/ToolTip.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TransitioningContentControl.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TreeView.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/TreeViewItem.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/Window.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:CompiledAvaloniaXaml.!AvaloniaResources.NamespaceInfo:/Controls/WindowNotificationManager.xaml</Target>
<Left>baseline/netstandard2.0/Avalonia.Themes.Simple.dll</Left>
<Right>target/netstandard2.0/Avalonia.Themes.Simple.dll</Right>
</Suppression>
</Suppressions>

153
nukebuild/ApiDiffValidation.cs

@ -0,0 +1,153 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Nuke.Common.Tooling;
public static class ApiDiffValidation
{
private static readonly HttpClient s_httpClient = new();
public static async Task ValidatePackage(
Tool apiCompatTool, string packagePath, string baselineVersion,
string suppressionFilesFolder, bool updateSuppressionFile)
{
if (baselineVersion is null)
{
throw new InvalidOperationException(
"Build \"api-baseline\" parameter must be set when running Nuke CreatePackages");
}
if (!Directory.Exists(suppressionFilesFolder))
{
Directory.CreateDirectory(suppressionFilesFolder!);
}
await using (var baselineStream = await DownloadBaselinePackage(packagePath, baselineVersion))
using (var target = new ZipArchive(File.Open(packagePath, FileMode.Open, FileAccess.Read), ZipArchiveMode.Read))
using (var baseline = new ZipArchive(baselineStream, ZipArchiveMode.Read))
using (Helpers.UseTempDir(out var tempFolder))
{
var targetDlls = GetDlls(target);
var baselineDlls = GetDlls(baseline);
var left = new List<string>();
var right = new List<string>();
var suppressionFile = Path.Combine(suppressionFilesFolder, GetPackageId(packagePath) + ".nupkg.xml");
// Don't use Path.Combine with these left and right tool parameters.
// Microsoft.DotNet.ApiCompat.Tool is stupid and treats '/' and '\' as different assemblies in suppression files.
// So, always use Unix '/'
foreach (var baselineDll in baselineDlls)
{
var baselineDllPath = $"baseline/{baselineDll.target}/{baselineDll.entry.Name}";
var baselineDllRealPath = Path.Combine(tempFolder, baselineDllPath);
Directory.CreateDirectory(Path.GetDirectoryName(baselineDllRealPath)!);
await using (var baselineDllFile = File.Create(baselineDllRealPath))
{
await baselineDll.entry.Open().CopyToAsync(baselineDllFile);
}
var targetDll = targetDlls.FirstOrDefault(e =>
e.target == baselineDll.target && e.entry.Name == baselineDll.entry.Name);
if (targetDll.entry is null)
{
throw new InvalidOperationException($"Some assemblies are missing in the new package: {baselineDll.entry.Name} for {baselineDll.target}");
}
var targetDllPath = $"target/{targetDll.target}/{targetDll.entry.Name}";
var targetDllRealPath = Path.Combine(tempFolder, targetDllPath);
Directory.CreateDirectory(Path.GetDirectoryName(targetDllRealPath)!);
await using (var targetDllFile = File.Create(targetDllRealPath))
{
await targetDll.entry.Open().CopyToAsync(targetDllFile);
}
left.Add(baselineDllPath);
right.Add(targetDllPath);
}
if (left.Any())
{
var args = $""" -l={string.Join(',', left)} -r="{string.Join(',', right)}" """;
if (File.Exists(suppressionFile))
{
args += $""" --suppression-file="{suppressionFile}" """;
}
if (updateSuppressionFile)
{
args += $""" --suppression-output-file="{suppressionFile}" --generate-suppression-file=true """;
}
var result = apiCompatTool(args, tempFolder)
.Where(t => t.Type == OutputType.Err).ToArray();
if (result.Any())
{
throw new AggregateException(
$"ApiDiffValidation task has failed for \"{Path.GetFileName(packagePath)}\" package",
result.Select(r => new Exception(r.Text)));
}
}
}
}
private static IReadOnlyCollection<(string target, ZipArchiveEntry entry)> GetDlls(ZipArchive archive)
{
return archive.Entries
.Where(e => Path.GetExtension(e.FullName) == ".dll"
// Exclude analyzers and build task, as we don't care about breaking changes there
&& !e.FullName.Contains("analyzers/") && !e.FullName.Contains("analyzers\\")
&& !e.Name.Contains("Avalonia.Build.Tasks"))
.Select(e => (
entry: e,
isRef: e.FullName.Contains("ref/") || e.FullName.Contains("ref\\"),
target: Path.GetDirectoryName(e.FullName)!.Split(new [] { '/', '\\' }).Last())
)
.GroupBy(e => (e.target, e.entry.Name))
.Select(g => g.MaxBy(e => e.isRef))
.Select(e => (e.target, e.entry))
.ToArray();
}
static async Task<Stream> DownloadBaselinePackage(string packagePath, string baselineVersion)
{
/*
Gets package name from versions like:
Avalonia.0.10.0-preview1
Avalonia.11.0.999-cibuild0037534-beta
Avalonia.11.0.0
*/
var packageId = GetPackageId(packagePath);
Build.Information("Downloading {0} {1} baseline package", packageId, baselineVersion);
try
{
using var response = await s_httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Get,
$"https://www.nuget.org/api/v2/package/{packageId}/{baselineVersion}"), HttpCompletionOption.ResponseHeadersRead);
response.EnsureSuccessStatusCode();
await using var stream = await response.Content.ReadAsStreamAsync();
var memoryStream = new MemoryStream();
await stream.CopyToAsync(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
return memoryStream;
}
catch (Exception ex)
{
throw new InvalidOperationException($"Downloading baseline package for {packageId} {baselineVersion} failed.\r" + ex.Message, ex);
}
}
static string GetPackageId(string packagePath)
{
return Regex.Replace(
Path.GetFileNameWithoutExtension(packagePath),
"""(\.\d+\.\d+\.\d+(?:-.+)?)$""", "");
}
}

19
nukebuild/Build.cs

@ -36,6 +36,10 @@ using MicroCom.CodeGenerator;
partial class Build : NukeBuild
{
BuildParameters Parameters { get; set; }
[PackageExecutable("Microsoft.DotNet.ApiCompat.Tool", "Microsoft.DotNet.ApiCompat.Tool.dll", Framework = "net6.0")]
Tool ApiCompatTool;
protected override void OnBuildInitialized()
{
Parameters = new BuildParameters(this);
@ -278,7 +282,17 @@ partial class Build : NukeBuild
RefAssemblyGenerator.GenerateRefAsmsInPackage(Parameters.NugetRoot / "Avalonia." +
Parameters.Version + ".nupkg");
});
Target ValidateApiDiff => _ => _
.DependsOn(CreateNugetPackages)
.Executes(async () =>
{
await Task.WhenAll(
Directory.GetFiles(Parameters.NugetRoot).Select(nugetPackage => ApiDiffValidation.ValidatePackage(
ApiCompatTool, nugetPackage, Parameters.ApiValidationBaseline,
Parameters.ApiValidationSuppressionFiles, Parameters.UpdateApiValidationSuppression)));
});
Target RunTests => _ => _
.DependsOn(RunCoreLibsTests)
.DependsOn(RunRenderTests)
@ -288,7 +302,8 @@ partial class Build : NukeBuild
Target Package => _ => _
.DependsOn(RunTests)
.DependsOn(CreateNugetPackages);
.DependsOn(CreateNugetPackages)
.DependsOn(ValidateApiDiff);
Target CiAzureLinux => _ => _
.DependsOn(RunTests);

22
nukebuild/BuildParameters.cs

@ -10,18 +10,24 @@ using static Nuke.Common.IO.PathConstruction;
public partial class Build
{
[Parameter("configuration")]
[Parameter(Name = "configuration")]
public string Configuration { get; set; }
[Parameter("skip-tests")]
[Parameter(Name = "skip-tests")]
public bool SkipTests { get; set; }
[Parameter("force-nuget-version")]
[Parameter(Name = "force-nuget-version")]
public string ForceNugetVersion { get; set; }
[Parameter("skip-previewer")]
[Parameter(Name = "skip-previewer")]
public bool SkipPreviewer { get; set; }
[Parameter(Name = "api-baseline")]
public string ApiValidationBaseline { get; set; }
[Parameter(Name = "update-api-suppression")]
public bool? UpdateApiValidationSuppression { get; set; }
public class BuildParameters
{
public string Configuration { get; }
@ -57,7 +63,9 @@ public partial class Build
public string FileZipSuffix { get; }
public AbsolutePath ZipCoreArtifacts { get; }
public AbsolutePath ZipNuGetArtifacts { get; }
public string ApiValidationBaseline { get; }
public bool UpdateApiValidationSuppression { get; }
public AbsolutePath ApiValidationSuppressionFiles { get; }
public BuildParameters(Build b)
{
@ -103,6 +111,9 @@ public partial class Build
// VERSION
Version = b.ForceNugetVersion ?? GetVersion();
ApiValidationBaseline = b.ApiValidationBaseline ?? new Version(new Version(Version).Major, 0).ToString();
UpdateApiValidationSuppression = b.UpdateApiValidationSuppression ?? IsLocalBuild;
if (IsRunningOnAzure)
{
if (!IsNuGetRelease)
@ -125,6 +136,7 @@ public partial class Build
FileZipSuffix = Version + ".zip";
ZipCoreArtifacts = ZipRoot / ("Avalonia-" + FileZipSuffix);
ZipNuGetArtifacts = ZipRoot / ("Avalonia-NuGet-" + FileZipSuffix);
ApiValidationSuppressionFiles = RootDirectory / "api";
}
string GetVersion()

4
nukebuild/Shims.cs

@ -9,12 +9,12 @@ using Numerge;
public partial class Build
{
static void Information(string info)
internal static void Information(string info)
{
Logger.Info(info);
}
static void Information(string info, params object[] args)
internal static void Information(string info, params object[] args)
{
Logger.Info(info, args);
}

2
nukebuild/_build.csproj

@ -22,6 +22,8 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageDownload Include="Microsoft.DotNet.ApiCompat.Tool" Version="[7.0.305]" />
</ItemGroup>
<ItemGroup>

6
readme.md

@ -6,18 +6,16 @@
<br />
[![NuGet](https://img.shields.io/nuget/v/Avalonia.svg)](https://www.nuget.org/packages/Avalonia) [![downloads](https://img.shields.io/nuget/dt/avalonia)](https://www.nuget.org/packages/Avalonia) ![Size](https://img.shields.io/github/repo-size/avaloniaui/avalonia.svg)
⚠️ **v11 Update - [Pausing community contributions](https://github.com/AvaloniaUI/Avalonia/discussions/10599)**
## 📖 About
[Avalonia](https://avaloniaui.net) is a cross-platform UI framework for dotnet, providing a flexible styling system and supporting a wide range of platforms such as Windows, macOS, Linux, iOS, Android and WebAssembly. Avalonia is mature and production ready and is used by companies, including [Schneider Electric](https://avaloniaui.net/showcase#se), [Unity](https://avaloniaui.net/showcase#unity), [JetBrains](https://avaloniaui.net/showcase#rider) and [Github](https://avaloniaui.net/showcase#github).
Considered by many to be the spiritual successor to WPF, Avalonia UI provides a familiar, modern development experience for XAML developers creating cross-platform applications. While Avalonia UI is [similar to WPF](https://docs.avaloniaui.net/misc/wpf), it isn't a 1:1 copy, and you'll find plenty of improvements.
Considered by many to be the spiritual successor to WPF, Avalonia UI provides a familiar, modern development experience for XAML developers creating cross-platform applications. While Avalonia UI is [similar to WPF](https://docs.avaloniaui.net/docs/next/get-started/wpf/), it isn't a 1:1 copy, and you'll find plenty of improvements.
For those seeking a cross-platform WPF, we have created [Avalonia XPF](https://avaloniaui.net/xpf), enabling WPF applications to run on macOS and Linux with little to no code changes. Avalonia XPF is a commercial product and is licensed per-app, per-platform.
#### Roadmap
To see the status of some of our features, please see our [Roadmap](https://github.com/AvaloniaUI/Avalonia/issues/2239).
To see the status of some of our features, look at our [Roadmap](https://github.com/AvaloniaUI/Avalonia/issues/2239).
#### Breaking Changes
You can also see what [breaking changes](https://github.com/AvaloniaUI/Avalonia/issues/3538) we have planned and what our [past breaking changes](https://github.com/AvaloniaUI/Avalonia/wiki/Breaking-Changes) have been.

5
samples/ControlCatalog/Pages/AutoCompleteBoxPage.xaml

@ -18,6 +18,10 @@
<Setter Property="Margin" Value="8" />
</Style>
</UniformGrid.Styles>
<StackPanel>
<TextBlock Text="MinimumPrefixLength: 0" />
<AutoCompleteBox MinimumPrefixLength="0" />
</StackPanel>
<StackPanel>
<TextBlock Text="MinimumPrefixLength: 1" />
<AutoCompleteBox MinimumPrefixLength="1" />
@ -42,7 +46,6 @@
<TextBlock Text="Disabled" />
<AutoCompleteBox IsEnabled="False" />
</StackPanel>
<StackPanel>
<TextBlock Text="ValueMemberBinding" />
<AutoCompleteBox ValueMemberBinding="{Binding Capital, x:DataType=models:StateData}" />

4
samples/ControlCatalog/Pages/DataGridPage.xaml

@ -34,7 +34,7 @@
RowBackground="#1000">
<DataGrid.Columns>
<!-- Using HeaderTemplate -->
<DataGridTextColumn Header="Country" HeaderTemplate="{StaticResource Demo.DataTemplates.CountryHeader}" Binding="{Binding Name}" Width="6*" x:DataType="local:Country" />
<DataGridTextColumn Header="Country or Region" HeaderTemplate="{StaticResource Demo.DataTemplates.CountryHeader}" Binding="{Binding Name}" Width="6*" x:DataType="local:Country" />
<DataGridTextColumn Header="Region" Binding="{Binding Region}" Width="4*" x:DataType="local:Country" />
<DataGridTextColumn Header="Population" Binding="{Binding Population}" Width="3*" x:DataType="local:Country" />
<DataGridTextColumn Header="Area" Binding="{Binding Area}" Width="3*" x:DataType="local:Country" />
@ -68,7 +68,7 @@
<TabItem Header="Grouping">
<DataGrid Name="dataGridGrouping" Margin="12">
<DataGrid.Columns>
<DataGridTextColumn Header="Country" Binding="{Binding Name}" Width="6*" x:DataType="local:Country" />
<DataGridTextColumn Header="Country or Region" Binding="{Binding Name}" Width="6*" x:DataType="local:Country" />
<DataGridTextColumn Header="Region" Binding="{Binding Region}" Width="4*" x:DataType="local:Country" />
<DataGridTextColumn DisplayIndex="3" Header="Population" Binding="{Binding Population}" Width="3*" x:DataType="local:Country" />
<DataGridTextColumn DisplayIndex="2" Header="Area" Binding="{Binding Area}" Width="3*" x:DataType="local:Country" />

5
src/Avalonia.Base/Interactivity/EventRoute.cs

@ -120,11 +120,6 @@ namespace Avalonia.Interactivity
return;
}
if (e.Source is null)
{
throw new ArgumentException("Event source may not be null", nameof(e));
}
Interactive? lastTarget = null;
var start = 0;
var end = _route.Count;

2
src/Avalonia.Base/Platform/Storage/PickerOptions.cs

@ -6,7 +6,7 @@
public class PickerOptions
{
/// <summary>
/// Gets or sets the text that appears in the title bar of a folder dialog.
/// Gets or sets the text that appears in the title bar of a picker.
/// </summary>
public string? Title { get; set; }

3
src/Avalonia.Base/Rendering/Composition/CompositionExternalMemory.cs

@ -91,8 +91,7 @@ public interface ICompositionGpuImportedObject : IAsyncDisposable
/// the user code is allowed to free the resource owner in case when a non-owning
/// sharing handle was used
/// </summary>
Task ImportCompleted { get; }
Task ImportCompeted { get; }
/// <summary>
/// Indicates if the device context this instance is associated with is no longer available
/// </summary>

6
src/Avalonia.Base/Rendering/Composition/CompositionInterop.cs

@ -67,18 +67,18 @@ abstract class CompositionGpuImportedObjectBase : ICompositionGpuImportedObject
Context = context;
Feature = feature;
ImportCompleted = Compositor.InvokeServerJobAsync(Import);
ImportCompeted = Compositor.InvokeServerJobAsync(Import);
}
protected abstract void Import();
public abstract void Dispose();
public Task ImportCompleted { get; }
public Task ImportCompeted { get; }
public bool IsLost => Context.IsLost;
public ValueTask DisposeAsync() => new(Compositor.InvokeServerJobAsync(() =>
{
if (ImportCompleted.Status == TaskStatus.RanToCompletion)
if (ImportCompeted.Status == TaskStatus.RanToCompletion)
Dispose();
}));
}

21
src/Avalonia.Base/Rendering/Composition/Drawing/ServerCompositionRenderData.cs

@ -42,22 +42,31 @@ class ServerCompositionRenderData : SimpleServerRenderResource
_items.Add(reader.ReadObject<IRenderDataItem>());
var collector = s_resourceHashSetPool.Get();
foreach(var item in _items)
if (item is IRenderDataItemWithServerResources resourceItem)
resourceItem.Collect(collector);
CollectResources(_items, collector);
foreach (var r in collector.Resources)
{
_referencedResources.Add(r);
r.AddObserver(this);
}
collector.Resources.Clear();
s_resourceHashSetPool.ReturnAndSetNull(ref collector);
base.DeserializeChangesCore(reader, committedAt);
}
private static void CollectResources(PooledInlineList<IRenderDataItem> items, IRenderDataServerResourcesCollector collector)
{
foreach (var item in items)
{
if (item is IRenderDataItemWithServerResources resourceItem)
resourceItem.Collect(collector);
else if (item is RenderDataPushNode pushNode)
CollectResources(pushNode.Children, collector);
}
}
public Rect? Bounds
{
get
@ -133,4 +142,4 @@ class ServerCompositionRenderData : SimpleServerRenderResource
Reset();
base.Dispose();
}
}
}

6
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionDrawingSurface.cs

@ -31,12 +31,12 @@ internal class ServerCompositionDrawingSurface : ServerCompositionSurface, IDisp
throw new PlatformGraphicsContextLostException();
// This should never happen, but check for it anyway to avoid a deadlock
if (!image.ImportCompleted.IsCompleted)
if (!image.ImportCompeted.IsCompleted)
throw new InvalidOperationException("The import operation is not completed yet");
// Rethrow the import here exception
if (image.ImportCompleted.IsFaulted)
image.ImportCompleted.GetAwaiter().GetResult();
if (image.ImportCompeted.IsFaulted)
image.ImportCompeted.GetAwaiter().GetResult();
}
void Update(IBitmapImpl newImage, IPlatformRenderInterfaceContext context)

8
src/Avalonia.Base/Threading/Dispatcher.Invoke.cs

@ -90,7 +90,7 @@ public partial class Dispatcher
{
if (callback == null)
{
throw new ArgumentNullException("callback");
throw new ArgumentNullException(nameof(callback));
}
DispatcherPriority.Validate(priority, "priority");
@ -212,7 +212,7 @@ public partial class Dispatcher
{
if (callback == null)
{
throw new ArgumentNullException("callback");
throw new ArgumentNullException(nameof(callback));
}
DispatcherPriority.Validate(priority, "priority");
@ -304,7 +304,7 @@ public partial class Dispatcher
{
if (callback == null)
{
throw new ArgumentNullException("callback");
throw new ArgumentNullException(nameof(callback));
}
DispatcherPriority.Validate(priority, "priority");
@ -379,7 +379,7 @@ public partial class Dispatcher
{
if (callback == null)
{
throw new ArgumentNullException("callback");
throw new ArgumentNullException(nameof(callback));
}
DispatcherPriority.Validate(priority, "priority");

4
src/Avalonia.Base/Threading/DispatcherTimer.cs

@ -62,7 +62,7 @@ public partial class DispatcherTimer
{
if (callback == null)
{
throw new ArgumentNullException("callback");
throw new ArgumentNullException(nameof(callback));
}
Tick += callback;
@ -253,7 +253,7 @@ public partial class DispatcherTimer
{
if (dispatcher == null)
{
throw new ArgumentNullException("dispatcher");
throw new ArgumentNullException(nameof(dispatcher));
}
DispatcherPriority.Validate(priority, "priority");

16
src/Avalonia.Base/Utilities/SmallDictionary.cs

@ -51,7 +51,7 @@ internal struct InlineDictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey,
throw new ArgumentException("Key already exists in dictionary");
}
if (arr[c].Key == null)
if (arr[c].Key == null && free == -1)
free = c;
}
@ -337,11 +337,15 @@ internal struct InlineDictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey,
}
else if (_type == Type.Array)
{
var next = _index + 1;
if (_arr!.Length - 1 < next || _arr[next].Key == null)
return false;
_index = next;
return true;
for (var next = _index + 1; next < _arr!.Length; ++next)
{
if (_arr[next].Key != null)
{
_index = next;
return true;
}
}
return false;
}
else if (_type == Type.Dictionary)
return _inner.MoveNext();

39
src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs

@ -304,7 +304,7 @@ namespace Avalonia.Build.Tasks
|| "Internal".Equals(classModifierText, StringComparison.OrdinalIgnoreCase))
classModifierPublic = false;
else
throw new XamlParseException("Invalid value for x:ClassModifier. Expected value are: Public, NotPublic (internal).", precompileDirective);
throw new XamlParseException("Invalid value for x:ClassModifier. Expected value are: Public, NotPublic (internal).", classModifierDirective);
}
var classDirective = initialRoot.Children.OfType<XamlAstXmlDirective>()
@ -353,10 +353,16 @@ namespace Avalonia.Build.Tasks
((List<XamlDocumentResource>)parsedXamlDocuments).Add(new XamlDocumentResource(
parsed, res.Uri, res, classType,
classModifierPublic.Value,
populateBuilder,
compiler.DefinePopulateMethod(populateBuilder, parsed, populateName,
classTypeDefinition == null && classModifierPublic.Value),
buildName == null ? null : compiler.DefineBuildMethod(builder, parsed, buildName, classModifierPublic.Value)));
() => new XamlDocumentTypeBuilderProvider(
populateBuilder,
compiler.DefinePopulateMethod(
populateBuilder,
parsed,
populateName,
classTypeDefinition == null && classModifierPublic.Value),
buildName == null ?
null :
compiler.DefineBuildMethod(builder, parsed, buildName, classModifierPublic.Value))));
}
catch (Exception e)
{
@ -387,10 +393,17 @@ namespace Avalonia.Build.Tasks
foreach (var document in parsedXamlDocuments)
{
var res = (IResource)document.FileSource!;
if (document.Usage == XamlDocumentUsage.Merged && !document.IsPublic)
{
res.Remove();
continue;
}
var parsed = document.XamlDocument;
var res = (IResource)document.FileSource;
var classType = document.ClassType;
var populateBuilder = document.TypeBuilder;
var populateBuilder = document.TypeBuilderProvider.TypeBuilder;
try
{
@ -399,8 +412,8 @@ namespace Avalonia.Build.Tasks
compiler.Compile(parsed,
contextClass,
document.PopulateMethod,
document.BuildMethod,
document.TypeBuilderProvider.PopulateMethod,
document.TypeBuilderProvider.BuildMethod,
builder.DefineSubType(compilerConfig.WellKnownTypes.Object, "NamespaceInfo:" + res.Name, true),
(closureName, closureBaseType) =>
populateBuilder.DefineSubType(closureBaseType, closureName, false),
@ -412,7 +425,7 @@ namespace Avalonia.Build.Tasks
if (classTypeDefinition != null)
{
var compiledPopulateMethod = typeSystem.GetTypeReference(populateBuilder).Resolve()
.Methods.First(m => m.Name == document.PopulateMethod.Name);
.Methods.First(m => m.Name == document.TypeBuilderProvider.PopulateMethod.Name);
var designLoaderFieldType = typeSystem
.GetType("System.Action`1")
@ -536,12 +549,12 @@ namespace Avalonia.Build.Tasks
}
if (document.IsPublic
&& (document.BuildMethod != null || classTypeDefinition != null))
&& (document.TypeBuilderProvider.BuildMethod != null || classTypeDefinition != null))
{
var compiledBuildMethod = document.BuildMethod == null ?
var compiledBuildMethod = document.TypeBuilderProvider.BuildMethod is not { } buildMethod ?
null :
typeSystem.GetTypeReference(builder).Resolve()
.Methods.First(m => m.Name == document.BuildMethod?.Name);
.Methods.First(m => m.Name == buildMethod.Name);
var parameterlessConstructor = compiledBuildMethod != null ?
null :
classTypeDefinition.GetConstructors().FirstOrDefault(c =>

2
src/Avalonia.Controls.DataGrid/DataGridCheckBoxColumn.cs

@ -222,7 +222,7 @@ namespace Avalonia.Controls
{
if (element == null)
{
throw new ArgumentNullException("element");
throw new ArgumentNullException(nameof(element));
}
if (element is CheckBox checkBox)
{

2
src/Avalonia.Controls.DataGrid/DataGridColumnCollection.cs

@ -191,7 +191,7 @@ namespace Avalonia.Controls
}
if (dataGridColumn == null)
{
throw new ArgumentNullException("dataGridColumn");
throw new ArgumentNullException(nameof(dataGridColumn));
}
int columnIndexWithFiller = columnIndex;

2
src/Avalonia.Controls.DataGrid/DataGridLength.cs

@ -499,7 +499,7 @@ namespace Avalonia.Controls
{
if (destinationType == null)
{
throw new ArgumentNullException("destinationType");
throw new ArgumentNullException(nameof(destinationType));
}
if (destinationType != typeof(string))
{

11
src/Avalonia.Controls/AutoCompleteBox/AutoCompleteBox.cs

@ -1320,17 +1320,14 @@ namespace Avalonia.Controls
// Evaluate the conditions needed for completion.
// 1. Minimum prefix length
// 2. If a delay timer is in use, use it
bool populateReady = newText.Length >= MinimumPrefixLength && MinimumPrefixLength >= 0;
if (populateReady && MinimumPrefixLength == 0 && String.IsNullOrEmpty(newText) && String.IsNullOrEmpty(SearchText))
{
populateReady = false;
}
_userCalledPopulate = populateReady ? userInitiated : false;
bool minimumLengthReached = newText.Length >= MinimumPrefixLength && MinimumPrefixLength >= 0;
_userCalledPopulate = minimumLengthReached && userInitiated;
// Update the interface and values only as necessary
UpdateTextValue(newText, userInitiated);
if (populateReady)
if (minimumLengthReached)
{
_ignoreTextSelectionChange = true;

2
src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs

@ -18,7 +18,7 @@ namespace Avalonia.Automation.Peers
public ControlAutomationPeer(Control owner)
{
Owner = owner ?? throw new ArgumentNullException("owner");
Owner = owner ?? throw new ArgumentNullException(nameof(owner));
Initialize();
}

3
src/Avalonia.Diagnostics/Diagnostics/ViewModels/EventTreeNode.cs

@ -72,12 +72,13 @@ namespace Avalonia.Diagnostics.ViewModels
var s = sender!;
var handled = e.Handled;
var route = e.Route;
var triggerTime = DateTime.Now;
void handler()
{
if (_currentEvent == null || !_currentEvent.IsPartOfSameEventChain(e))
{
_currentEvent = new FiredEvent(e, new EventChainLink(s, handled, route));
_currentEvent = new FiredEvent(e, new EventChainLink(s, handled, route), triggerTime);
_parentViewModel.RecordedEvents.Add(_currentEvent);

5
src/Avalonia.Diagnostics/Diagnostics/ViewModels/FiredEvent.cs

@ -10,11 +10,12 @@ namespace Avalonia.Diagnostics.ViewModels
private readonly RoutedEventArgs _eventArgs;
private EventChainLink? _handledBy;
public FiredEvent(RoutedEventArgs eventArgs, EventChainLink originator)
public FiredEvent(RoutedEventArgs eventArgs, EventChainLink originator, DateTime triggerTime)
{
_eventArgs = eventArgs ?? throw new ArgumentNullException(nameof(eventArgs));
Originator = originator ?? throw new ArgumentNullException(nameof(originator));
AddToChain(originator);
TriggerTime = triggerTime;
}
public bool IsPartOfSameEventChain(RoutedEventArgs e)
@ -22,6 +23,8 @@ namespace Avalonia.Diagnostics.ViewModels
return e == _eventArgs;
}
public DateTime TriggerTime { get; }
public RoutedEvent Event => _eventArgs.RoutedEvent!;
public bool IsHandled => HandledBy?.Handled == true;

10
src/Avalonia.Diagnostics/Diagnostics/Views/EventsPageView.xaml

@ -77,21 +77,23 @@
<ListBox.ItemTemplate>
<DataTemplate>
<ListBoxItem Classes.handled="{Binding IsHandled}">
<Grid ColumnDefinitions="Auto,Auto,*,Auto">
<Grid ColumnDefinitions="Auto,Auto,Auto,*,Auto">
<StackPanel Grid.Column="0" Spacing="2" Orientation="Horizontal" >
<TextBlock Grid.Column="0" Text="{Binding TriggerTime, StringFormat={}{0:HH:mm:ss.fff}}"/>
<StackPanel Margin="10,0,0,0" Grid.Column="1" Spacing="2" Orientation="Horizontal" >
<TextBlock Tag="{Binding Event}" DoubleTapped="NavigateTo" Text="{Binding Event.Name}" FontWeight="Bold" Classes="nav" />
<TextBlock Text="on" />
<TextBlock Tag="{Binding Originator}" DoubleTapped="NavigateTo" Text="{Binding Originator.HandlerName}" Classes="nav" />
</StackPanel>
<StackPanel Margin="2,0,0,0" Grid.Column="1" Spacing="2" Orientation="Horizontal" IsVisible="{Binding IsHandled}" >
<StackPanel Margin="2,0,0,0" Grid.Column="2" Spacing="2" Orientation="Horizontal" IsVisible="{Binding IsHandled}" >
<TextBlock Text="::" />
<TextBlock Text="Handled by" />
<TextBlock Tag="{Binding HandledBy}" DoubleTapped="NavigateTo" Text="{Binding HandledBy.HandlerName}" Classes="nav" />
</StackPanel>
<StackPanel Grid.Column="3" Orientation="Horizontal" HorizontalAlignment="Right">
<StackPanel Grid.Column="4" Orientation="Horizontal" HorizontalAlignment="Right">
<TextBlock Text="Routing (" />
<TextBlock Text="{Binding Event.RoutingStrategies}"/>
<TextBlock Text=")"/>

23
src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaXamlIlRuntimeCompiler.cs

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
@ -231,10 +232,19 @@ namespace Avalonia.Markup.Xaml.XamlIl
?? ((IXamlAstValueNode)parsed.Root).Type.GetClrType().Name;
var tb = _sreBuilder.DefineType("Builder_" + Guid.NewGuid().ToString("N") + "_" + xamlName);
var builder = _sreTypeSystem.CreateTypeBuilder(tb);
parsedDocuments.Add(new XamlDocumentResource(parsed, document.BaseUri?.ToString(),
null, null, true, builder,
compiler.DefinePopulateMethod(builder, parsed, AvaloniaXamlIlCompiler.PopulateName, true),
document.RootInstance is null ? compiler.DefineBuildMethod(builder, parsed, AvaloniaXamlIlCompiler.BuildName, true) : null));
parsedDocuments.Add(new XamlDocumentResource(
parsed,
document.BaseUri?.ToString(),
null,
null,
true,
() => new XamlDocumentTypeBuilderProvider(
builder,
compiler.DefinePopulateMethod(builder, parsed, AvaloniaXamlIlCompiler.PopulateName, true),
document.RootInstance is null ?
compiler.DefineBuildMethod(builder, parsed, AvaloniaXamlIlCompiler.BuildName, true) :
null)));
originalDocuments.Add(document);
}
@ -242,9 +252,8 @@ namespace Avalonia.Markup.Xaml.XamlIl
var createdTypes = parsedDocuments.Select(document =>
{
compiler.Compile(document.XamlDocument, document.TypeBuilder, document.PopulateMethod,
document.BuildMethod, document.Uri, document.FileSource);
return _sreTypeSystem.GetType(document.TypeBuilder.CreateType());
compiler.Compile(document.XamlDocument, document.TypeBuilderProvider, document.Uri, document.FileSource);
return _sreTypeSystem.GetType(document.TypeBuilderProvider.TypeBuilder.CreateType());
}).ToArray();
clrPropertyBuilder.CreateTypeInfo();

6
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompiler.cs

@ -179,9 +179,11 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
return parsed;
}
public void Compile(XamlDocument document, IXamlTypeBuilder<IXamlILEmitter> tb, IXamlMethodBuilder<IXamlILEmitter> populateMethod, IXamlMethodBuilder<IXamlILEmitter> buildMethod, string baseUri, IFileSource fileSource)
public void Compile(XamlDocument document, XamlDocumentTypeBuilderProvider typeBuilderProvider, string baseUri, IFileSource fileSource)
{
Compile(document, _contextType, populateMethod, buildMethod,
var tb = typeBuilderProvider.TypeBuilder;
Compile(document, _contextType, typeBuilderProvider.PopulateMethod, typeBuilderProvider.BuildMethod,
_configuration.TypeMappings.XmlNamespaceInfoProvider == null ?
null :
tb.DefineSubType(_configuration.WellKnownTypes.Object,

20
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/GroupTransformers/XamlMergeResourceGroupTransformer.cs

@ -3,8 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers;
using XamlX.Ast;
using XamlX.IL.Emitters;
using XamlX.Transform.Transformers;
using XamlX.TypeSystem;
namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.GroupTransformers;
@ -24,7 +22,6 @@ internal class XamlMergeResourceGroupTransformer : IXamlAstGroupTransformer
var mergeResourceIncludeType = context.GetAvaloniaTypes().MergeResourceInclude;
var mergeSourceNodes = new List<XamlPropertyAssignmentNode>();
var mergedResourceWasAdded = false;
foreach (var manipulationNode in resourceDictionaryManipulation.Children.ToArray())
{
void ProcessXamlPropertyAssignmentNode(XamlManipulationGroupNode parent, XamlPropertyAssignmentNode assignmentNode)
@ -39,7 +36,6 @@ internal class XamlMergeResourceGroupTransformer : IXamlAstGroupTransformer
{
parent.Children.Remove(assignmentNode);
mergeSourceNodes.Add(sourceAssignmentNode);
mergedResourceWasAdded = true;
}
else
{
@ -85,25 +81,29 @@ internal class XamlMergeResourceGroupTransformer : IXamlAstGroupTransformer
return context.ParseError(
$"Node MergeResourceInclude is unable to resolve \"{originalAssetPath}\" path.", propertyNode, node);
}
var targetDocument = context.Documents.FirstOrDefault(d =>
string.Equals(d.Uri, originalAssetPath, StringComparison.InvariantCultureIgnoreCase))
?.XamlDocument.Root as XamlValueWithManipulationNode;
if (targetDocument is null)
string.Equals(d.Uri, originalAssetPath, StringComparison.InvariantCultureIgnoreCase));
if (targetDocument?.XamlDocument.Root is not XamlValueWithManipulationNode targetDocumentRoot)
{
return context.ParseError(
$"Node MergeResourceInclude is unable to resolve \"{originalAssetPath}\" path.", propertyNode, node);
}
var singleRootObject = ((XamlManipulationGroupNode)targetDocument.Manipulation)
var singleRootObject = ((XamlManipulationGroupNode)targetDocumentRoot.Manipulation)
.Children.OfType<XamlObjectInitializationNode>().Single();
if (singleRootObject.Type != resourceDictionaryType)
{
return context.ParseError(
$"MergeResourceInclude can only include another ResourceDictionary", propertyNode, node);
"MergeResourceInclude can only include another ResourceDictionary", propertyNode, node);
}
manipulationGroup.Add(singleRootObject.Manipulation);
if (targetDocument.Usage == XamlDocumentUsage.Unknown)
{
targetDocument.Usage = XamlDocumentUsage.Merged;
}
}
// Order of resources is defined by ResourceDictionary.TryGetResource.

4
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/IXamlDocumentResource.cs

@ -1,5 +1,4 @@
using System;
using XamlX.Ast;
using XamlX.Ast;
using XamlX.TypeSystem;
namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions;
@ -14,4 +13,5 @@ internal interface IXamlDocumentResource
IXamlMethod PopulateMethod { get; }
IFileSource? FileSource { get; }
XamlDocument XamlDocument { get; }
XamlDocumentUsage Usage { get; set; }
}

34
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlDocumentResource.cs

@ -1,6 +1,5 @@
using System;
using XamlX.Ast;
using XamlX.IL;
using XamlX.TypeSystem;
#nullable enable
@ -8,24 +7,23 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions;
internal class XamlDocumentResource : IXamlDocumentResource
{
private readonly Func<XamlDocumentTypeBuilderProvider> _createTypeBuilderProvider;
private XamlDocumentTypeBuilderProvider? _typeBuilderProvider;
public XamlDocumentResource(
XamlDocument xamlDocument,
string? uri,
IFileSource? fileSource,
IXamlType? classType,
bool isPublic,
IXamlTypeBuilder<IXamlILEmitter> typeBuilder,
IXamlMethodBuilder<IXamlILEmitter> populateMethod,
IXamlMethodBuilder<IXamlILEmitter>? buildMethod)
Func<XamlDocumentTypeBuilderProvider> createTypeBuilderProvider)
{
_createTypeBuilderProvider = createTypeBuilderProvider;
XamlDocument = xamlDocument;
Uri = uri;
FileSource = fileSource;
ClassType = classType;
IsPublic = isPublic;
TypeBuilder = typeBuilder;
PopulateMethod = populateMethod;
BuildMethod = buildMethod;
}
public XamlDocument XamlDocument { get; }
@ -34,10 +32,22 @@ internal class XamlDocumentResource : IXamlDocumentResource
public IXamlType? ClassType { get; }
public bool IsPublic { get; }
public IXamlTypeBuilder<IXamlILEmitter> TypeBuilder { get; }
public IXamlMethodBuilder<IXamlILEmitter> PopulateMethod { get; }
public IXamlMethodBuilder<IXamlILEmitter>? BuildMethod { get; }
public XamlDocumentUsage Usage { get; set; }
public XamlDocumentTypeBuilderProvider TypeBuilderProvider
{
get
{
if (_typeBuilderProvider is null)
{
_typeBuilderProvider = _createTypeBuilderProvider();
Usage = XamlDocumentUsage.Used;
}
return _typeBuilderProvider;
}
}
IXamlMethod? IXamlDocumentResource.BuildMethod => BuildMethod;
IXamlMethod IXamlDocumentResource.PopulateMethod => PopulateMethod;
IXamlMethod? IXamlDocumentResource.BuildMethod => TypeBuilderProvider.BuildMethod;
IXamlMethod IXamlDocumentResource.PopulateMethod => TypeBuilderProvider.PopulateMethod;
}

23
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlDocumentTypeBuilderProvider.cs

@ -0,0 +1,23 @@
#nullable enable
using XamlX.IL;
using XamlX.TypeSystem;
namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions;
internal sealed class XamlDocumentTypeBuilderProvider
{
public XamlDocumentTypeBuilderProvider(
IXamlTypeBuilder<IXamlILEmitter> typeBuilder,
IXamlMethodBuilder<IXamlILEmitter> populateMethod,
IXamlMethodBuilder<IXamlILEmitter>? buildMethod)
{
TypeBuilder = typeBuilder;
PopulateMethod = populateMethod;
BuildMethod = buildMethod;
}
public IXamlTypeBuilder<IXamlILEmitter> TypeBuilder { get; }
public IXamlMethodBuilder<IXamlILEmitter> PopulateMethod { get; }
public IXamlMethodBuilder<IXamlILEmitter>? BuildMethod { get; }
}

8
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlDocumentUsage.cs

@ -0,0 +1,8 @@
namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions;
internal enum XamlDocumentUsage
{
Unknown,
Merged,
Used
}

16
src/Windows/Avalonia.Win32/OpenGl/WglDisplay.cs

@ -38,12 +38,10 @@ namespace Avalonia.Win32.OpenGl
[MemberNotNullWhen(true, nameof(s_wglChoosePixelFormatArb))]
[MemberNotNullWhen(true, nameof(s_wglCreateContextAttribsArb))]
[MemberNotNullWhen(true, nameof(s_glDebugMessageCallback))]
private static bool Initialize() => _initialized ??= InitializeCore();
[MemberNotNullWhen(true, nameof(s_wglChoosePixelFormatArb))]
[MemberNotNullWhen(true, nameof(s_wglCreateContextAttribsArb))]
[MemberNotNullWhen(true, nameof(s_glDebugMessageCallback))]
private static bool InitializeCore()
{
Dispatcher.UIThread.VerifyAccess();
@ -74,9 +72,9 @@ namespace Avalonia.Win32.OpenGl
Marshal.GetDelegateForFunctionPointer<WglChoosePixelFormatARBDelegate>(
wglGetProcAddress("wglChoosePixelFormatARB"));
s_glDebugMessageCallback =
Marshal.GetDelegateForFunctionPointer<GlDebugMessageCallbackDelegate>(
wglGetProcAddress("glDebugMessageCallback"));
s_glDebugMessageCallback = wglGetProcAddress("glDebugMessageCallback") is { } setDebugCallback && setDebugCallback != default ?
Marshal.GetDelegateForFunctionPointer<GlDebugMessageCallbackDelegate>(setDebugCallback) :
null;
var formats = new int[1];
@ -144,8 +142,12 @@ namespace Avalonia.Win32.OpenGl
});
}
using(new WglRestoreContext(dc, context, null))
s_glDebugMessageCallback(Marshal.GetFunctionPointerForDelegate(_debugCallback), IntPtr.Zero);
if (s_glDebugMessageCallback is not null)
{
using (new WglRestoreContext(dc, context, null))
s_glDebugMessageCallback(Marshal.GetFunctionPointerForDelegate(_debugCallback), IntPtr.Zero);
}
if (context != IntPtr.Zero)
return new WglContext(shareContext, version, context, window, dc,
_defaultPixelFormat, _defaultPfd);

4
src/Windows/Avalonia.Win32/Win32GlManager.cs

@ -20,6 +20,10 @@ static class Win32GlManager
{
AvaloniaLocator.CurrentMutable.Bind<IPlatformGraphics>().ToConstant(gl);
}
if (gl is IPlatformGraphicsOpenGlContextFactory openGlFactory)
{
AvaloniaLocator.CurrentMutable.Bind<IPlatformGraphicsOpenGlContextFactory>().ToConstant(openGlFactory);
}
return gl;
}

8
src/tools/Avalonia.Generators/NameGenerator/AvaloniaNameGenerator.cs

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Avalonia.Generators.Common.Domain;
using Microsoft.CodeAnalysis;
@ -31,7 +32,7 @@ internal class AvaloniaNameGenerator : INameGenerator
_code = code;
}
public IReadOnlyList<GeneratedPartialClass> GenerateNameReferences(IEnumerable<AdditionalText> additionalFiles)
public IEnumerable<GeneratedPartialClass> GenerateNameReferences(IEnumerable<AdditionalText> additionalFiles, CancellationToken cancellationToken)
{
var resolveViews =
from file in additionalFiles
@ -39,7 +40,8 @@ internal class AvaloniaNameGenerator : INameGenerator
file.Path.EndsWith(".paml") ||
file.Path.EndsWith(".axaml")) &&
_pathPattern.Matches(file.Path)
let xaml = file.GetText()!.ToString()
let xaml = file.GetText(cancellationToken)?.ToString()
where xaml != null
let view = _classes.ResolveView(xaml)
where view != null && _namespacePattern.Matches(view.Namespace)
select view;
@ -51,7 +53,7 @@ internal class AvaloniaNameGenerator : INameGenerator
let fileName = ResolveViewFileName(view, _naming)
select new GeneratedPartialClass(fileName, code);
return query.ToList();
return query;
}
private static string ResolveViewFileName(ResolvedView view, ViewFileNamingStrategy strategy) => strategy switch

15
src/tools/Avalonia.Generators/NameGenerator/AvaloniaNameSourceGenerator.cs

@ -22,8 +22,19 @@ public class AvaloniaNameSourceGenerator : ISourceGenerator
return;
}
var partials = generator.GenerateNameReferences(context.AdditionalFiles);
foreach (var (fileName, content) in partials) context.AddSource(fileName, content);
var partials = generator.GenerateNameReferences(context.AdditionalFiles, context.CancellationToken);
foreach (var (fileName, content) in partials)
{
if(context.CancellationToken.IsCancellationRequested)
{
break;
}
context.AddSource(fileName, content);
}
}
catch (OperationCanceledException)
{
}
catch (Exception exception)
{

3
src/tools/Avalonia.Generators/NameGenerator/INameGenerator.cs

@ -1,11 +1,12 @@
using System.Collections.Generic;
using System.Threading;
using Microsoft.CodeAnalysis;
namespace Avalonia.Generators.NameGenerator;
internal interface INameGenerator
{
IReadOnlyList<GeneratedPartialClass> GenerateNameReferences(IEnumerable<AdditionalText> additionalFiles);
IEnumerable<GeneratedPartialClass> GenerateNameReferences(IEnumerable<AdditionalText> additionalFiles, CancellationToken cancellationToken);
}
internal record GeneratedPartialClass(string FileName, string Content);

53
tests/Avalonia.Base.UnitTests/Utilities/InlineDictionaryTests.cs

@ -0,0 +1,53 @@
#nullable enable
using System.Collections.Generic;
using Avalonia.Utilities;
using Xunit;
namespace Avalonia.Base.UnitTests.Utilities;
public class InlineDictionaryTests
{
[Fact]
public void Enumeration_After_Add_With_Internal_Array_Works()
{
var dic = new InlineDictionary<string, int>();
dic.Add("foo", 1);
dic.Add("bar", 2);
dic.Add("baz", 3);
Assert.Equal(
new[] {
new KeyValuePair<string, int>("foo", 1),
new KeyValuePair<string, int>("bar", 2),
new KeyValuePair<string, int>("baz", 3)
},
dic);
}
[Fact]
public void Enumeration_After_Remove_With_Internal_Array_Works()
{
var dic = new InlineDictionary<string, int>();
dic.Add("foo", 1);
dic.Add("bar", 2);
dic.Add("baz", 3);
Assert.Equal(
new[] {
new KeyValuePair<string, int>("foo", 1),
new KeyValuePair<string, int>("bar", 2),
new KeyValuePair<string, int>("baz", 3)
},
dic);
dic.Remove("bar");
Assert.Equal(
new[] {
new KeyValuePair<string, int>("foo", 1),
new KeyValuePair<string, int>("baz", 3)
},
dic);
}
}

37
tests/Avalonia.Controls.UnitTests/AutoCompleteBoxTests.cs

@ -1,21 +1,15 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Templates;
using Avalonia.Data;
using Avalonia.Markup.Data;
using Avalonia.Platform;
using Avalonia.Threading;
using Avalonia.UnitTests;
using Moq;
using Xunit;
using System.Collections.ObjectModel;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using Avalonia.Input;
namespace Avalonia.Controls.UnitTests
{
@ -439,6 +433,29 @@ namespace Avalonia.Controls.UnitTests
});
}
[Fact]
public void Explicit_Dropdown_Open_Request_MinimumPrefixLength_0()
{
RunTest((control, textbox) =>
{
control.Text = "";
control.MinimumPrefixLength = 0;
Dispatcher.UIThread.RunJobs();
Assert.False(control.IsDropDownOpen);
control.RaiseEvent(new KeyEventArgs
{
RoutedEvent = InputElement.KeyDownEvent,
Key = Key.Down
});
Dispatcher.UIThread.RunJobs();
Assert.True(control.IsDropDownOpen);
});
}
/// <summary>
/// Retrieves a defined predicate filter through a new AutoCompleteBox
/// control instance.
@ -1072,14 +1089,14 @@ namespace Avalonia.Controls.UnitTests
private AutoCompleteBox CreateControl()
{
var datePicker =
var autoCompleteBox =
new AutoCompleteBox
{
Template = CreateTemplate()
};
datePicker.ApplyTemplate();
return datePicker;
autoCompleteBox.ApplyTemplate();
return autoCompleteBox;
}
private TextBox GetTextBox(AutoCompleteBox control)
{

1
tests/Avalonia.UnitTests/TestRoot.cs

@ -35,7 +35,6 @@ namespace Avalonia.UnitTests
public TestRoot(Control child)
: this(false, child)
{
Child = child;
}
public TestRoot(bool useGlobalStyles, Control child)

Loading…
Cancel
Save