Browse Source

Merge pull request #9480 from AvaloniaUI/enable-trimming

Enable trimming and fix errors in multiple projects
pull/9629/head
Max Katz 4 years ago
committed by GitHub
parent
commit
567a38ec72
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      .editorconfig
  2. 6
      Avalonia.sln
  3. 2
      build/SharedVersion.props
  4. 16
      build/TrimmingEnable.props
  5. 1
      nukebuild/Build.cs
  6. 2
      nukebuild/_build.csproj
  7. 1
      src/Android/Avalonia.Android/Avalonia.Android.csproj
  8. 2
      src/Avalonia.Base/Animation/Animation.cs
  9. 4
      src/Avalonia.Base/Animation/AnimatorKeyFrame.cs
  10. 10
      src/Avalonia.Base/Avalonia.Base.csproj
  11. 2
      src/Avalonia.Base/AvaloniaProperty.cs
  12. 2
      src/Avalonia.Base/AvaloniaPropertyRegistry.cs
  13. 2
      src/Avalonia.Base/AvaloniaProperty`1.cs
  14. 4
      src/Avalonia.Base/Collections/AvaloniaListConverter.cs
  15. 121
      src/Avalonia.Base/Compatibility/TrimmingAttributes.cs
  16. 3
      src/Avalonia.Base/Data/BindingValue.cs
  17. 2
      src/Avalonia.Base/Data/Converters/DefaultValueConverter.cs
  18. 2
      src/Avalonia.Base/Data/Converters/MethodToCommandConverter.cs
  19. 2
      src/Avalonia.Base/Data/Core/BindingExpression.cs
  20. 5
      src/Avalonia.Base/Data/Core/ExpressionObserver.cs
  21. 4
      src/Avalonia.Base/Data/Core/Parsers/ExpressionTreeParser.cs
  22. 2
      src/Avalonia.Base/Data/Core/Parsers/ExpressionVisitorNodeBuilder.cs
  23. 3
      src/Avalonia.Base/Data/Core/Plugins/AvaloniaPropertyAccessorPlugin.cs
  24. 4
      src/Avalonia.Base/Data/Core/Plugins/DataAnnotationsValidationPlugin.cs
  25. 3
      src/Avalonia.Base/Data/Core/Plugins/ExceptionValidationPlugin.cs
  26. 3
      src/Avalonia.Base/Data/Core/Plugins/IDataValidationPlugin.cs
  27. 3
      src/Avalonia.Base/Data/Core/Plugins/IPropertyAccessorPlugin.cs
  28. 3
      src/Avalonia.Base/Data/Core/Plugins/IStreamPlugin.cs
  29. 3
      src/Avalonia.Base/Data/Core/Plugins/IndeiValidationPlugin.cs
  30. 10
      src/Avalonia.Base/Data/Core/Plugins/InpcPropertyAccessorPlugin.cs
  31. 9
      src/Avalonia.Base/Data/Core/Plugins/MethodAccessorPlugin.cs
  32. 5
      src/Avalonia.Base/Data/Core/Plugins/ObservableStreamPlugin.cs
  33. 7
      src/Avalonia.Base/Data/Core/Plugins/TaskStreamPlugin.cs
  34. 3
      src/Avalonia.Base/Data/Core/PropertyAccessorNode.cs
  35. 2
      src/Avalonia.Base/Data/Core/StreamNode.cs
  36. 30
      src/Avalonia.Base/Diagnostics/TrimmingMessages.cs
  37. 2
      src/Avalonia.Base/PropertyStore/DirectUntypedBindingObserver.cs
  38. 2
      src/Avalonia.Base/PropertyStore/UntypedValueUtils.cs
  39. 2
      src/Avalonia.Base/StyledPropertyBase.cs
  40. 5
      src/Avalonia.Base/Styling/PropertyEqualsSelector.cs
  41. 2
      src/Avalonia.Base/Styling/Setter.cs
  42. 3
      src/Avalonia.Base/Utilities/AvaloniaResourcesIndex.cs
  43. 13
      src/Avalonia.Base/Utilities/TypeUtilities.cs
  44. 8
      src/Avalonia.Base/Utilities/WeakEventHandlerManager.cs
  45. 3
      src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj
  46. 1
      src/Avalonia.Controls.ColorPicker/Avalonia.Controls.ColorPicker.csproj
  47. 50
      src/Avalonia.Controls/AppBuilderBase.cs
  48. 1
      src/Avalonia.Controls/Avalonia.Controls.csproj
  49. 12
      src/Avalonia.Controls/NativeMenuBar.cs
  50. 2
      src/Avalonia.DesignerSupport/Avalonia.DesignerSupport.csproj
  51. 13
      src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs
  52. 4
      src/Avalonia.Desktop/Avalonia.Desktop.csproj
  53. 1
      src/Avalonia.Dialogs/Avalonia.Dialogs.csproj
  54. 1
      src/Avalonia.Headless.Vnc/Avalonia.Headless.Vnc.csproj
  55. 6
      src/Avalonia.Headless/Avalonia.Headless.csproj
  56. 2
      src/Avalonia.MicroCom/Avalonia.MicroCom.csproj
  57. 2
      src/Avalonia.MicroCom/CallbackBase.cs
  58. 1
      src/Avalonia.Native/Avalonia.Native.csproj
  59. 1
      src/Avalonia.OpenGL/Avalonia.OpenGL.csproj
  60. 1
      src/Avalonia.ReactiveUI/Avalonia.ReactiveUI.csproj
  61. 2
      src/Avalonia.Remote.Protocol/Avalonia.Remote.Protocol.csproj
  62. 2
      src/Avalonia.Remote.Protocol/BsonStreamTransport.cs
  63. 4
      src/Avalonia.Remote.Protocol/BsonTcpTransport.cs
  64. 4
      src/Avalonia.Remote.Protocol/DefaultMessageTypeResolver.cs
  65. 11
      src/Avalonia.Remote.Protocol/MetsysBson.cs
  66. 3
      src/Avalonia.Themes.Fluent/Avalonia.Themes.Fluent.csproj
  67. 3
      src/Avalonia.Themes.Simple/Avalonia.Themes.Simple.csproj
  68. 1
      src/Avalonia.X11/Avalonia.X11.csproj
  69. 4
      src/Avalonia.X11/X11Structs.cs
  70. 1
      src/Browser/Avalonia.Browser.Blazor/Avalonia.Browser.Blazor.csproj
  71. 1
      src/Browser/Avalonia.Browser/Avalonia.Browser.csproj
  72. 3
      src/Linux/Avalonia.LinuxFramebuffer/Avalonia.LinuxFramebuffer.csproj
  73. 3
      src/Markup/Avalonia.Markup.Xaml.Loader/Avalonia.Markup.Xaml.Loader.csproj
  74. 8
      src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
  75. 5
      src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs
  76. 3
      src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaPropertyTypeConverter.cs
  77. 2
      src/Markup/Avalonia.Markup.Xaml/Extensions.cs
  78. 3
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/ArrayElementPlugin.cs
  79. 3
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/CommandAccessorPlugin.cs
  80. 2
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/CompiledBindingPath.cs
  81. 3
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/MethodAccessorPlugin.cs
  82. 3
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/ObservableStreamPlugin.cs
  83. 3
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/PropertyInfoAccessorPlugin.cs
  84. 3
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/TaskStreamPlugin.cs
  85. 11
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ReflectionBindingExtension.cs
  86. 4
      src/Markup/Avalonia.Markup.Xaml/Styling/ResourceInclude.cs
  87. 4
      src/Markup/Avalonia.Markup.Xaml/Styling/StyleInclude.cs
  88. 2
      src/Markup/Avalonia.Markup.Xaml/Templates/TreeDataTemplate.cs
  89. 2
      src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs
  90. 2
      src/Markup/Avalonia.Markup.Xaml/XamlTypes.cs
  91. 1
      src/Markup/Avalonia.Markup/Avalonia.Markup.csproj
  92. 2
      src/Markup/Avalonia.Markup/Data/Binding.cs
  93. 3
      src/Markup/Avalonia.Markup/Data/BindingBase.cs
  94. 6
      src/Markup/Avalonia.Markup/Markup/Parsers/ExpressionObserverBuilder.cs
  95. 2
      src/Markup/Avalonia.Markup/Markup/Parsers/ExpressionParser.cs
  96. 2
      src/Markup/Avalonia.Markup/Markup/Parsers/Nodes/StringIndexerNode.cs
  97. 3
      src/Markup/Avalonia.Markup/Markup/Parsers/SelectorParser.cs
  98. 1
      src/Skia/Avalonia.Skia/Avalonia.Skia.csproj
  99. 2
      src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj
  100. 2
      src/Windows/Avalonia.Win32/Automation/AutomationNode.cs

5
.editorconfig

@ -64,7 +64,7 @@ dotnet_naming_symbols.static_fields.applicable_kinds = field
dotnet_naming_symbols.static_fields.required_modifiers = static dotnet_naming_symbols.static_fields.required_modifiers = static
dotnet_naming_style.static_prefix_style.required_prefix = s_ dotnet_naming_style.static_prefix_style.required_prefix = s_
dotnet_naming_style.static_prefix_style.capitalization = camel_case dotnet_naming_style.static_prefix_style.capitalization = camel_case
# internal and private fields should be _camelCase # internal and private fields should be _camelCase
dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion
@ -137,6 +137,9 @@ space_within_single_line_array_initializer_braces = true
#Net Analyzer #Net Analyzer
dotnet_analyzer_diagnostic.category-Performance.severity = none #error - Uncomment when all violations are fixed. dotnet_analyzer_diagnostic.category-Performance.severity = none #error - Uncomment when all violations are fixed.
# CS1591: Missing XML comment for publicly visible type or member
dotnet_diagnostic.CS1591.severity = suggestion
# CA1304: Specify CultureInfo # CA1304: Specify CultureInfo
dotnet_diagnostic.CA1304.severity = warning dotnet_diagnostic.CA1304.severity = warning
# CA1802: Use literals where appropriate # CA1802: Use literals where appropriate

6
Avalonia.sln

@ -40,6 +40,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{A689DE
.editorconfig = .editorconfig .editorconfig = .editorconfig
src\Shared\IsExternalInit.cs = src\Shared\IsExternalInit.cs src\Shared\IsExternalInit.cs = src\Shared\IsExternalInit.cs
src\Shared\ModuleInitializer.cs = src\Shared\ModuleInitializer.cs src\Shared\ModuleInitializer.cs = src\Shared\ModuleInitializer.cs
src\Shared\NullableAttributes.cs = src\Shared\NullableAttributes.cs
src\Shared\SourceGeneratorAttributes.cs = src\Shared\SourceGeneratorAttributes.cs src\Shared\SourceGeneratorAttributes.cs = src\Shared\SourceGeneratorAttributes.cs
src\Avalonia.Base\Compatibility\StringCompatibilityExtensions.cs = src\Avalonia.Base\Compatibility\StringCompatibilityExtensions.cs src\Avalonia.Base\Compatibility\StringCompatibilityExtensions.cs = src\Avalonia.Base\Compatibility\StringCompatibilityExtensions.cs
EndProjectSection EndProjectSection
@ -119,6 +120,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{F3AC8BC1
build\SourceLink.props = build\SourceLink.props build\SourceLink.props = build\SourceLink.props
build\System.Drawing.Common.props = build\System.Drawing.Common.props build\System.Drawing.Common.props = build\System.Drawing.Common.props
build\System.Memory.props = build\System.Memory.props build\System.Memory.props = build\System.Memory.props
build\TrimmingEnable.props = build\TrimmingEnable.props
build\UnitTests.NetFX.props = build\UnitTests.NetFX.props build\UnitTests.NetFX.props = build\UnitTests.NetFX.props
build\XUnit.props = build\XUnit.props build\XUnit.props = build\XUnit.props
EndProjectSection EndProjectSection
@ -222,9 +224,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MobileSandbox.iOS", "sample
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MobileSandbox.Desktop", "samples\MobileSandbox.Desktop\MobileSandbox.Desktop.csproj", "{62D392C9-81CF-487F-92E8-598B2AF3FDCE}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MobileSandbox.Desktop", "samples\MobileSandbox.Desktop\MobileSandbox.Desktop.csproj", "{62D392C9-81CF-487F-92E8-598B2AF3FDCE}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Browser", "src\Browser\Avalonia.Browser\Avalonia.Browser.csproj", "{4A39637C-9338-4925-A4DB-D072E292EC78}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Browser", "src\Browser\Avalonia.Browser\Avalonia.Browser.csproj", "{4A39637C-9338-4925-A4DB-D072E292EC78}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Browser.Blazor", "src\Browser\Avalonia.Browser.Blazor\Avalonia.Browser.Blazor.csproj", "{47F8530C-F19B-4B1A-B4D6-EB231522AE5D}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Browser.Blazor", "src\Browser\Avalonia.Browser.Blazor\Avalonia.Browser.Blazor.csproj", "{47F8530C-F19B-4B1A-B4D6-EB231522AE5D}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog.Browser", "samples\ControlCatalog.Browser\ControlCatalog.Browser.csproj", "{15B93A4C-1B46-43F6-B534-7B25B6E99932}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog.Browser", "samples\ControlCatalog.Browser\ControlCatalog.Browser.csproj", "{15B93A4C-1B46-43F6-B534-7B25B6E99932}"
EndProject EndProject

2
build/SharedVersion.props

@ -7,7 +7,7 @@
<PackageProjectUrl>https://avaloniaui.net</PackageProjectUrl> <PackageProjectUrl>https://avaloniaui.net</PackageProjectUrl>
<RepositoryUrl>https://github.com/AvaloniaUI/Avalonia/</RepositoryUrl> <RepositoryUrl>https://github.com/AvaloniaUI/Avalonia/</RepositoryUrl>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>CS1591</NoWarn> <NoWarn>$(NoWarn);CS1591</NoWarn>
<LangVersion>preview</LangVersion> <LangVersion>preview</LangVersion>
<PackageLicenseExpression>MIT</PackageLicenseExpression> <PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageIcon>Icon.png</PackageIcon> <PackageIcon>Icon.png</PackageIcon>

16
build/TrimmingEnable.props

@ -0,0 +1,16 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>
<EnableTrimAnalyzer>true</EnableTrimAnalyzer>
<TrimmerSingleWarn>false</TrimmerSingleWarn>
<IsTrimmable>true</IsTrimmable>
</PropertyGroup>
<!-- Remove check for the AOT when we get rid of dependencies with reflection -->
<PropertyGroup Condition="'$(TargetFramework)' != 'netstandard2.0' and '$(PublishAot)' != 'true'">
<ILLinkTreatWarningsAsErrors>true</ILLinkTreatWarningsAsErrors>
<!-- Trim warnings -->
<WarningsAsErrors>$(WarningsAsErrors);IL2000;IL2001;IL2002;IL2003;IL2004;IL2005;IL2006;IL2007;IL2008;IL2009;IL2010;IL2011;IL2012;IL2013;IL2014;IL2015;IL2016;IL2017;IL2018;IL2019;IL2020;IL2021;IL2022;IL2023;IL2024;IL2025;IL2026;IL2027;IL2028;IL2029;IL2030;IL2031;IL2032;IL2033;IL2034;IL2035;IL2036;IL2037;IL2038;IL2039;IL2040;IL2041;IL2042;IL2043;IL2044;IL2045;IL2046;IL2047;IL2048;IL2049;IL2050;IL2051;IL2052;IL2053;IL2054;IL2055;IL2056;IL2057;IL2058;IL2059;IL2060;IL2061;IL2062;IL2063;IL2064;IL2065;IL2066;IL2067;IL2068;IL2069;IL2070;IL2071;IL2072;IL2073;IL2074;IL2075;IL2076;IL2077;IL2078;IL2079;IL2080;IL2081;IL2082;IL2083;IL2084;IL2085;IL2086;IL2087;IL2088;IL2089;IL2090;IL2091;IL2092;IL2093;IL2094;IL2095;IL2096;IL2097;IL2098;IL2099;IL2100;IL2101;IL2102;IL2103;IL2104;IL2105;IL2106;IL2107;IL2108;IL2109;IL2110;IL2111;IL2112;IL2113;IL2114;IL2115;IL2116;IL2117;IL2118;IL2119;IL2120;IL2121;IL2122;IL2123;IL2124;IL2125;IL2126;IL2127;IL2128;IL2129;IL2130;IL2131;IL2132;IL2133;IL2134;IL2135;IL2136;IL2137;IL2138;IL2139;IL2140;IL2141;IL2142;IL2143;IL2144;IL2145;IL2146;IL2147;IL2148;IL2149;IL2150;IL2151;IL2152;IL2153;IL2154;IL2155;IL2156;IL2157</WarningsAsErrors>
<!-- NativeAOT warnings -->
<WarningsAsErrors>$(WarningsAsErrors);IL3050;IL3051;IL3052;IL3053;IL3054;IL3055;IL3056</WarningsAsErrors>
</PropertyGroup>
</Project>

1
nukebuild/Build.cs

@ -80,7 +80,6 @@ partial class Build : NukeBuild
if (Parameters.IsRunningOnAzure) if (Parameters.IsRunningOnAzure)
c.AddProperty("JavaSdkDirectory", GetVariable<string>("JAVA_HOME_11_X64")); c.AddProperty("JavaSdkDirectory", GetVariable<string>("JAVA_HOME_11_X64"));
c.AddProperty("PackageVersion", Parameters.Version) c.AddProperty("PackageVersion", Parameters.Version)
.AddProperty("iOSRoslynPathHackRequired", true)
.SetConfiguration(Parameters.Configuration) .SetConfiguration(Parameters.Configuration)
.SetVerbosity(DotNetVerbosity.Minimal); .SetVerbosity(DotNetVerbosity.Minimal);
return c; return c;

2
nukebuild/_build.csproj

@ -4,7 +4,7 @@
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<RootNamespace></RootNamespace> <RootNamespace></RootNamespace>
<IsPackable>False</IsPackable> <IsPackable>False</IsPackable>
<NoWarn>CS0649;CS0169;SYSLIB0011</NoWarn> <NoWarn>$(NoWarn);CS0649;CS0169;SYSLIB0011</NoWarn>
<NukeTelemetryVersion>1</NukeTelemetryVersion> <NukeTelemetryVersion>1</NukeTelemetryVersion>
<TargetFramework>net7.0</TargetFramework> <TargetFramework>net7.0</TargetFramework>
</PropertyGroup> </PropertyGroup>

1
src/Android/Avalonia.Android/Avalonia.Android.csproj

@ -16,4 +16,5 @@
<ProjectReference Include="..\..\Skia\Avalonia.Skia\Avalonia.Skia.csproj" /> <ProjectReference Include="..\..\Skia\Avalonia.Skia\Avalonia.Skia.csproj" />
</ItemGroup> </ItemGroup>
<Import Project="..\..\..\build\DevAnalyzers.props" /> <Import Project="..\..\..\build\DevAnalyzers.props" />
<Import Project="..\..\..\build\TrimmingEnable.props" />
</Project> </Project>

2
src/Avalonia.Base/Animation/Animation.cs

@ -202,9 +202,7 @@ namespace Avalonia.Animation
/// <param name="setter">The animation setter.</param> /// <param name="setter">The animation setter.</param>
/// <param name="value">The property animator value.</param> /// <param name="value">The property animator value.</param>
public static void SetAnimator(IAnimationSetter setter, public static void SetAnimator(IAnimationSetter setter,
#if NET6_0_OR_GREATER
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.PublicMethods)] [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.PublicMethods)]
#endif
Type value) Type value)
{ {
s_animators[setter] = (value, () => (IAnimator)Activator.CreateInstance(value)!); s_animators[setter] = (value, () => (IAnimator)Activator.CreateInstance(value)!);

4
src/Avalonia.Base/Animation/AnimatorKeyFrame.cs

@ -1,5 +1,6 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using Avalonia.Animation.Animators; using Avalonia.Animation.Animators;
using Avalonia.Data; using Avalonia.Data;
using Avalonia.Reactive; using Avalonia.Reactive;
@ -66,7 +67,8 @@ namespace Avalonia.Animation
} }
} }
public T GetTypedValue<T>() [RequiresUnreferencedCode(TrimmingMessages.TypeConvertionRequiresUnreferencedCodeMessage)]
public T GetTypedValue<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>()
{ {
var typeConv = TypeDescriptor.GetConverter(typeof(T)); var typeConv = TypeDescriptor.GetConverter(typeof(T));

10
src/Avalonia.Base/Avalonia.Base.csproj

@ -19,6 +19,7 @@
<Import Project="..\..\build\System.Memory.props" /> <Import Project="..\..\build\System.Memory.props" />
<Import Project="..\..\build\ApiDiff.props" /> <Import Project="..\..\build\ApiDiff.props" />
<Import Project="..\..\build\NullableEnable.props" /> <Import Project="..\..\build\NullableEnable.props" />
<Import Project="..\..\build\TrimmingEnable.props" />
<Import Project="..\..\build\DevAnalyzers.props" /> <Import Project="..\..\build\DevAnalyzers.props" />
<Import Project="..\..\build\SourceGenerators.props" /> <Import Project="..\..\build\SourceGenerators.props" />
<ItemGroup> <ItemGroup>
@ -30,6 +31,8 @@
<InternalsVisibleTo Include="Avalonia.Base.UnitTests, PublicKey=$(AvaloniaPublicKey)" /> <InternalsVisibleTo Include="Avalonia.Base.UnitTests, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Benchmarks, PublicKey=$(AvaloniaPublicKey)" /> <InternalsVisibleTo Include="Avalonia.Benchmarks, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Controls, PublicKey=$(AvaloniaPublicKey)" /> <InternalsVisibleTo Include="Avalonia.Controls, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Markup, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Markup.Xaml, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Controls.ColorPicker, PublicKey=$(AvaloniaPublicKey)" /> <InternalsVisibleTo Include="Avalonia.Controls.ColorPicker, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Controls.DataGrid, PublicKey=$(AvaloniaPublicKey)" /> <InternalsVisibleTo Include="Avalonia.Controls.DataGrid, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Controls.UnitTests, PublicKey=$(AvaloniaPublicKey)" /> <InternalsVisibleTo Include="Avalonia.Controls.UnitTests, PublicKey=$(AvaloniaPublicKey)" />
@ -41,6 +44,7 @@
<InternalsVisibleTo Include="Avalonia.Skia.UnitTests, PublicKey=$(AvaloniaPublicKey)" /> <InternalsVisibleTo Include="Avalonia.Skia.UnitTests, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.UnitTests, PublicKey=$(AvaloniaPublicKey)" /> <InternalsVisibleTo Include="Avalonia.UnitTests, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Benchmarks, PublicKey=$(AvaloniaPublicKey)" /> <InternalsVisibleTo Include="Avalonia.Benchmarks, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.X11, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Win32, PublicKey=$(AvaloniaPublicKey)" /> <InternalsVisibleTo Include="Avalonia.Win32, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Dialogs, PublicKey=$(AvaloniaPublicKey)" /> <InternalsVisibleTo Include="Avalonia.Dialogs, PublicKey=$(AvaloniaPublicKey)" />
<InternalsVisibleTo Include="Avalonia.Diagnostics, PublicKey=$(AvaloniaPublicKey)" /> <InternalsVisibleTo Include="Avalonia.Diagnostics, PublicKey=$(AvaloniaPublicKey)" />
@ -48,14 +52,10 @@
</ItemGroup> </ItemGroup>
<ItemGroup Label="Build dependency"> <ItemGroup Label="Build dependency">
<ProjectReference Include="$(MSBuildThisFileDirectory)\..\Avalonia.Build.Tasks\Avalonia.Build.Tasks.csproj" <ProjectReference Include="$(MSBuildThisFileDirectory)\..\Avalonia.Build.Tasks\Avalonia.Build.Tasks.csproj" SetTargetFramework="TargetFramework=netstandard2.0" ReferenceOutputAssembly="false" SkipGetTargetFrameworkProperties="true" />
SetTargetFramework="TargetFramework=netstandard2.0"
ReferenceOutputAssembly="false"
SkipGetTargetFrameworkProperties="true" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Compatibility\" />
<Folder Include="Rendering\Composition\Utils" /> <Folder Include="Rendering\Composition\Utils" />
</ItemGroup> </ItemGroup>
</Project> </Project>

2
src/Avalonia.Base/AvaloniaProperty.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Avalonia.Data; using Avalonia.Data;
using Avalonia.Data.Core; using Avalonia.Data.Core;
using Avalonia.PropertyStore; using Avalonia.PropertyStore;
@ -442,6 +443,7 @@ namespace Avalonia
/// </summary> /// </summary>
/// <param name="value">The value.</param> /// <param name="value">The value.</param>
/// <returns>True if the value is valid, otherwise false.</returns> /// <returns>True if the value is valid, otherwise false.</returns>
[RequiresUnreferencedCode(TrimmingMessages.ImplicitTypeConvertionRequiresUnreferencedCodeMessage)]
public bool IsValidValue(object? value) public bool IsValidValue(object? value)
{ {
return TypeUtilities.TryConvertImplicit(PropertyType, value, out _); return TypeUtilities.TryConvertImplicit(PropertyType, value, out _);

2
src/Avalonia.Base/AvaloniaPropertyRegistry.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
namespace Avalonia namespace Avalonia
@ -42,6 +43,7 @@ namespace Avalonia
/// </summary> /// </summary>
/// <param name="type">The type.</param> /// <param name="type">The type.</param>
/// <returns>A collection of <see cref="AvaloniaProperty"/> definitions.</returns> /// <returns>A collection of <see cref="AvaloniaProperty"/> definitions.</returns>
[UnconditionalSuppressMessage("Trimming", "IL2059", Justification = "If type was trimmed out, no properties were referenced")]
public IReadOnlyList<AvaloniaProperty> GetRegistered(Type type) public IReadOnlyList<AvaloniaProperty> GetRegistered(Type type)
{ {
_ = type ?? throw new ArgumentNullException(nameof(type)); _ = type ?? throw new ArgumentNullException(nameof(type));

2
src/Avalonia.Base/AvaloniaProperty`1.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.Reactive.Subjects; using System.Reactive.Subjects;
using Avalonia.Data; using Avalonia.Data;
using Avalonia.Utilities; using Avalonia.Utilities;
@ -67,6 +68,7 @@ namespace Avalonia
protected override IObservable<AvaloniaPropertyChangedEventArgs> GetChanged() => Changed; protected override IObservable<AvaloniaPropertyChangedEventArgs> GetChanged() => Changed;
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.ImplicitTypeConvertionSupressWarningMessage)]
protected BindingValue<object?> TryConvert(object? value) protected BindingValue<object?> TryConvert(object? value)
{ {
if (value == UnsetValue) if (value == UnsetValue)

4
src/Avalonia.Base/Collections/AvaloniaListConverter.cs

@ -1,5 +1,6 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization; using System.Globalization;
using Avalonia.Utilities; using Avalonia.Utilities;
@ -8,7 +9,8 @@ namespace Avalonia.Collections
/// <summary> /// <summary>
/// Creates an <see cref="AvaloniaList{T}"/> from a string representation. /// Creates an <see cref="AvaloniaList{T}"/> from a string representation.
/// </summary> /// </summary>
public class AvaloniaListConverter<T> : TypeConverter [RequiresUnreferencedCode(TrimmingMessages.TypeConvertionRequiresUnreferencedCodeMessage)]
public class AvaloniaListConverter<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T> : TypeConverter
{ {
public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType) public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
{ {

121
src/Avalonia.Base/Compatibility/TrimmingAttributes.cs

@ -0,0 +1,121 @@
#pragma warning disable MA0048 // File name must match type name
// https://github.com/dotnet/runtime/tree/main/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace System.Diagnostics.CodeAnalysis
{
#nullable enable
#if !NET6_0_OR_GREATER
[AttributeUsage(
AttributeTargets.Field | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter |
AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Method |
AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct,
Inherited = false)]
internal sealed class DynamicallyAccessedMembersAttribute : Attribute
{
public DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes memberTypes)
{
MemberTypes = memberTypes;
}
public DynamicallyAccessedMemberTypes MemberTypes { get; }
}
[Flags]
internal enum DynamicallyAccessedMemberTypes
{
None = 0,
PublicParameterlessConstructor = 0x0001,
PublicConstructors = 0x0002 | PublicParameterlessConstructor,
NonPublicConstructors = 0x0004,
PublicMethods = 0x0008,
NonPublicMethods = 0x0010,
PublicFields = 0x0020,
NonPublicFields = 0x0040,
PublicNestedTypes = 0x0080,
NonPublicNestedTypes = 0x0100,
PublicProperties = 0x0200,
NonPublicProperties = 0x0400,
PublicEvents = 0x0800,
NonPublicEvents = 0x1000,
Interfaces = 0x2000,
All = ~None
}
[AttributeUsage(
AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Method,
AllowMultiple = true, Inherited = false)]
internal sealed class DynamicDependencyAttribute : Attribute
{
public DynamicDependencyAttribute(string memberSignature)
{
MemberSignature = memberSignature;
}
public DynamicDependencyAttribute(string memberSignature, Type type)
{
MemberSignature = memberSignature;
Type = type;
}
public DynamicDependencyAttribute(string memberSignature, string typeName, string assemblyName)
{
MemberSignature = memberSignature;
TypeName = typeName;
AssemblyName = assemblyName;
}
public DynamicDependencyAttribute(DynamicallyAccessedMemberTypes memberTypes, Type type)
{
MemberTypes = memberTypes;
Type = type;
}
public DynamicDependencyAttribute(DynamicallyAccessedMemberTypes memberTypes, string typeName, string assemblyName)
{
MemberTypes = memberTypes;
TypeName = typeName;
AssemblyName = assemblyName;
}
public string? MemberSignature { get; }
public DynamicallyAccessedMemberTypes MemberTypes { get; }
public Type? Type { get; }
public string? TypeName { get; }
public string? AssemblyName { get; }
public string? Condition { get; set; }
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class, Inherited = false)]
internal sealed class RequiresUnreferencedCodeAttribute : Attribute
{
public RequiresUnreferencedCodeAttribute(string message)
{
Message = message;
}
public string Message { get; }
public string? Url { get; set; }
}
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
internal sealed class UnconditionalSuppressMessageAttribute : Attribute
{
public UnconditionalSuppressMessageAttribute(string category, string checkId)
{
Category = category;
CheckId = checkId;
}
public string Category { get; }
public string CheckId { get; }
public string? Scope { get; set; }
public string? Target { get; set; }
public string? MessageId { get; set; }
public string? Justification { get; set; }
}
#endif
}

3
src/Avalonia.Base/Data/BindingValue.cs

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using Avalonia.Utilities; using Avalonia.Utilities;
namespace Avalonia.Data namespace Avalonia.Data
@ -236,6 +237,7 @@ namespace Avalonia.Data
/// </summary> /// </summary>
/// <param name="value">The untyped value.</param> /// <param name="value">The untyped value.</param>
/// <returns>The typed binding value.</returns> /// <returns>The typed binding value.</returns>
[RequiresUnreferencedCode(TrimmingMessages.ImplicitTypeConvertionRequiresUnreferencedCodeMessage)]
public static BindingValue<T> FromUntyped(object? value) public static BindingValue<T> FromUntyped(object? value)
{ {
return FromUntyped(value, typeof(T)); return FromUntyped(value, typeof(T));
@ -249,6 +251,7 @@ namespace Avalonia.Data
/// <param name="value">The untyped value.</param> /// <param name="value">The untyped value.</param>
/// <param name="targetType">The runtime target type.</param> /// <param name="targetType">The runtime target type.</param>
/// <returns>The typed binding value.</returns> /// <returns>The typed binding value.</returns>
[RequiresUnreferencedCode(TrimmingMessages.ImplicitTypeConvertionRequiresUnreferencedCodeMessage)]
public static BindingValue<T> FromUntyped(object? value, Type targetType) public static BindingValue<T> FromUntyped(object? value, Type targetType)
{ {
if (value == AvaloniaProperty.UnsetValue) if (value == AvaloniaProperty.UnsetValue)

2
src/Avalonia.Base/Data/Converters/DefaultValueConverter.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization; using System.Globalization;
using System.Windows.Input; using System.Windows.Input;
using Avalonia.Utilities; using Avalonia.Utilities;
@ -9,6 +10,7 @@ namespace Avalonia.Data.Converters
/// Provides a default set of value conversions for bindings that do not specify a value /// Provides a default set of value conversions for bindings that do not specify a value
/// converter. /// converter.
/// </summary> /// </summary>
[RequiresUnreferencedCode(TrimmingMessages.TypeConvertionRequiresUnreferencedCodeMessage)]
public class DefaultValueConverter : IValueConverter public class DefaultValueConverter : IValueConverter
{ {
/// <summary> /// <summary>

2
src/Avalonia.Base/Data/Converters/MethodToCommandConverter.cs

@ -1,5 +1,6 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
@ -9,6 +10,7 @@ using Avalonia.Utilities;
namespace Avalonia.Data.Converters namespace Avalonia.Data.Converters
{ {
[RequiresUnreferencedCode(TrimmingMessages.ReflectionBindingRequiresUnreferencedCodeMessage)]
class MethodToCommandConverter : ICommand class MethodToCommandConverter : ICommand
{ {
readonly static Func<object?, bool> AlwaysEnabled = (_) => true; readonly static Func<object?, bool> AlwaysEnabled = (_) => true;

2
src/Avalonia.Base/Data/Core/BindingExpression.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization; using System.Globalization;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Reactive.Subjects; using System.Reactive.Subjects;
@ -13,6 +14,7 @@ namespace Avalonia.Data.Core
/// Binds to an expression on an object using a type value converter to convert the values /// Binds to an expression on an object using a type value converter to convert the values
/// that are sent and received. /// that are sent and received.
/// </summary> /// </summary>
[RequiresUnreferencedCode(TrimmingMessages.TypeConvertionRequiresUnreferencedCodeMessage)]
public class BindingExpression : LightweightObservableBase<object?>, ISubject<object?>, IDescription public class BindingExpression : LightweightObservableBase<object?>, ISubject<object?>, IDescription
{ {
private readonly ExpressionObserver _inner; private readonly ExpressionObserver _inner;

5
src/Avalonia.Base/Data/Core/ExpressionObserver.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Reactive; using System.Reactive;
using System.Reactive.Linq; using System.Reactive.Linq;
@ -126,6 +127,7 @@ namespace Avalonia.Data.Core
/// <param name="description"> /// <param name="description">
/// A description of the expression. If null, <paramref name="expression"/>'s string representation will be used. /// A description of the expression. If null, <paramref name="expression"/>'s string representation will be used.
/// </param> /// </param>
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.ExpressionSafeSupressWarningMessage)]
public static ExpressionObserver Create<T, U>( public static ExpressionObserver Create<T, U>(
T? root, T? root,
Expression<Func<T, U>> expression, Expression<Func<T, U>> expression,
@ -144,6 +146,7 @@ namespace Avalonia.Data.Core
/// <param name="description"> /// <param name="description">
/// A description of the expression. If null, <paramref name="expression"/>'s string representation will be used. /// A description of the expression. If null, <paramref name="expression"/>'s string representation will be used.
/// </param> /// </param>
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.ExpressionSafeSupressWarningMessage)]
public static ExpressionObserver Create<T, U>( public static ExpressionObserver Create<T, U>(
IObservable<T> rootObservable, IObservable<T> rootObservable,
Expression<Func<T, U>> expression, Expression<Func<T, U>> expression,
@ -168,6 +171,7 @@ namespace Avalonia.Data.Core
/// <param name="description"> /// <param name="description">
/// A description of the expression. If null, <paramref name="expression"/>'s string representation will be used. /// A description of the expression. If null, <paramref name="expression"/>'s string representation will be used.
/// </param> /// </param>
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.ExpressionSafeSupressWarningMessage)]
public static ExpressionObserver Create<T, U>( public static ExpressionObserver Create<T, U>(
Func<T> rootGetter, Func<T> rootGetter,
Expression<Func<T, U>> expression, Expression<Func<T, U>> expression,
@ -283,6 +287,7 @@ namespace Avalonia.Data.Core
} }
} }
[RequiresUnreferencedCode(TrimmingMessages.ExpressionNodeRequiresUnreferencedCodeMessage)]
private static ExpressionNode Parse(LambdaExpression expression, bool enableDataValidation) private static ExpressionNode Parse(LambdaExpression expression, bool enableDataValidation)
{ {
return ExpressionTreeParser.Parse(expression, enableDataValidation); return ExpressionTreeParser.Parse(expression, enableDataValidation);

4
src/Avalonia.Base/Data/Core/Parsers/ExpressionTreeParser.cs

@ -1,10 +1,12 @@
using System.Linq; using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
namespace Avalonia.Data.Core.Parsers namespace Avalonia.Data.Core.Parsers
{ {
static class ExpressionTreeParser static class ExpressionTreeParser
{ {
[RequiresUnreferencedCode(TrimmingMessages.ExpressionNodeRequiresUnreferencedCodeMessage)]
public static ExpressionNode Parse(Expression expr, bool enableDataValidation) public static ExpressionNode Parse(Expression expr, bool enableDataValidation)
{ {
var visitor = new ExpressionVisitorNodeBuilder(enableDataValidation); var visitor = new ExpressionVisitorNodeBuilder(enableDataValidation);

2
src/Avalonia.Base/Data/Core/Parsers/ExpressionVisitorNodeBuilder.cs

@ -1,11 +1,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Reflection; using System.Reflection;
namespace Avalonia.Data.Core.Parsers namespace Avalonia.Data.Core.Parsers
{ {
[RequiresUnreferencedCode(TrimmingMessages.ExpressionNodeRequiresUnreferencedCodeMessage)]
class ExpressionVisitorNodeBuilder : ExpressionVisitor class ExpressionVisitorNodeBuilder : ExpressionVisitor
{ {
private const string MultiDimensionalArrayGetterMethodName = "Get"; private const string MultiDimensionalArrayGetterMethodName = "Get";

3
src/Avalonia.Base/Data/Core/Plugins/AvaloniaPropertyAccessorPlugin.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.ExceptionServices; using System.Runtime.ExceptionServices;
using Avalonia.Utilities; using Avalonia.Utilities;
@ -10,6 +11,7 @@ namespace Avalonia.Data.Core.Plugins
public class AvaloniaPropertyAccessorPlugin : IPropertyAccessorPlugin public class AvaloniaPropertyAccessorPlugin : IPropertyAccessorPlugin
{ {
/// <inheritdoc/> /// <inheritdoc/>
[RequiresUnreferencedCode(TrimmingMessages.PropertyAccessorsRequiresUnreferencedCodeMessage)]
public bool Match(object obj, string propertyName) public bool Match(object obj, string propertyName)
{ {
if (obj is AvaloniaObject o) if (obj is AvaloniaObject o)
@ -29,6 +31,7 @@ namespace Avalonia.Data.Core.Plugins
/// An <see cref="IPropertyAccessor"/> interface through which future interactions with the /// An <see cref="IPropertyAccessor"/> interface through which future interactions with the
/// property will be made. /// property will be made.
/// </returns> /// </returns>
[RequiresUnreferencedCode(TrimmingMessages.PropertyAccessorsRequiresUnreferencedCodeMessage)]
public IPropertyAccessor? Start(WeakReference<object?> reference, string propertyName) public IPropertyAccessor? Start(WeakReference<object?> reference, string propertyName)
{ {
_ = reference ?? throw new ArgumentNullException(nameof(reference)); _ = reference ?? throw new ArgumentNullException(nameof(reference));

4
src/Avalonia.Base/Data/Core/Plugins/DataAnnotationsValidationPlugin.cs

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
@ -12,6 +13,7 @@ namespace Avalonia.Data.Core.Plugins
public class DataAnnotationsValidationPlugin : IDataValidationPlugin public class DataAnnotationsValidationPlugin : IDataValidationPlugin
{ {
/// <inheritdoc/> /// <inheritdoc/>
[RequiresUnreferencedCode(TrimmingMessages.DataValidationPluginRequiresUnreferencedCodeMessage)]
public bool Match(WeakReference<object?> reference, string memberName) public bool Match(WeakReference<object?> reference, string memberName)
{ {
reference.TryGetTarget(out var target); reference.TryGetTarget(out var target);
@ -24,11 +26,13 @@ namespace Avalonia.Data.Core.Plugins
} }
/// <inheritdoc/> /// <inheritdoc/>
[RequiresUnreferencedCode(TrimmingMessages.DataValidationPluginRequiresUnreferencedCodeMessage)]
public IPropertyAccessor Start(WeakReference<object?> reference, string name, IPropertyAccessor inner) public IPropertyAccessor Start(WeakReference<object?> reference, string name, IPropertyAccessor inner)
{ {
return new Accessor(reference, name, inner); return new Accessor(reference, name, inner);
} }
[RequiresUnreferencedCode(TrimmingMessages.DataValidationPluginRequiresUnreferencedCodeMessage)]
private sealed class Accessor : DataValidationBase private sealed class Accessor : DataValidationBase
{ {
private readonly ValidationContext? _context; private readonly ValidationContext? _context;

3
src/Avalonia.Base/Data/Core/Plugins/ExceptionValidationPlugin.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.Reflection; using System.Reflection;
namespace Avalonia.Data.Core.Plugins namespace Avalonia.Data.Core.Plugins
@ -9,9 +10,11 @@ namespace Avalonia.Data.Core.Plugins
public class ExceptionValidationPlugin : IDataValidationPlugin public class ExceptionValidationPlugin : IDataValidationPlugin
{ {
/// <inheritdoc/> /// <inheritdoc/>
[RequiresUnreferencedCode(TrimmingMessages.DataValidationPluginRequiresUnreferencedCodeMessage)]
public bool Match(WeakReference<object?> reference, string memberName) => true; public bool Match(WeakReference<object?> reference, string memberName) => true;
/// <inheritdoc/> /// <inheritdoc/>
[RequiresUnreferencedCode(TrimmingMessages.DataValidationPluginRequiresUnreferencedCodeMessage)]
public IPropertyAccessor Start(WeakReference<object?> reference, string name, IPropertyAccessor inner) public IPropertyAccessor Start(WeakReference<object?> reference, string name, IPropertyAccessor inner)
{ {
return new Validator(reference, name, inner); return new Validator(reference, name, inner);

3
src/Avalonia.Base/Data/Core/Plugins/IDataValidationPlugin.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
namespace Avalonia.Data.Core.Plugins namespace Avalonia.Data.Core.Plugins
{ {
@ -13,6 +14,7 @@ namespace Avalonia.Data.Core.Plugins
/// <param name="reference">A weak reference to the object.</param> /// <param name="reference">A weak reference to the object.</param>
/// <param name="memberName">The name of the member to validate.</param> /// <param name="memberName">The name of the member to validate.</param>
/// <returns>True if the plugin can handle the object; otherwise false.</returns> /// <returns>True if the plugin can handle the object; otherwise false.</returns>
[RequiresUnreferencedCode(TrimmingMessages.DataValidationPluginRequiresUnreferencedCodeMessage)]
bool Match(WeakReference<object?> reference, string memberName); bool Match(WeakReference<object?> reference, string memberName);
/// <summary> /// <summary>
@ -25,6 +27,7 @@ namespace Avalonia.Data.Core.Plugins
/// An <see cref="IPropertyAccessor"/> interface through which future interactions with the /// An <see cref="IPropertyAccessor"/> interface through which future interactions with the
/// property will be made. /// property will be made.
/// </returns> /// </returns>
[RequiresUnreferencedCode(TrimmingMessages.DataValidationPluginRequiresUnreferencedCodeMessage)]
IPropertyAccessor Start(WeakReference<object?> reference, IPropertyAccessor Start(WeakReference<object?> reference,
string propertyName, string propertyName,
IPropertyAccessor inner); IPropertyAccessor inner);

3
src/Avalonia.Base/Data/Core/Plugins/IPropertyAccessorPlugin.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
namespace Avalonia.Data.Core.Plugins namespace Avalonia.Data.Core.Plugins
{ {
@ -14,6 +15,7 @@ namespace Avalonia.Data.Core.Plugins
/// <param name="obj">The object.</param> /// <param name="obj">The object.</param>
/// <param name="propertyName">The property name.</param> /// <param name="propertyName">The property name.</param>
/// <returns>True if the plugin can handle the property on the object; otherwise false.</returns> /// <returns>True if the plugin can handle the property on the object; otherwise false.</returns>
[RequiresUnreferencedCode(TrimmingMessages.PropertyAccessorsRequiresUnreferencedCodeMessage)]
bool Match(object obj, string propertyName); bool Match(object obj, string propertyName);
/// <summary> /// <summary>
@ -25,6 +27,7 @@ namespace Avalonia.Data.Core.Plugins
/// An <see cref="IPropertyAccessor"/> interface through which future interactions with the /// An <see cref="IPropertyAccessor"/> interface through which future interactions with the
/// property will be made. /// property will be made.
/// </returns> /// </returns>
[RequiresUnreferencedCode(TrimmingMessages.PropertyAccessorsRequiresUnreferencedCodeMessage)]
IPropertyAccessor? Start(WeakReference<object?> reference, IPropertyAccessor? Start(WeakReference<object?> reference,
string propertyName); string propertyName);
} }

3
src/Avalonia.Base/Data/Core/Plugins/IStreamPlugin.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
namespace Avalonia.Data.Core.Plugins namespace Avalonia.Data.Core.Plugins
{ {
@ -12,6 +13,7 @@ namespace Avalonia.Data.Core.Plugins
/// </summary> /// </summary>
/// <param name="reference">A weak reference to the value.</param> /// <param name="reference">A weak reference to the value.</param>
/// <returns>True if the plugin can handle the value; otherwise false.</returns> /// <returns>True if the plugin can handle the value; otherwise false.</returns>
[RequiresUnreferencedCode(TrimmingMessages.StreamPluginRequiresUnreferencedCodeMessage)]
bool Match(WeakReference<object?> reference); bool Match(WeakReference<object?> reference);
/// <summary> /// <summary>
@ -21,6 +23,7 @@ namespace Avalonia.Data.Core.Plugins
/// <returns> /// <returns>
/// An observable that produces the output for the value. /// An observable that produces the output for the value.
/// </returns> /// </returns>
[RequiresUnreferencedCode(TrimmingMessages.StreamPluginRequiresUnreferencedCodeMessage)]
IObservable<object?> Start(WeakReference<object?> reference); IObservable<object?> Start(WeakReference<object?> reference);
} }
} }

3
src/Avalonia.Base/Data/Core/Plugins/IndeiValidationPlugin.cs

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using Avalonia.Utilities; using Avalonia.Utilities;
@ -18,6 +19,7 @@ namespace Avalonia.Data.Core.Plugins
); );
/// <inheritdoc/> /// <inheritdoc/>
[RequiresUnreferencedCode(TrimmingMessages.DataValidationPluginRequiresUnreferencedCodeMessage)]
public bool Match(WeakReference<object?> reference, string memberName) public bool Match(WeakReference<object?> reference, string memberName)
{ {
reference.TryGetTarget(out var target); reference.TryGetTarget(out var target);
@ -26,6 +28,7 @@ namespace Avalonia.Data.Core.Plugins
} }
/// <inheritdoc/> /// <inheritdoc/>
[RequiresUnreferencedCode(TrimmingMessages.DataValidationPluginRequiresUnreferencedCodeMessage)]
public IPropertyAccessor Start(WeakReference<object?> reference, string name, IPropertyAccessor accessor) public IPropertyAccessor Start(WeakReference<object?> reference, string name, IPropertyAccessor accessor)
{ {
return new Validator(reference, name, accessor); return new Validator(reference, name, accessor);

10
src/Avalonia.Base/Data/Core/Plugins/InpcPropertyAccessorPlugin.cs

@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Reflection; using System.Reflection;
using Avalonia.Utilities; using Avalonia.Utilities;
@ -17,6 +17,7 @@ namespace Avalonia.Data.Core.Plugins
new Dictionary<(Type, string), PropertyInfo?>(); new Dictionary<(Type, string), PropertyInfo?>();
/// <inheritdoc/> /// <inheritdoc/>
[RequiresUnreferencedCode(TrimmingMessages.PropertyAccessorsRequiresUnreferencedCodeMessage)]
public bool Match(object obj, string propertyName) => GetFirstPropertyWithName(obj, propertyName) != null; public bool Match(object obj, string propertyName) => GetFirstPropertyWithName(obj, propertyName) != null;
/// <summary> /// <summary>
@ -28,6 +29,7 @@ namespace Avalonia.Data.Core.Plugins
/// An <see cref="IPropertyAccessor"/> interface through which future interactions with the /// An <see cref="IPropertyAccessor"/> interface through which future interactions with the
/// property will be made. /// property will be made.
/// </returns> /// </returns>
[RequiresUnreferencedCode(TrimmingMessages.PropertyAccessorsRequiresUnreferencedCodeMessage)]
public IPropertyAccessor? Start(WeakReference<object?> reference, string propertyName) public IPropertyAccessor? Start(WeakReference<object?> reference, string propertyName)
{ {
_ = reference ?? throw new ArgumentNullException(nameof(reference)); _ = reference ?? throw new ArgumentNullException(nameof(reference));
@ -52,7 +54,8 @@ namespace Avalonia.Data.Core.Plugins
private const BindingFlags PropertyBindingFlags = private const BindingFlags PropertyBindingFlags =
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance; BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance;
[RequiresUnreferencedCode(TrimmingMessages.PropertyAccessorsRequiresUnreferencedCodeMessage)]
private PropertyInfo? GetFirstPropertyWithName(object instance, string propertyName) private PropertyInfo? GetFirstPropertyWithName(object instance, string propertyName)
{ {
if (instance is IReflectableType reflectableType && instance is not Type) if (instance is IReflectableType reflectableType && instance is not Type)
@ -70,7 +73,8 @@ namespace Avalonia.Data.Core.Plugins
return propertyInfo; return propertyInfo;
} }
private PropertyInfo? TryFindAndCacheProperty(Type type, string propertyName) private PropertyInfo? TryFindAndCacheProperty(
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type, string propertyName)
{ {
PropertyInfo? found = null; PropertyInfo? found = null;

9
src/Avalonia.Base/Data/Core/Plugins/MethodAccessorPlugin.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Reflection; using System.Reflection;
@ -10,8 +11,10 @@ namespace Avalonia.Data.Core.Plugins
private readonly Dictionary<(Type, string), MethodInfo?> _methodLookup = private readonly Dictionary<(Type, string), MethodInfo?> _methodLookup =
new Dictionary<(Type, string), MethodInfo?>(); new Dictionary<(Type, string), MethodInfo?>();
[RequiresUnreferencedCode(TrimmingMessages.PropertyAccessorsRequiresUnreferencedCodeMessage)]
public bool Match(object obj, string methodName) => GetFirstMethodWithName(obj.GetType(), methodName) != null; public bool Match(object obj, string methodName) => GetFirstMethodWithName(obj.GetType(), methodName) != null;
[RequiresUnreferencedCode(TrimmingMessages.PropertyAccessorsRequiresUnreferencedCodeMessage)]
public IPropertyAccessor? Start(WeakReference<object?> reference, string methodName) public IPropertyAccessor? Start(WeakReference<object?> reference, string methodName)
{ {
_ = reference ?? throw new ArgumentNullException(nameof(reference)); _ = reference ?? throw new ArgumentNullException(nameof(reference));
@ -34,7 +37,8 @@ namespace Avalonia.Data.Core.Plugins
} }
} }
private MethodInfo? GetFirstMethodWithName(Type type, string methodName) private MethodInfo? GetFirstMethodWithName(
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] Type type, string methodName)
{ {
var key = (type, methodName); var key = (type, methodName);
@ -46,7 +50,8 @@ namespace Avalonia.Data.Core.Plugins
return methodInfo; return methodInfo;
} }
private MethodInfo? TryFindAndCacheMethod(Type type, string methodName) private MethodInfo? TryFindAndCacheMethod(
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] Type type, string methodName)
{ {
MethodInfo? found = null; MethodInfo? found = null;

5
src/Avalonia.Base/Data/Core/Plugins/ObservableStreamPlugin.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Reflection; using System.Reflection;
@ -8,6 +9,7 @@ namespace Avalonia.Data.Core.Plugins
/// <summary> /// <summary>
/// Handles binding to <see cref="IObservable{T}"/>s for the '^' stream binding operator. /// Handles binding to <see cref="IObservable{T}"/>s for the '^' stream binding operator.
/// </summary> /// </summary>
[UnconditionalSuppressMessage("Trimming", "IL3050", Justification = TrimmingMessages.IgnoreNativeAotSupressWarningMessage)]
public class ObservableStreamPlugin : IStreamPlugin public class ObservableStreamPlugin : IStreamPlugin
{ {
static MethodInfo? observableSelect; static MethodInfo? observableSelect;
@ -17,6 +19,7 @@ namespace Avalonia.Data.Core.Plugins
/// </summary> /// </summary>
/// <param name="reference">A weak reference to the value.</param> /// <param name="reference">A weak reference to the value.</param>
/// <returns>True if the plugin can handle the value; otherwise false.</returns> /// <returns>True if the plugin can handle the value; otherwise false.</returns>
[RequiresUnreferencedCode(TrimmingMessages.StreamPluginRequiresUnreferencedCodeMessage)]
public virtual bool Match(WeakReference<object?> reference) public virtual bool Match(WeakReference<object?> reference)
{ {
reference.TryGetTarget(out var target); reference.TryGetTarget(out var target);
@ -33,6 +36,7 @@ namespace Avalonia.Data.Core.Plugins
/// <returns> /// <returns>
/// An observable that produces the output for the value. /// An observable that produces the output for the value.
/// </returns> /// </returns>
[RequiresUnreferencedCode(TrimmingMessages.StreamPluginRequiresUnreferencedCodeMessage)]
public virtual IObservable<object?> Start(WeakReference<object?> reference) public virtual IObservable<object?> Start(WeakReference<object?> reference)
{ {
if (!reference.TryGetTarget(out var target) || target is null) if (!reference.TryGetTarget(out var target) || target is null)
@ -65,6 +69,7 @@ namespace Avalonia.Data.Core.Plugins
new object[] { target, box })!; new object[] { target, box })!;
} }
[RequiresUnreferencedCode(TrimmingMessages.StreamPluginRequiresUnreferencedCodeMessage)]
private static MethodInfo GetObservableSelect(Type source) private static MethodInfo GetObservableSelect(Type source)
{ {
return GetObservableSelect().MakeGenericMethod(source, typeof(object)); return GetObservableSelect().MakeGenericMethod(source, typeof(object));

7
src/Avalonia.Base/Data/Core/Plugins/TaskStreamPlugin.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Reactive.Subjects; using System.Reactive.Subjects;
using System.Reflection; using System.Reflection;
@ -9,6 +10,7 @@ namespace Avalonia.Data.Core.Plugins
/// <summary> /// <summary>
/// Handles binding to <see cref="Task"/>s for the '^' stream binding operator. /// Handles binding to <see cref="Task"/>s for the '^' stream binding operator.
/// </summary> /// </summary>
[UnconditionalSuppressMessage("Trimming", "IL3050", Justification = TrimmingMessages.IgnoreNativeAotSupressWarningMessage)]
public class TaskStreamPlugin : IStreamPlugin public class TaskStreamPlugin : IStreamPlugin
{ {
/// <summary> /// <summary>
@ -16,12 +18,13 @@ namespace Avalonia.Data.Core.Plugins
/// </summary> /// </summary>
/// <param name="reference">A weak reference to the value.</param> /// <param name="reference">A weak reference to the value.</param>
/// <returns>True if the plugin can handle the value; otherwise false.</returns> /// <returns>True if the plugin can handle the value; otherwise false.</returns>
[RequiresUnreferencedCode(TrimmingMessages.StreamPluginRequiresUnreferencedCodeMessage)]
public virtual bool Match(WeakReference<object?> reference) public virtual bool Match(WeakReference<object?> reference)
{ {
reference.TryGetTarget(out var target); reference.TryGetTarget(out var target);
return target is Task; return target is Task;
} }
/// <summary> /// <summary>
/// Starts producing output based on the specified value. /// Starts producing output based on the specified value.
@ -30,6 +33,7 @@ namespace Avalonia.Data.Core.Plugins
/// <returns> /// <returns>
/// An observable that produces the output for the value. /// An observable that produces the output for the value.
/// </returns> /// </returns>
[RequiresUnreferencedCode(TrimmingMessages.StreamPluginRequiresUnreferencedCodeMessage)]
public virtual IObservable<object?> Start(WeakReference<object?> reference) public virtual IObservable<object?> Start(WeakReference<object?> reference)
{ {
reference.TryGetTarget(out var target); reference.TryGetTarget(out var target);
@ -59,6 +63,7 @@ namespace Avalonia.Data.Core.Plugins
return Observable.Empty<object?>(); return Observable.Empty<object?>();
} }
[RequiresUnreferencedCode(TrimmingMessages.StreamPluginRequiresUnreferencedCodeMessage)]
private static IObservable<object?> HandleCompleted(Task task) private static IObservable<object?> HandleCompleted(Task task)
{ {
var resultProperty = task.GetType().GetRuntimeProperty("Result"); var resultProperty = task.GetType().GetRuntimeProperty("Result");

3
src/Avalonia.Base/Data/Core/PropertyAccessorNode.cs

@ -1,9 +1,10 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics.CodeAnalysis;
using Avalonia.Data.Core.Plugins; using Avalonia.Data.Core.Plugins;
namespace Avalonia.Data.Core namespace Avalonia.Data.Core
{ {
[RequiresUnreferencedCode(TrimmingMessages.ExpressionNodeRequiresUnreferencedCodeMessage)]
public class PropertyAccessorNode : SettableNode public class PropertyAccessorNode : SettableNode
{ {
private readonly bool _enableValidation; private readonly bool _enableValidation;

2
src/Avalonia.Base/Data/Core/StreamNode.cs

@ -1,9 +1,11 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.Reactive.Linq; using System.Reactive.Linq;
using Avalonia.Data.Core.Plugins; using Avalonia.Data.Core.Plugins;
namespace Avalonia.Data.Core namespace Avalonia.Data.Core
{ {
[RequiresUnreferencedCode(TrimmingMessages.ExpressionNodeRequiresUnreferencedCodeMessage)]
public class StreamNode : ExpressionNode public class StreamNode : ExpressionNode
{ {
private IStreamPlugin? _customPlugin = null; private IStreamPlugin? _customPlugin = null;

30
src/Avalonia.Base/Diagnostics/TrimmingMessages.cs

@ -0,0 +1,30 @@
namespace Avalonia;
internal static class TrimmingMessages
{
public const string ImplicitTypeConvertionSupressWarningMessage = "Implicit convertion methods might be removed by the linker. We don't have a reliable way to prevent it, except converting everything in compile time when possible.";
public const string ImplicitTypeConvertionRequiresUnreferencedCodeMessage = "Implicit convertion methods are required for type conversion.";
public const string TypeConvertionSupressWarningMessage = "Convertion methods might be removed by the linker. We don't have a reliable way to prevent it, except converting everything in compile time when possible.";
public const string TypeConvertionRequiresUnreferencedCodeMessage = "Convertion methods are required for type conversion, including op_Implicit, op_Explicit, Parse and TypeConverter.";
public const string ReflectionBindingRequiresUnreferencedCodeMessage = "BindingExpression and ReflectionBinding heavily use reflection. Consider using CompiledBindings instead.";
public const string ReflectionBindingSupressWarningMessage = "BindingExpression and ReflectionBinding internal heavily use reflection.";
public const string CompiledBindingSafeSupressWarningMessage = "CompiledBinding preserves members used in the expression tree.";
public const string ExpressionNodeRequiresUnreferencedCodeMessage = "ExpressionNode might require unreferenced code.";
public const string ExpressionSafeSupressWarningMessage = "Typed Expressions preserves members used in the expression tree.";
public const string SelectorsParseRequiresUnreferencedCodeMessage = "Selectors runtime parser might require unreferenced code. Consider using stronly typed selectors factory with 'new Style(s => s.OfType<Button>())' syntax.";
public const string PropertyAccessorsRequiresUnreferencedCodeMessage = "PropertyAccessors might require unreferenced code.";
public const string DataValidationPluginRequiresUnreferencedCodeMessage = "DataValidationPlugin might require unreferenced code.";
public const string StreamPluginRequiresUnreferencedCodeMessage = "StreamPlugin might require unreferenced code.";
public const string StyleResourceIncludeRequiresUnreferenceCodeMessage = "StyleInclude and ResourceInclude use AvaloniaXamlLoader.Load which dynamically loads referenced assembly with Avalonia resources. Note, StyleInclude and ResourceInclude defined in XAML are resolved compile time and are safe with trimming and AOT.";
public const string AvaloniaXamlLoaderRequiresUnreferenceCodeMessage = "AvaloniaXamlLoader.Load(uri, baseUri) dynamically loads referenced assembly with Avalonia resources.";
public const string XamlTypeResolvedRequiresUnreferenceCodeMessage = "XamlTypeResolver might require unreferenced code.";
public const string IgnoreNativeAotSupressWarningMessage = "This method is not supported by NativeAOT.";
}

2
src/Avalonia.Base/PropertyStore/DirectUntypedBindingObserver.cs

@ -1,9 +1,11 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using Avalonia.Data; using Avalonia.Data;
using Avalonia.Threading; using Avalonia.Threading;
namespace Avalonia.PropertyStore namespace Avalonia.PropertyStore
{ {
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.ImplicitTypeConvertionSupressWarningMessage)]
internal class DirectUntypedBindingObserver<T> : IObserver<object?>, internal class DirectUntypedBindingObserver<T> : IObserver<object?>,
IDisposable IDisposable
{ {

2
src/Avalonia.Base/PropertyStore/UntypedValueUtils.cs

@ -7,6 +7,7 @@ namespace Avalonia.PropertyStore
{ {
internal static class UntypedValueUtils internal static class UntypedValueUtils
{ {
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.ImplicitTypeConvertionSupressWarningMessage)]
public static BindingValue<T> ConvertAndValidate<T>( public static BindingValue<T> ConvertAndValidate<T>(
object? value, object? value,
Type targetType, Type targetType,
@ -23,6 +24,7 @@ namespace Avalonia.PropertyStore
return v; return v;
} }
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.ImplicitTypeConvertionSupressWarningMessage)]
public static bool TryConvertAndValidate<T>( public static bool TryConvertAndValidate<T>(
StyledPropertyBase<T> property, StyledPropertyBase<T> property,
object? value, object? value,

2
src/Avalonia.Base/StyledPropertyBase.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.Reflection; using System.Reflection;
using Avalonia.Data; using Avalonia.Data;
using Avalonia.PropertyStore; using Avalonia.PropertyStore;
@ -206,6 +207,7 @@ namespace Avalonia
} }
/// <inheritdoc/> /// <inheritdoc/>
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.ImplicitTypeConvertionSupressWarningMessage)]
internal override IDisposable? RouteSetValue( internal override IDisposable? RouteSetValue(
AvaloniaObject target, AvaloniaObject target,
object? value, object? value,

5
src/Avalonia.Base/Styling/PropertyEqualsSelector.cs

@ -1,11 +1,10 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization; using System.Globalization;
using Avalonia.Styling.Activators; using Avalonia.Styling.Activators;
using Avalonia.Utilities; using Avalonia.Utilities;
#nullable enable
namespace Avalonia.Styling namespace Avalonia.Styling
{ {
/// <summary> /// <summary>
@ -92,6 +91,8 @@ namespace Avalonia.Styling
protected override Selector? MovePrevious() => _previous; protected override Selector? MovePrevious() => _previous;
protected override Selector? MovePreviousOrParent() => _previous; protected override Selector? MovePreviousOrParent() => _previous;
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.TypeConvertionSupressWarningMessage)]
[UnconditionalSuppressMessage("Trimming", "IL2067", Justification = TrimmingMessages.TypeConvertionSupressWarningMessage)]
internal static bool Compare(Type propertyType, object? propertyValue, object? value) internal static bool Compare(Type propertyType, object? propertyValue, object? value)
{ {
if (propertyType == typeof(object) && if (propertyType == typeof(object) &&

2
src/Avalonia.Base/Styling/Setter.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using Avalonia.Animation; using Avalonia.Animation;
using Avalonia.Data; using Avalonia.Data;
using Avalonia.Metadata; using Avalonia.Metadata;
@ -64,6 +65,7 @@ namespace Avalonia.Styling
void IValueEntry.Unsubscribe() { } void IValueEntry.Unsubscribe() { }
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.ImplicitTypeConvertionSupressWarningMessage)]
ISetterInstance ISetter.Instance(IStyleInstance instance, StyledElement target) ISetterInstance ISetter.Instance(IStyleInstance instance, StyledElement target)
{ {
if (target is not AvaloniaObject ao) if (target is not AvaloniaObject ao)

3
src/Avalonia.Base/Utilities/AvaloniaResourcesIndex.cs

@ -4,6 +4,7 @@ using System.IO;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using System.Xml.Linq; using System.Xml.Linq;
using System.Linq; using System.Linq;
using System.Diagnostics.CodeAnalysis;
namespace Avalonia.Utilities namespace Avalonia.Utilities
{ {
@ -33,6 +34,7 @@ namespace Avalonia.Utilities
return entries; return entries;
} }
[RequiresUnreferencedCode("AvaloniaResources uses Data Contract Serialization, which might require unreferenced code")]
public static void Write(Stream stream, List<AvaloniaResourcesIndexEntry> entries) public static void Write(Stream stream, List<AvaloniaResourcesIndexEntry> entries)
{ {
new BinaryWriter(stream).Write(LastKnownVersion); new BinaryWriter(stream).Write(LastKnownVersion);
@ -43,6 +45,7 @@ namespace Avalonia.Utilities
}); });
} }
[RequiresUnreferencedCode("AvaloniaResources uses Data Contract Serialization, which might require unreferenced code")]
public static byte[] Create(Dictionary<string, byte[]> data) public static byte[] Create(Dictionary<string, byte[]> data)
{ {
var sources = data.ToList(); var sources = data.ToList();

13
src/Avalonia.Base/Utilities/TypeUtilities.cs

@ -1,5 +1,6 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
@ -125,6 +126,7 @@ namespace Avalonia.Utilities
/// <param name="culture">The culture to use.</param> /// <param name="culture">The culture to use.</param>
/// <param name="result">If successful, contains the convert value.</param> /// <param name="result">If successful, contains the convert value.</param>
/// <returns>True if the cast was successful, otherwise false.</returns> /// <returns>True if the cast was successful, otherwise false.</returns>
[RequiresUnreferencedCode(TrimmingMessages.TypeConvertionRequiresUnreferencedCodeMessage)]
public static bool TryConvert(Type to, object? value, CultureInfo? culture, out object? result) public static bool TryConvert(Type to, object? value, CultureInfo? culture, out object? result)
{ {
if (value == null) if (value == null)
@ -150,7 +152,7 @@ namespace Avalonia.Utilities
if (toUnderl == typeof(string)) if (toUnderl == typeof(string))
{ {
result = Convert.ToString(value, culture); result = Convert.ToString(value, culture)!;
return true; return true;
} }
@ -244,6 +246,7 @@ namespace Avalonia.Utilities
/// <param name="value">The value to convert.</param> /// <param name="value">The value to convert.</param>
/// <param name="result">If successful, contains the converted value.</param> /// <param name="result">If successful, contains the converted value.</param>
/// <returns>True if the convert was successful, otherwise false.</returns> /// <returns>True if the convert was successful, otherwise false.</returns>
[RequiresUnreferencedCode(TrimmingMessages.ImplicitTypeConvertionRequiresUnreferencedCodeMessage)]
public static bool TryConvertImplicit(Type to, object? value, out object? result) public static bool TryConvertImplicit(Type to, object? value, out object? result)
{ {
if (value == null) if (value == null)
@ -306,6 +309,7 @@ namespace Avalonia.Utilities
/// <param name="type">The type to convert to..</param> /// <param name="type">The type to convert to..</param>
/// <param name="culture">The culture to use.</param> /// <param name="culture">The culture to use.</param>
/// <returns>A value of <paramref name="type"/>.</returns> /// <returns>A value of <paramref name="type"/>.</returns>
[RequiresUnreferencedCode(TrimmingMessages.TypeConvertionRequiresUnreferencedCodeMessage)]
public static object? ConvertOrDefault(object? value, Type type, CultureInfo culture) public static object? ConvertOrDefault(object? value, Type type, CultureInfo culture)
{ {
return TryConvert(type, value, culture, out var result) ? result : Default(type); return TryConvert(type, value, culture, out var result) ? result : Default(type);
@ -318,11 +322,13 @@ namespace Avalonia.Utilities
/// <param name="value">The value to convert.</param> /// <param name="value">The value to convert.</param>
/// <param name="type">The type to convert to.</param> /// <param name="type">The type to convert to.</param>
/// <returns>A value of <paramref name="type"/>.</returns> /// <returns>A value of <paramref name="type"/>.</returns>
[RequiresUnreferencedCode(TrimmingMessages.ImplicitTypeConvertionRequiresUnreferencedCodeMessage)]
public static object? ConvertImplicitOrDefault(object? value, Type type) public static object? ConvertImplicitOrDefault(object? value, Type type)
{ {
return TryConvertImplicit(type, value, out var result) ? result : Default(type); return TryConvertImplicit(type, value, out var result) ? result : Default(type);
} }
[RequiresUnreferencedCode(TrimmingMessages.ImplicitTypeConvertionRequiresUnreferencedCodeMessage)]
public static T ConvertImplicit<T>(object value) public static T ConvertImplicit<T>(object value)
{ {
if (TryConvertImplicit(typeof(T), value, out var result)) if (TryConvertImplicit(typeof(T), value, out var result))
@ -339,6 +345,7 @@ namespace Avalonia.Utilities
/// </summary> /// </summary>
/// <param name="type">The type.</param> /// <param name="type">The type.</param>
/// <returns>The default value.</returns> /// <returns>The default value.</returns>
[UnconditionalSuppressMessage("Trimming", "IL2067", Justification = "We don't care about public ctors for the value types, and always return null for the ref types.")]
public static object? Default(Type type) public static object? Default(Type type)
{ {
if (type.IsValueType) if (type.IsValueType)
@ -391,7 +398,9 @@ namespace Avalonia.Utilities
return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);
} }
private static MethodInfo? FindTypeConversionOperatorMethod(Type fromType, Type toType, OperatorType operatorType) private static MethodInfo? FindTypeConversionOperatorMethod(
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type fromType,
Type toType, OperatorType operatorType)
{ {
const string implicitName = "op_Implicit"; const string implicitName = "op_Implicit";
const string explicitName = "op_Explicit"; const string explicitName = "op_Explicit";

8
src/Avalonia.Base/Utilities/WeakEventHandlerManager.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
@ -20,7 +21,8 @@ namespace Avalonia.Utilities
/// <param name="target">The event source.</param> /// <param name="target">The event source.</param>
/// <param name="eventName">The name of the event.</param> /// <param name="eventName">The name of the event.</param>
/// <param name="subscriber">The subscriber.</param> /// <param name="subscriber">The subscriber.</param>
public static void Subscribe<TTarget, TEventArgs, TSubscriber>(TTarget target, string eventName, EventHandler<TEventArgs> subscriber) public static void Subscribe<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] TTarget, TEventArgs, TSubscriber>(
TTarget target, string eventName, EventHandler<TEventArgs> subscriber)
where TEventArgs : EventArgs where TSubscriber : class where TEventArgs : EventArgs where TSubscriber : class
{ {
_ = target ?? throw new ArgumentNullException(nameof(target)); _ = target ?? throw new ArgumentNullException(nameof(target));
@ -92,7 +94,9 @@ namespace Avalonia.Utilities
private static Dictionary<MethodInfo, CallerDelegate> s_Callers = private static Dictionary<MethodInfo, CallerDelegate> s_Callers =
new Dictionary<MethodInfo, CallerDelegate>(); new Dictionary<MethodInfo, CallerDelegate>();
public Subscription(SubscriptionDic<T, TSubscriber> sdic, Type targetType, object target, string eventName) public Subscription(SubscriptionDic<T, TSubscriber> sdic,
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] Type targetType,
object target, string eventName)
{ {
_sdic = sdic; _sdic = sdic;
_target = target; _target = target;

3
src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj

@ -6,7 +6,7 @@
<BuildOutputTargetFolder>tools</BuildOutputTargetFolder> <BuildOutputTargetFolder>tools</BuildOutputTargetFolder>
<DefineConstants>$(DefineConstants);BUILDTASK;XAMLX_CECIL_INTERNAL;XAMLX_INTERNAL</DefineConstants> <DefineConstants>$(DefineConstants);BUILDTASK;XAMLX_CECIL_INTERNAL;XAMLX_INTERNAL</DefineConstants>
<CopyLocalLockFileAssemblies Condition="$(TargetFramework) == 'netstandard2.0'">true</CopyLocalLockFileAssemblies> <CopyLocalLockFileAssemblies Condition="$(TargetFramework) == 'netstandard2.0'">true</CopyLocalLockFileAssemblies>
<NoWarn>NU1605;CS8632</NoWarn> <NoWarn>$(NoWarn);NU1605;CS8632</NoWarn>
</PropertyGroup> </PropertyGroup>
<!--Disable Net Perf. analyzer for submodule to avoid commit issue --> <!--Disable Net Perf. analyzer for submodule to avoid commit issue -->
@ -111,6 +111,7 @@
<Link>Markup/%(RecursiveDir)%(FileName)%(Extension)</Link> <Link>Markup/%(RecursiveDir)%(FileName)%(Extension)</Link>
</Compile> </Compile>
<Compile Include="..\Avalonia.Base\Metadata\NullableAttributes.cs" Link="NullableAttributes.cs" /> <Compile Include="..\Avalonia.Base\Metadata\NullableAttributes.cs" Link="NullableAttributes.cs" />
<Compile Include="..\Avalonia.Base\Compatibility\TrimmingAttributes.cs" Link="TrimmingAttributes.cs" Visible="False" />
<Compile Remove="../Markup/Avalonia.Markup.Xaml.Loader\xamlil.github\**\obj\**\*.cs" /> <Compile Remove="../Markup/Avalonia.Markup.Xaml.Loader\xamlil.github\**\obj\**\*.cs" />
<Compile Remove="../Markup/Avalonia.Markup.Xaml.Loader\xamlil.github\src\XamlX\IL\SreTypeSystem.cs" /> <Compile Remove="../Markup/Avalonia.Markup.Xaml.Loader\xamlil.github\src\XamlX\IL\SreTypeSystem.cs" />
<PackageReference Include="Mono.Cecil" Version="0.11.4" /> <PackageReference Include="Mono.Cecil" Version="0.11.4" />

1
src/Avalonia.Controls.ColorPicker/Avalonia.Controls.ColorPicker.csproj

@ -21,6 +21,7 @@
<Import Project="..\..\build\BuildTargets.targets" /> <Import Project="..\..\build\BuildTargets.targets" />
<!--<Import Project="..\..\build\ApiDiff.props" />--> <!--<Import Project="..\..\build\ApiDiff.props" />-->
<Import Project="..\..\build\NullableEnable.props" /> <Import Project="..\..\build\NullableEnable.props" />
<Import Project="..\..\build\TrimmingEnable.props" />
<Import Project="..\..\build\DevAnalyzers.props" /> <Import Project="..\..\build\DevAnalyzers.props" />
<ItemGroup Label="InternalsVisibleTo"> <ItemGroup Label="InternalsVisibleTo">

50
src/Avalonia.Controls/AppBuilderBase.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.Reflection; using System.Reflection;
using System.Linq; using System.Linq;
using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.ApplicationLifetimes;
@ -162,13 +163,6 @@ namespace Avalonia.Controls
return Self; return Self;
} }
/// <summary>
/// Specifies a windowing subsystem to use.
/// </summary>
/// <param name="dll">The dll in which to look for subsystem.</param>
/// <returns>An <typeparamref name="TAppBuilder"/> instance.</returns>
public TAppBuilder UseWindowingSubsystem(string dll) => UseWindowingSubsystem(GetInitializer(dll), dll.Replace("Avalonia.", string.Empty));
/// <summary> /// <summary>
/// Specifies a rendering subsystem to use. /// Specifies a rendering subsystem to use.
/// </summary> /// </summary>
@ -182,50 +176,8 @@ namespace Avalonia.Controls
return Self; return Self;
} }
/// <summary>
/// Specifies a rendering subsystem to use.
/// </summary>
/// <param name="dll">The dll in which to look for subsystem.</param>
/// <returns>An <typeparamref name="TAppBuilder"/> instance.</returns>
public TAppBuilder UseRenderingSubsystem(string dll) => UseRenderingSubsystem(GetInitializer(dll));
static Action GetInitializer(string assemblyName) => () =>
{
var assembly = Assembly.Load(new AssemblyName(assemblyName));
var platformClassName = assemblyName.Replace("Avalonia.", string.Empty) + "Platform";
var platformClassFullName = assemblyName + "." + platformClassName;
var platformClass = assembly.GetType(platformClassFullName);
var init = platformClass!.GetRuntimeMethod("Initialize", Type.EmptyTypes);
init!.Invoke(null, null);
};
public TAppBuilder UseAvaloniaModules() => AfterSetup(builder => SetupAvaloniaModules());
protected virtual bool CheckSetup => true; protected virtual bool CheckSetup => true;
/// <summary>
/// Searches and initiates modules included with <see cref="ExportAvaloniaModuleAttribute"/> attribute.
/// </summary>
private void SetupAvaloniaModules()
{
var moduleInitializers = from assembly in AppDomain.CurrentDomain.GetAssemblies()
from attribute in assembly.GetCustomAttributes<ExportAvaloniaModuleAttribute>()
where string.IsNullOrEmpty(attribute.ForWindowingSubsystem)
|| attribute.ForWindowingSubsystem == WindowingSubsystemName
where string.IsNullOrEmpty(attribute.ForRenderingSubsystem)
|| attribute.ForRenderingSubsystem == RenderingSubsystemName
group attribute by attribute.Name into exports
select (from export in exports
orderby export.ForWindowingSubsystem.Length descending
orderby export.ForRenderingSubsystem.Length descending
select export).First().ModuleType into moduleType
select (from constructor in moduleType.GetTypeInfo().DeclaredConstructors
where constructor.GetParameters().Length == 0 && !constructor.IsStatic
select constructor).Single() into constructor
select (Action)(() => constructor.Invoke(Array.Empty<object>()));
Delegate.Combine(moduleInitializers.ToArray())!.DynamicInvoke();
}
/// <summary> /// <summary>
/// Configures platform-specific options /// Configures platform-specific options
/// </summary> /// </summary>

1
src/Avalonia.Controls/Avalonia.Controls.csproj

@ -10,6 +10,7 @@
<Import Project="..\..\build\JetBrains.Annotations.props" /> <Import Project="..\..\build\JetBrains.Annotations.props" />
<Import Project="..\..\build\ApiDiff.props" /> <Import Project="..\..\build\ApiDiff.props" />
<Import Project="..\..\build\NullableEnable.props" /> <Import Project="..\..\build\NullableEnable.props" />
<Import Project="..\..\build\TrimmingEnable.props" />
<Import Project="..\..\build\DevAnalyzers.props" /> <Import Project="..\..\build\DevAnalyzers.props" />
<ItemGroup Label="InternalsVisibleTo"> <ItemGroup Label="InternalsVisibleTo">

12
src/Avalonia.Controls/NativeMenuBar.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.Interactivity; using Avalonia.Interactivity;
@ -21,7 +22,16 @@ namespace Avalonia.Controls
item.Click -= OnMenuItemClick; item.Click -= OnMenuItemClick;
}); });
} }
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(NativeMenu))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(NativeMenuItem))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(NativeMenuItemBase))]
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(NativeMenuItemSeparator))]
public NativeMenuBar()
{
}
public static void SetEnableMenuItemClickForwarding(MenuItem menuItem, bool enable) public static void SetEnableMenuItemClickForwarding(MenuItem menuItem, bool enable)
{ {
menuItem.SetValue(EnableMenuItemClickForwardingProperty, enable); menuItem.SetValue(EnableMenuItemClickForwardingProperty, enable);

2
src/Avalonia.DesignerSupport/Avalonia.DesignerSupport.csproj

@ -7,7 +7,7 @@
need change when there are breaking changes to designer support api. need change when there are breaking changes to designer support api.
--> -->
<Version>0.7.0</Version> <Version>0.7.0</Version>
<NoWarn>CS1591</NoWarn> <NoWarn>$(NoWarn);CS1591</NoWarn>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<NugetPackageName>Avalonia</NugetPackageName> <NugetPackageName>Avalonia</NugetPackageName>
</PropertyGroup> </PropertyGroup>

13
src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Net; using System.Net;
using System.Reflection; using System.Reflection;
using System.Threading; using System.Threading;
@ -150,10 +151,20 @@ namespace Avalonia.DesignerSupport.Remote
} }
if (args.Method == Methods.Win32) if (args.Method == Methods.Win32)
builder.UseWindowingSubsystem("Avalonia.Win32"); builder.UseWindowingSubsystem(GetInitializer("Avalonia.Win32"), "Win32");
builder.SetupWithoutStarting(); builder.SetupWithoutStarting();
return transport; return transport;
} }
private static Action GetInitializer(string assemblyName) => () =>
{
var assembly = Assembly.Load(new AssemblyName(assemblyName));
var platformClassName = assemblyName.Replace("Avalonia.", string.Empty) + "Platform";
var platformClassFullName = assemblyName + "." + platformClassName;
var platformClass = assembly.GetType(platformClassFullName);
var init = platformClass!.GetRuntimeMethod("Initialize", Type.EmptyTypes);
init!.Invoke(null, null);
};
} }
private const string BuilderMethodName = "BuildAvaloniaApp"; private const string BuilderMethodName = "BuildAvaloniaApp";

4
src/Avalonia.Desktop/Avalonia.Desktop.csproj

@ -12,5 +12,7 @@
<ProjectReference Include="../Avalonia.X11/Avalonia.X11.csproj" /> <ProjectReference Include="../Avalonia.X11/Avalonia.X11.csproj" />
</ItemGroup> </ItemGroup>
<Import Project="..\..\build\ApiDiff.props" /> <Import Project="..\..\build\ApiDiff.props" />
<Import Project="..\..\build\TrimmingEnable.props" />
<Import Project="..\..\build\NullableEnable.props" />
</Project> </Project>

1
src/Avalonia.Dialogs/Avalonia.Dialogs.csproj

@ -16,4 +16,5 @@
<Import Project="..\..\build\ApiDiff.props" /> <Import Project="..\..\build\ApiDiff.props" />
<Import Project="..\..\build\DevAnalyzers.props" /> <Import Project="..\..\build\DevAnalyzers.props" />
<Import Project="..\..\build\TrimmingEnable.props" />
</Project> </Project>

1
src/Avalonia.Headless.Vnc/Avalonia.Headless.Vnc.csproj

@ -9,4 +9,5 @@
<PackageReference Include="Quamotion.RemoteViewing" Version="1.1.21" /> <PackageReference Include="Quamotion.RemoteViewing" Version="1.1.21" />
</ItemGroup> </ItemGroup>
<Import Project="..\..\build\TrimmingEnable.props" />
</Project> </Project>

6
src/Avalonia.Headless/Avalonia.Headless.csproj

@ -5,5 +5,9 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\packages\Avalonia\Avalonia.csproj" /> <ProjectReference Include="..\..\packages\Avalonia\Avalonia.csproj" />
</ItemGroup> </ItemGroup>
<Import Project="..\..\build\ApiDiff.props" />
<Import Project="..\..\build\DevAnalyzers.props" />
<Import Project="..\..\build\TrimmingEnable.props" />
</Project> </Project>

2
src/Avalonia.MicroCom/Avalonia.MicroCom.csproj

@ -13,4 +13,6 @@
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<Import Project="..\..\build\BuildTargets.targets" /> <Import Project="..\..\build\BuildTargets.targets" />
<Import Project="..\..\build\TrimmingEnable.props" />
<Import Project="..\..\build\NullableEnable.props" />
</Project> </Project>

2
src/Avalonia.MicroCom/CallbackBase.cs

@ -38,7 +38,7 @@ namespace Avalonia.MicroCom
} }
} }
public MicroComShadow Shadow { get; set; } public MicroComShadow? Shadow { get; set; }
public void OnReferencedFromNative() public void OnReferencedFromNative()
{ {
lock (_lock) lock (_lock)

1
src/Avalonia.Native/Avalonia.Native.csproj

@ -29,4 +29,5 @@
</ItemGroup> </ItemGroup>
<Import Project="..\..\build\DevAnalyzers.props" /> <Import Project="..\..\build\DevAnalyzers.props" />
<Import Project="..\..\build\TrimmingEnable.props" />
</Project> </Project>

1
src/Avalonia.OpenGL/Avalonia.OpenGL.csproj

@ -12,4 +12,5 @@
<Import Project="..\..\build\DevAnalyzers.props" /> <Import Project="..\..\build\DevAnalyzers.props" />
<Import Project="..\..\build\SourceGenerators.props" /> <Import Project="..\..\build\SourceGenerators.props" />
<Import Project="..\..\build\TrimmingEnable.props" />
</Project> </Project>

1
src/Avalonia.ReactiveUI/Avalonia.ReactiveUI.csproj

@ -11,4 +11,5 @@
<Import Project="..\..\build\ReactiveUI.props" /> <Import Project="..\..\build\ReactiveUI.props" />
<Import Project="..\..\build\ApiDiff.props" /> <Import Project="..\..\build\ApiDiff.props" />
<Import Project="..\..\build\NullableEnable.props" /> <Import Project="..\..\build\NullableEnable.props" />
<Import Project="..\..\build\TrimmingEnable.props" />
</Project> </Project>

2
src/Avalonia.Remote.Protocol/Avalonia.Remote.Protocol.csproj

@ -8,6 +8,8 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Include="..\Avalonia.Base\Input\Key.cs" /> <Compile Include="..\Avalonia.Base\Input\Key.cs" />
<Compile Include="..\Avalonia.Base\Compatibility\TrimmingAttributes.cs" Visible="False" />
</ItemGroup> </ItemGroup>
<Import Project="..\..\build\ApiDiff.props" /> <Import Project="..\..\build\ApiDiff.props" />
<Import Project="..\..\build\TrimmingEnable.props" />
</Project> </Project>

2
src/Avalonia.Remote.Protocol/BsonStreamTransport.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.IO; using System.IO;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -6,6 +7,7 @@ using Metsys.Bson;
namespace Avalonia.Remote.Protocol namespace Avalonia.Remote.Protocol
{ {
[RequiresUnreferencedCode("Bson uses reflection")]
class BsonStreamTransportConnection : IAvaloniaRemoteTransportConnection class BsonStreamTransportConnection : IAvaloniaRemoteTransportConnection
{ {
private readonly IMessageTypeResolver _resolver; private readonly IMessageTypeResolver _resolver;

4
src/Avalonia.Remote.Protocol/BsonTcpTransport.cs

@ -1,9 +1,11 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
namespace Avalonia.Remote.Protocol namespace Avalonia.Remote.Protocol
{ {
[RequiresUnreferencedCode("Bson uses reflection")]
public class BsonTcpTransport : TcpTransportBase public class BsonTcpTransport : TcpTransportBase
{ {
public BsonTcpTransport(IMessageTypeResolver resolver) : base(resolver) public BsonTcpTransport(IMessageTypeResolver resolver) : base(resolver)
@ -24,4 +26,4 @@ namespace Avalonia.Remote.Protocol
return wrap; return wrap;
} }
} }
} }

4
src/Avalonia.Remote.Protocol/DefaultMessageTypeResolver.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
@ -9,6 +10,9 @@ namespace Avalonia.Remote.Protocol
{ {
private readonly Dictionary<Guid, Type> _guidsToTypes = new Dictionary<Guid, Type>(); private readonly Dictionary<Guid, Type> _guidsToTypes = new Dictionary<Guid, Type>();
private readonly Dictionary<Type, Guid> _typesToGuids = new Dictionary<Type, Guid>(); private readonly Dictionary<Type, Guid> _typesToGuids = new Dictionary<Type, Guid>();
[UnconditionalSuppressMessage("Trimming", "IL2026",
Justification = "If type was trimmed, we don't need to resolve it in the remove protocol")]
public DefaultMessageTypeResolver(params Assembly[] assemblies) public DefaultMessageTypeResolver(params Assembly[] assemblies)
{ {
foreach (var asm in foreach (var asm in

11
src/Avalonia.Remote.Protocol/MetsysBson.cs

@ -32,6 +32,7 @@ using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
@ -71,7 +72,7 @@ namespace Metsys.Bson
namespace Metsys.Bson namespace Metsys.Bson
{ {
[RequiresUnreferencedCode("Bson uses reflection")]
internal class Serializer internal class Serializer
{ {
private static readonly IDictionary<Type, Types> _typeMap = new Dictionary<Type, Types> private static readonly IDictionary<Type, Types> _typeMap = new Dictionary<Type, Types>
@ -687,6 +688,7 @@ namespace Metsys.Bson
namespace Metsys.Bson namespace Metsys.Bson
{ {
[RequiresUnreferencedCode("Bson uses reflection")]
internal class TypeHelper internal class TypeHelper
{ {
private static readonly IDictionary<Type, TypeHelper> _cachedTypeLookup = new Dictionary<Type, TypeHelper>(); private static readonly IDictionary<Type, TypeHelper> _cachedTypeLookup = new Dictionary<Type, TypeHelper>();
@ -787,6 +789,7 @@ namespace Metsys.Bson
namespace Metsys.Bson namespace Metsys.Bson
{ {
[RequiresUnreferencedCode("Bson uses reflection")]
internal class ListWrapper : BaseWrapper internal class ListWrapper : BaseWrapper
{ {
private IList _list; private IList _list;
@ -821,6 +824,7 @@ namespace Metsys.Bson
namespace Metsys.Bson namespace Metsys.Bson
{ {
[RequiresUnreferencedCode("Bson uses reflection")]
internal static class ListHelper internal static class ListHelper
{ {
public static Type GetListItemType(Type enumerableType) public static Type GetListItemType(Type enumerableType)
@ -865,6 +869,7 @@ namespace Metsys.Bson
namespace Metsys.Bson namespace Metsys.Bson
{ {
[RequiresUnreferencedCode("Bson uses reflection")]
internal class CollectionWrapper<T> : BaseWrapper internal class CollectionWrapper<T> : BaseWrapper
{ {
private ICollection<T> _list; private ICollection<T> _list;
@ -892,6 +897,7 @@ namespace Metsys.Bson
namespace Metsys.Bson namespace Metsys.Bson
{ {
[RequiresUnreferencedCode("Bson uses reflection")]
internal abstract class BaseWrapper internal abstract class BaseWrapper
{ {
public static BaseWrapper Create(Type type, Type itemType, object existingContainer) public static BaseWrapper Create(Type type, Type itemType, object existingContainer)
@ -948,7 +954,7 @@ namespace Metsys.Bson
namespace Metsys.Bson namespace Metsys.Bson
{ {
[RequiresUnreferencedCode("Bson uses reflection")]
internal class ArrayWrapper<T> : BaseWrapper internal class ArrayWrapper<T> : BaseWrapper
{ {
private readonly List<T> _list = new List<T>(); private readonly List<T> _list = new List<T>();
@ -1000,6 +1006,7 @@ namespace Metsys.Bson
namespace Metsys.Bson namespace Metsys.Bson
{ {
[RequiresUnreferencedCode("Bson uses reflection")]
internal class Deserializer internal class Deserializer
{ {
internal class Options internal class Options

3
src/Avalonia.Themes.Fluent/Avalonia.Themes.Fluent.csproj

@ -1,6 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>net6.0;netstandard2.0</TargetFrameworks> <TargetFrameworks>net6.0;netstandard2.0</TargetFrameworks>
<!-- NativeMenuBar uses ReflectionBinding -->
<NoWarn>$(NoWarn);IL2026</NoWarn>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Avalonia.Base\Avalonia.Base.csproj" /> <ProjectReference Include="..\Avalonia.Base\Avalonia.Base.csproj" />
@ -14,4 +16,5 @@
<Import Project="..\..\build\BuildTargets.targets" /> <Import Project="..\..\build\BuildTargets.targets" />
<Import Project="..\..\build\Rx.props" /> <Import Project="..\..\build\Rx.props" />
<Import Project="..\..\build\ApiDiff.props" /> <Import Project="..\..\build\ApiDiff.props" />
<Import Project="..\..\build\TrimmingEnable.props" />
</Project> </Project>

3
src/Avalonia.Themes.Simple/Avalonia.Themes.Simple.csproj

@ -1,6 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>net6.0;netstandard2.0</TargetFrameworks> <TargetFrameworks>net6.0;netstandard2.0</TargetFrameworks>
<!-- NativeMenuBar uses ReflectionBinding -->
<NoWarn>$(NoWarn);IL2026</NoWarn>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Avalonia.Base\Avalonia.Base.csproj" /> <ProjectReference Include="..\Avalonia.Base\Avalonia.Base.csproj" />
@ -13,4 +15,5 @@
<Import Project="..\..\build\BuildTargets.targets" /> <Import Project="..\..\build\BuildTargets.targets" />
<Import Project="..\..\build\Rx.props" /> <Import Project="..\..\build\Rx.props" />
<Import Project="..\..\build\ApiDiff.props" /> <Import Project="..\..\build\ApiDiff.props" />
<Import Project="..\..\build\TrimmingEnable.props" />
</Project> </Project>

1
src/Avalonia.X11/Avalonia.X11.csproj

@ -12,4 +12,5 @@
<Compile Include="..\Shared\RawEventGrouping.cs" /> <Compile Include="..\Shared\RawEventGrouping.cs" />
</ItemGroup> </ItemGroup>
<Import Project="..\..\build\SourceGenerators.props" /> <Import Project="..\..\build\SourceGenerators.props" />
<Import Project="..\..\build\TrimmingEnable.props" />
</Project> </Project>

4
src/Avalonia.X11/X11Structs.cs

@ -34,6 +34,7 @@ using System.Diagnostics;
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Diagnostics.CodeAnalysis;
// ReSharper disable FieldCanBeMadeReadOnly.Global // ReSharper disable FieldCanBeMadeReadOnly.Global
// ReSharper disable IdentifierTypo // ReSharper disable IdentifierTypo
// ReSharper disable MemberCanBePrivate.Global // ReSharper disable MemberCanBePrivate.Global
@ -654,7 +655,8 @@ namespace Avalonia.X11 {
return type.ToString (); return type.ToString ();
} }
} }
[UnconditionalSuppressMessage("Trimming", "IL2075", Justification = TrimmingMessages.IgnoreNativeAotSupressWarningMessage)]
public static string ToString (object ev) public static string ToString (object ev)
{ {
string result = string.Empty; string result = string.Empty;

1
src/Browser/Avalonia.Browser.Blazor/Avalonia.Browser.Blazor.csproj

@ -11,6 +11,7 @@
</ItemGroup> </ItemGroup>
<Import Project="..\..\..\build\NullableEnable.props" /> <Import Project="..\..\..\build\NullableEnable.props" />
<Import Project="..\..\..\build\TrimmingEnable.props" />
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="7.0.0-*" /> <PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="7.0.0-*" />

1
src/Browser/Avalonia.Browser/Avalonia.Browser.csproj

@ -15,6 +15,7 @@
<Import Project="..\..\..\build\SkiaSharp.props" /> <Import Project="..\..\..\build\SkiaSharp.props" />
<Import Project="..\..\..\build\HarfBuzzSharp.props" /> <Import Project="..\..\..\build\HarfBuzzSharp.props" />
<Import Project="..\..\..\build\NullableEnable.props" /> <Import Project="..\..\..\build\NullableEnable.props" />
<Import Project="..\..\..\build\TrimmingEnable.props" />
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\..\packages\Avalonia\Avalonia.csproj" /> <ProjectReference Include="..\..\..\packages\Avalonia\Avalonia.csproj" />

3
src/Linux/Avalonia.LinuxFramebuffer/Avalonia.LinuxFramebuffer.csproj

@ -8,5 +8,6 @@
<ProjectReference Include="..\..\..\packages\Avalonia\Avalonia.csproj" /> <ProjectReference Include="..\..\..\packages\Avalonia\Avalonia.csproj" />
<ProjectReference Include="..\..\Skia\Avalonia.Skia\Avalonia.Skia.csproj" /> <ProjectReference Include="..\..\Skia\Avalonia.Skia\Avalonia.Skia.csproj" />
<Compile Include="..\..\Shared\RawEventGrouping.cs" /> <Compile Include="..\..\Shared\RawEventGrouping.cs" />
</ItemGroup> </ItemGroup>
<Import Project="..\..\..\build\TrimmingEnable.props" />
</Project> </Project>

3
src/Markup/Avalonia.Markup.Xaml.Loader/Avalonia.Markup.Xaml.Loader.csproj

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>net6.0;netstandard2.0</TargetFrameworks> <TargetFrameworks>net6.0;netstandard2.0</TargetFrameworks>
@ -13,6 +13,7 @@
<Import Project="IncludeXamlIlSre.props" /> <Import Project="IncludeXamlIlSre.props" />
<ItemGroup> <ItemGroup>
<Compile Include="..\..\Avalonia.Base\Utilities\StringBuilderCache.cs" Link="Utilities\StringBuilderCache.cs" /> <Compile Include="..\..\Avalonia.Base\Utilities\StringBuilderCache.cs" Link="Utilities\StringBuilderCache.cs" />
<Compile Include="..\..\Avalonia.Base\Compatibility\TrimmingAttributes.cs" Link="TrimmingAttributes.cs" Visible="False" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="System.Reflection.Emit" Version="4.3.0" /> <PackageReference Include="System.Reflection.Emit" Version="4.3.0" />

8
src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj

@ -6,10 +6,9 @@
<DefineConstants Condition="$(UseCecil) == true">$(DefineConstants);RUNTIME_XAML_CECIL</DefineConstants> <DefineConstants Condition="$(UseCecil) == true">$(DefineConstants);RUNTIME_XAML_CECIL</DefineConstants>
<EnableDefaultCompileItems>False</EnableDefaultCompileItems> <EnableDefaultCompileItems>False</EnableDefaultCompileItems>
<EnableDefaultItems>false</EnableDefaultItems> <EnableDefaultItems>false</EnableDefaultItems>
<NoWarn>CS1591</NoWarn> <NoWarn>$(NoWarn);CS1591</NoWarn>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Include="..\..\Shared\StringCompatibilityExtensions.cs" Link="Compatibility\StringCompatibilityExtensions.cs" />
<Compile Include="AvaloniaXamlLoader.cs" /> <Compile Include="AvaloniaXamlLoader.cs" />
<Compile Include="Converters\AvaloniaUriTypeConverter.cs" /> <Compile Include="Converters\AvaloniaUriTypeConverter.cs" />
<Compile Include="Converters\ColorToBrushConverter.cs" /> <Compile Include="Converters\ColorToBrushConverter.cs" />
@ -69,12 +68,9 @@
<Import Project="..\..\..\build\Rx.props" /> <Import Project="..\..\..\build\Rx.props" />
<Import Project="..\..\..\build\ApiDiff.props" /> <Import Project="..\..\..\build\ApiDiff.props" />
<Import Project="..\..\..\build\DevAnalyzers.props" /> <Import Project="..\..\..\build\DevAnalyzers.props" />
<Import Project="..\..\..\build\TrimmingEnable.props" />
<ItemGroup Label="InternalsVisibleTo"> <ItemGroup Label="InternalsVisibleTo">
<InternalsVisibleTo Include="Avalonia.Markup.Xaml.UnitTests, PublicKey=$(AvaloniaPublicKey)" /> <InternalsVisibleTo Include="Avalonia.Markup.Xaml.UnitTests, PublicKey=$(AvaloniaPublicKey)" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Compatibility\" />
</ItemGroup>
</Project> </Project>

5
src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.IO; using System.IO;
using Avalonia.Platform; using Avalonia.Platform;
#nullable enable #nullable enable
@ -43,11 +44,12 @@ namespace Avalonia.Markup.Xaml
/// A base URI to use if <paramref name="uri"/> is relative. /// A base URI to use if <paramref name="uri"/> is relative.
/// </param> /// </param>
/// <returns>The loaded object.</returns> /// <returns>The loaded object.</returns>
[RequiresUnreferencedCode(TrimmingMessages.AvaloniaXamlLoaderRequiresUnreferenceCodeMessage)]
public static object Load(Uri uri, Uri? baseUri = null) public static object Load(Uri uri, Uri? baseUri = null)
{ {
return Load(null, uri, baseUri); return Load(null, uri, baseUri);
} }
/// <summary> /// <summary>
/// Loads XAML from a URI. /// Loads XAML from a URI.
/// </summary> /// </summary>
@ -57,6 +59,7 @@ namespace Avalonia.Markup.Xaml
/// A base URI to use if <paramref name="uri"/> is relative. /// A base URI to use if <paramref name="uri"/> is relative.
/// </param> /// </param>
/// <returns>The loaded object.</returns> /// <returns>The loaded object.</returns>
[RequiresUnreferencedCode(TrimmingMessages.AvaloniaXamlLoaderRequiresUnreferenceCodeMessage)]
public static object Load(IServiceProvider? sp, Uri uri, Uri? baseUri = null) public static object Load(IServiceProvider? sp, Uri uri, Uri? baseUri = null)
{ {
if (uri is null) if (uri is null)

3
src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaPropertyTypeConverter.cs

@ -1,5 +1,6 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization; using System.Globalization;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Logging; using Avalonia.Logging;
@ -10,6 +11,7 @@ using Avalonia.Utilities;
namespace Avalonia.Markup.Xaml.Converters namespace Avalonia.Markup.Xaml.Converters
{ {
[RequiresUnreferencedCode(TrimmingMessages.XamlTypeResolvedRequiresUnreferenceCodeMessage)]
public class AvaloniaPropertyTypeConverter : TypeConverter public class AvaloniaPropertyTypeConverter : TypeConverter
{ {
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
@ -48,6 +50,7 @@ namespace Avalonia.Markup.Xaml.Converters
return property; return property;
} }
[RequiresUnreferencedCode(TrimmingMessages.XamlTypeResolvedRequiresUnreferenceCodeMessage)]
private static Type TryResolveOwnerByName(ITypeDescriptorContext context, string ns, string owner) private static Type TryResolveOwnerByName(ITypeDescriptorContext context, string ns, string owner)
{ {
if (owner != null) if (owner != null)

2
src/Markup/Avalonia.Markup.Xaml/Extensions.cs

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Markup.Xaml.XamlIl.Runtime; using Avalonia.Markup.Xaml.XamlIl.Runtime;
@ -28,6 +29,7 @@ namespace Avalonia.Markup.Xaml
public static bool IsInControlTemplate(this IServiceProvider sp) => sp.GetService<IAvaloniaXamlIlControlTemplateProvider>() != null; public static bool IsInControlTemplate(this IServiceProvider sp) => sp.GetService<IAvaloniaXamlIlControlTemplateProvider>() != null;
[RequiresUnreferencedCode(TrimmingMessages.XamlTypeResolvedRequiresUnreferenceCodeMessage)]
public static Type ResolveType(this IServiceProvider ctx, string namespacePrefix, string type) public static Type ResolveType(this IServiceProvider ctx, string namespacePrefix, string type)
{ {
var tr = ctx.GetService<IXamlTypeResolver>(); var tr = ctx.GetService<IXamlTypeResolver>();

3
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/ArrayElementPlugin.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Text; using System.Text;
using Avalonia.Data; using Avalonia.Data;
using Avalonia.Data.Core.Plugins; using Avalonia.Data.Core.Plugins;
@ -17,11 +18,13 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings
_elementType = elementType; _elementType = elementType;
} }
[RequiresUnreferencedCode(TrimmingMessages.PropertyAccessorsRequiresUnreferencedCodeMessage)]
public bool Match(object obj, string propertyName) public bool Match(object obj, string propertyName)
{ {
throw new InvalidOperationException("The ArrayElementPlugin does not support dynamic matching"); throw new InvalidOperationException("The ArrayElementPlugin does not support dynamic matching");
} }
[RequiresUnreferencedCode(TrimmingMessages.PropertyAccessorsRequiresUnreferencedCodeMessage)]
public IPropertyAccessor Start(WeakReference<object> reference, string propertyName) public IPropertyAccessor Start(WeakReference<object> reference, string propertyName)
{ {
if (reference.TryGetTarget(out var target) && target is Array arr) if (reference.TryGetTarget(out var target) && target is Array arr)

3
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/CommandAccessorPlugin.cs

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using System.Windows.Input; using System.Windows.Input;
@ -23,11 +24,13 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings
_dependsOnProperties = dependsOnProperties; _dependsOnProperties = dependsOnProperties;
} }
[RequiresUnreferencedCode(TrimmingMessages.PropertyAccessorsRequiresUnreferencedCodeMessage)]
public bool Match(object obj, string propertyName) public bool Match(object obj, string propertyName)
{ {
throw new InvalidOperationException("The CommandAccessorPlugin does not support dynamic matching"); throw new InvalidOperationException("The CommandAccessorPlugin does not support dynamic matching");
} }
[RequiresUnreferencedCode(TrimmingMessages.PropertyAccessorsRequiresUnreferencedCodeMessage)]
public IPropertyAccessor Start(WeakReference<object> reference, string propertyName) public IPropertyAccessor Start(WeakReference<object> reference, string propertyName)
{ {
return new CommandAccessor(reference, _execute, _canExecute, _dependsOnProperties); return new CommandAccessor(reference, _execute, _canExecute, _dependsOnProperties);

2
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/CompiledBindingPath.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using Avalonia.Controls; using Avalonia.Controls;
@ -22,6 +23,7 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings
RawSource = rawSource; RawSource = rawSource;
} }
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.CompiledBindingSafeSupressWarningMessage)]
public ExpressionNode BuildExpression(bool enableValidation) public ExpressionNode BuildExpression(bool enableValidation)
{ {
ExpressionNode pathRoot = null; ExpressionNode pathRoot = null;

3
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/MethodAccessorPlugin.cs

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using Avalonia.Data; using Avalonia.Data;
@ -21,11 +22,13 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings
_delegateType = delegateType; _delegateType = delegateType;
} }
[RequiresUnreferencedCode(TrimmingMessages.PropertyAccessorsRequiresUnreferencedCodeMessage)]
public bool Match(object obj, string propertyName) public bool Match(object obj, string propertyName)
{ {
throw new InvalidOperationException("The MethodAccessorPlugin does not support dynamic matching"); throw new InvalidOperationException("The MethodAccessorPlugin does not support dynamic matching");
} }
[RequiresUnreferencedCode(TrimmingMessages.PropertyAccessorsRequiresUnreferencedCodeMessage)]
public IPropertyAccessor Start(WeakReference<object?> reference, string propertyName) public IPropertyAccessor Start(WeakReference<object?> reference, string propertyName)
{ {
Debug.Assert(_method.Name == propertyName); Debug.Assert(_method.Name == propertyName);

3
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/ObservableStreamPlugin.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Text; using System.Text;
using Avalonia.Data.Core.Plugins; using Avalonia.Data.Core.Plugins;
@ -8,11 +9,13 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings
{ {
class ObservableStreamPlugin<T> : IStreamPlugin class ObservableStreamPlugin<T> : IStreamPlugin
{ {
[RequiresUnreferencedCode(TrimmingMessages.StreamPluginRequiresUnreferencedCodeMessage)]
public bool Match(WeakReference<object> reference) public bool Match(WeakReference<object> reference)
{ {
return reference.TryGetTarget(out var target) && target is IObservable<T>; return reference.TryGetTarget(out var target) && target is IObservable<T>;
} }
[RequiresUnreferencedCode(TrimmingMessages.StreamPluginRequiresUnreferencedCodeMessage)]
public IObservable<object> Start(WeakReference<object> reference) public IObservable<object> Start(WeakReference<object> reference)
{ {
if (!(reference.TryGetTarget(out var target) && target is IObservable<T> obs)) if (!(reference.TryGetTarget(out var target) && target is IObservable<T> obs))

3
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/PropertyInfoAccessorPlugin.cs

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Text; using System.Text;
using Avalonia.Data; using Avalonia.Data;
using Avalonia.Data.Core; using Avalonia.Data.Core;
@ -19,11 +20,13 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings
_accessorFactory = accessorFactory; _accessorFactory = accessorFactory;
} }
[RequiresUnreferencedCode(TrimmingMessages.PropertyAccessorsRequiresUnreferencedCodeMessage)]
public bool Match(object obj, string propertyName) public bool Match(object obj, string propertyName)
{ {
throw new InvalidOperationException("The PropertyInfoAccessorPlugin does not support dynamic matching"); throw new InvalidOperationException("The PropertyInfoAccessorPlugin does not support dynamic matching");
} }
[RequiresUnreferencedCode(TrimmingMessages.PropertyAccessorsRequiresUnreferencedCodeMessage)]
public IPropertyAccessor Start(WeakReference<object> reference, string propertyName) public IPropertyAccessor Start(WeakReference<object> reference, string propertyName)
{ {
Debug.Assert(_propertyInfo.Name == propertyName); Debug.Assert(_propertyInfo.Name == propertyName);

3
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/TaskStreamPlugin.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Reactive.Subjects; using System.Reactive.Subjects;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -9,11 +10,13 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings
{ {
class TaskStreamPlugin<T> : IStreamPlugin class TaskStreamPlugin<T> : IStreamPlugin
{ {
[RequiresUnreferencedCode(TrimmingMessages.StreamPluginRequiresUnreferencedCodeMessage)]
public bool Match(WeakReference<object> reference) public bool Match(WeakReference<object> reference)
{ {
return reference.TryGetTarget(out var target) && target is Task<T>; return reference.TryGetTarget(out var target) && target is Task<T>;
} }
[RequiresUnreferencedCode(TrimmingMessages.StreamPluginRequiresUnreferencedCodeMessage)]
public IObservable<object> Start(WeakReference<object> reference) public IObservable<object> Start(WeakReference<object> reference)
{ {
if(!(reference.TryGetTarget(out var target) && target is Task<T> task)) if(!(reference.TryGetTarget(out var target) && target is Task<T> task))

11
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ReflectionBindingExtension.cs

@ -1,14 +1,13 @@
using Avalonia.Data; using Avalonia.Data;
using System; using System;
using Avalonia.Controls;
using Avalonia.Data.Converters;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
namespace Avalonia.Markup.Xaml.MarkupExtensions namespace Avalonia.Markup.Xaml.MarkupExtensions
{ {
using Avalonia.Controls; [RequiresUnreferencedCode(TrimmingMessages.ReflectionBindingRequiresUnreferencedCodeMessage)]
using Avalonia.Data.Converters;
using Avalonia.Markup.Data;
using Avalonia.Styling;
using System.ComponentModel;
public class ReflectionBindingExtension public class ReflectionBindingExtension
{ {
public ReflectionBindingExtension() public ReflectionBindingExtension()

4
src/Markup/Avalonia.Markup.Xaml/Styling/ResourceInclude.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using Avalonia.Controls; using Avalonia.Controls;
#nullable enable #nullable enable
@ -8,9 +9,10 @@ namespace Avalonia.Markup.Xaml.Styling
/// <summary> /// <summary>
/// Loads a resource dictionary from a specified URL. /// Loads a resource dictionary from a specified URL.
/// </summary> /// </summary>
[RequiresUnreferencedCode(TrimmingMessages.StyleResourceIncludeRequiresUnreferenceCodeMessage)]
public class ResourceInclude : IResourceProvider public class ResourceInclude : IResourceProvider
{ {
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider? _serviceProvider;
private readonly Uri? _baseUri; private readonly Uri? _baseUri;
private IResourceDictionary? _loaded; private IResourceDictionary? _loaded;
private bool _isLoading; private bool _isLoading;

4
src/Markup/Avalonia.Markup.Xaml/Styling/StyleInclude.cs

@ -2,6 +2,7 @@ using Avalonia.Styling;
using System; using System;
using Avalonia.Controls; using Avalonia.Controls;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
#nullable enable #nullable enable
@ -10,9 +11,10 @@ namespace Avalonia.Markup.Xaml.Styling
/// <summary> /// <summary>
/// Includes a style from a URL. /// Includes a style from a URL.
/// </summary> /// </summary>
[RequiresUnreferencedCode(TrimmingMessages.StyleResourceIncludeRequiresUnreferenceCodeMessage)]
public class StyleInclude : IStyle, IResourceProvider public class StyleInclude : IStyle, IResourceProvider
{ {
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider? _serviceProvider;
private readonly Uri? _baseUri; private readonly Uri? _baseUri;
private IStyle[]? _loaded; private IStyle[]? _loaded;
private bool _isLoading; private bool _isLoading;

2
src/Markup/Avalonia.Markup.Xaml/Templates/TreeDataTemplate.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Templates; using Avalonia.Controls.Templates;
using Avalonia.Data; using Avalonia.Data;
@ -33,6 +34,7 @@ namespace Avalonia.Markup.Xaml.Templates
} }
} }
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "If ItemsSource is a CompiledBinding, then path members will be preserver")]
public InstancedBinding ItemsSelector(object item) public InstancedBinding ItemsSelector(object item)
{ {
if (ItemsSource != null) if (ItemsSource != null)

2
src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using Avalonia.Controls; using Avalonia.Controls;
@ -141,6 +142,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.Runtime
_nsInfo = nsInfo; _nsInfo = nsInfo;
} }
[RequiresUnreferencedCode(TrimmingMessages.XamlTypeResolvedRequiresUnreferenceCodeMessage)]
public Type Resolve(string qualifiedTypeName) public Type Resolve(string qualifiedTypeName)
{ {
var sp = qualifiedTypeName.Split(new[] {':'}, 2); var sp = qualifiedTypeName.Split(new[] {':'}, 2);

2
src/Markup/Avalonia.Markup.Xaml/XamlTypes.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
namespace Avalonia.Markup.Xaml namespace Avalonia.Markup.Xaml
{ {
@ -28,6 +29,7 @@ namespace Avalonia.Markup.Xaml
public interface IXamlTypeResolver public interface IXamlTypeResolver
{ {
[RequiresUnreferencedCode(TrimmingMessages.XamlTypeResolvedRequiresUnreferenceCodeMessage)]
Type Resolve (string qualifiedTypeName); Type Resolve (string qualifiedTypeName);
} }

1
src/Markup/Avalonia.Markup/Avalonia.Markup.csproj

@ -17,6 +17,7 @@
<Import Project="..\..\..\build\ApiDiff.props" /> <Import Project="..\..\..\build\ApiDiff.props" />
<Import Project="..\..\..\build\NullableEnable.props" /> <Import Project="..\..\..\build\NullableEnable.props" />
<Import Project="..\..\..\build\DevAnalyzers.props" /> <Import Project="..\..\..\build\DevAnalyzers.props" />
<Import Project="..\..\..\build\TrimmingEnable.props" />
<ItemGroup Label="InternalsVisibleTo"> <ItemGroup Label="InternalsVisibleTo">
<InternalsVisibleTo Include="Avalonia.Markup.UnitTests, PublicKey=$(AvaloniaPublicKey)" /> <InternalsVisibleTo Include="Avalonia.Markup.UnitTests, PublicKey=$(AvaloniaPublicKey)" />

2
src/Markup/Avalonia.Markup/Data/Binding.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Reactive; using System.Reactive;
using System.Reactive.Linq; using System.Reactive.Linq;
@ -15,6 +16,7 @@ namespace Avalonia.Data
/// <summary> /// <summary>
/// A XAML binding. /// A XAML binding.
/// </summary> /// </summary>
[RequiresUnreferencedCode(TrimmingMessages.ReflectionBindingRequiresUnreferencedCodeMessage)]
public class Binding : BindingBase public class Binding : BindingBase
{ {
/// <summary> /// <summary>

3
src/Markup/Avalonia.Markup/Data/BindingBase.cs

@ -1,5 +1,6 @@
 
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Reactive; using System.Reactive;
using System.Reactive.Linq; using System.Reactive.Linq;
@ -7,7 +8,6 @@ using Avalonia.Controls;
using Avalonia.Data.Converters; using Avalonia.Data.Converters;
using Avalonia.Data.Core; using Avalonia.Data.Core;
using Avalonia.LogicalTree; using Avalonia.LogicalTree;
using Avalonia.Markup.Parsers;
using Avalonia.Reactive; using Avalonia.Reactive;
using Avalonia.VisualTree; using Avalonia.VisualTree;
@ -81,6 +81,7 @@ namespace Avalonia.Data
bool enableDataValidation); bool enableDataValidation);
/// <inheritdoc/> /// <inheritdoc/>
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.TypeConvertionSupressWarningMessage)]
public InstancedBinding? Initiate( public InstancedBinding? Initiate(
AvaloniaObject target, AvaloniaObject target,
AvaloniaProperty? targetProperty, AvaloniaProperty? targetProperty,

6
src/Markup/Avalonia.Markup/Markup/Parsers/ExpressionObserverBuilder.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.Reactive; using System.Reactive;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Data.Core; using Avalonia.Data.Core;
@ -8,6 +9,7 @@ namespace Avalonia.Markup.Parsers
{ {
public static class ExpressionObserverBuilder public static class ExpressionObserverBuilder
{ {
[RequiresUnreferencedCode(TrimmingMessages.ReflectionBindingRequiresUnreferencedCodeMessage)]
internal static (ExpressionNode Node, SourceMode Mode) Parse(string expression, bool enableValidation = false, Func<string, string, Type>? typeResolver = null, internal static (ExpressionNode Node, SourceMode Mode) Parse(string expression, bool enableValidation = false, Func<string, string, Type>? typeResolver = null,
INameScope? nameScope = null) INameScope? nameScope = null)
{ {
@ -28,6 +30,7 @@ namespace Avalonia.Markup.Parsers
return node; return node;
} }
[RequiresUnreferencedCode(TrimmingMessages.ReflectionBindingRequiresUnreferencedCodeMessage)]
public static ExpressionObserver Build( public static ExpressionObserver Build(
object root, object root,
string expression, string expression,
@ -41,6 +44,7 @@ namespace Avalonia.Markup.Parsers
description ?? expression); description ?? expression);
} }
[RequiresUnreferencedCode(TrimmingMessages.ReflectionBindingRequiresUnreferencedCodeMessage)]
public static ExpressionObserver Build( public static ExpressionObserver Build(
IObservable<object> rootObservable, IObservable<object> rootObservable,
string expression, string expression,
@ -56,7 +60,7 @@ namespace Avalonia.Markup.Parsers
description ?? expression); description ?? expression);
} }
[RequiresUnreferencedCode(TrimmingMessages.ReflectionBindingRequiresUnreferencedCodeMessage)]
public static ExpressionObserver Build( public static ExpressionObserver Build(
Func<object> rootGetter, Func<object> rootGetter,
string expression, string expression,

2
src/Markup/Avalonia.Markup/Markup/Parsers/ExpressionParser.cs

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Avalonia.Controls; using Avalonia.Controls;
using System.Diagnostics.CodeAnalysis;
namespace Avalonia.Markup.Parsers namespace Avalonia.Markup.Parsers
{ {
@ -24,6 +25,7 @@ namespace Avalonia.Markup.Parsers
_enableValidation = enableValidation; _enableValidation = enableValidation;
} }
[RequiresUnreferencedCode(TrimmingMessages.ReflectionBindingRequiresUnreferencedCodeMessage)]
public (ExpressionNode Node, SourceMode Mode) Parse(ref CharacterReader r) public (ExpressionNode Node, SourceMode Mode) Parse(ref CharacterReader r)
{ {
ExpressionNode? rootNode = null; ExpressionNode? rootNode = null;

2
src/Markup/Avalonia.Markup/Markup/Parsers/Nodes/StringIndexerNode.cs

@ -2,6 +2,7 @@ using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Reactive.Linq; using System.Reactive.Linq;
@ -12,6 +13,7 @@ using Avalonia.Utilities;
namespace Avalonia.Markup.Parsers.Nodes namespace Avalonia.Markup.Parsers.Nodes
{ {
[RequiresUnreferencedCode(TrimmingMessages.ReflectionBindingRequiresUnreferencedCodeMessage)]
internal class StringIndexerNode : IndexerNodeBase internal class StringIndexerNode : IndexerNodeBase
{ {
public StringIndexerNode(IList<string> arguments) public StringIndexerNode(IList<string> arguments)

3
src/Markup/Avalonia.Markup/Markup/Parsers/SelectorParser.cs

@ -4,6 +4,7 @@ using System.Globalization;
using Avalonia.Styling; using Avalonia.Styling;
using Avalonia.Utilities; using Avalonia.Utilities;
using System.Linq; using System.Linq;
using System.Diagnostics.CodeAnalysis;
namespace Avalonia.Markup.Parsers namespace Avalonia.Markup.Parsers
{ {
@ -32,12 +33,14 @@ namespace Avalonia.Markup.Parsers
/// </summary> /// </summary>
/// <param name="s">The string.</param> /// <param name="s">The string.</param>
/// <returns>The parsed selector.</returns> /// <returns>The parsed selector.</returns>
[RequiresUnreferencedCode(TrimmingMessages.SelectorsParseRequiresUnreferencedCodeMessage)]
public Selector? Parse(string s) public Selector? Parse(string s)
{ {
var syntax = SelectorGrammar.Parse(s); var syntax = SelectorGrammar.Parse(s);
return Create(syntax); return Create(syntax);
} }
[RequiresUnreferencedCode(TrimmingMessages.SelectorsParseRequiresUnreferencedCodeMessage)]
private Selector? Create(IEnumerable<SelectorGrammar.ISyntax> syntax) private Selector? Create(IEnumerable<SelectorGrammar.ISyntax> syntax)
{ {
var result = default(Selector); var result = default(Selector);

1
src/Skia/Avalonia.Skia/Avalonia.Skia.csproj

@ -18,6 +18,7 @@
<Import Project="..\..\..\build\SkiaSharp.props" /> <Import Project="..\..\..\build\SkiaSharp.props" />
<Import Project="..\..\..\build\HarfBuzzSharp.props" /> <Import Project="..\..\..\build\HarfBuzzSharp.props" />
<Import Project="..\..\..\build\DevAnalyzers.props" /> <Import Project="..\..\..\build\DevAnalyzers.props" />
<Import Project="..\..\..\build\TrimmingEnable.props" />
<ItemGroup Label="InternalsVisibleTo"> <ItemGroup Label="InternalsVisibleTo">
<InternalsVisibleTo Include="Avalonia.Skia.RenderTests, PublicKey=$(AvaloniaPublicKey)" /> <InternalsVisibleTo Include="Avalonia.Skia.RenderTests, PublicKey=$(AvaloniaPublicKey)" />

2
src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj

@ -19,6 +19,7 @@
<Import Project="..\..\..\build\HarfBuzzSharp.props" /> <Import Project="..\..\..\build\HarfBuzzSharp.props" />
<Import Project="..\..\..\build\JetBrains.Annotations.props" /> <Import Project="..\..\..\build\JetBrains.Annotations.props" />
<Import Project="..\..\..\build\DevAnalyzers.props" /> <Import Project="..\..\..\build\DevAnalyzers.props" />
<Import Project="..\..\..\build\TrimmingEnable.props" />
<ItemGroup Label="InternalsVisibleTo"> <ItemGroup Label="InternalsVisibleTo">
<InternalsVisibleTo Include="Avalonia.Direct2D1.RenderTests, PublicKey=$(AvaloniaPublicKey)" /> <InternalsVisibleTo Include="Avalonia.Direct2D1.RenderTests, PublicKey=$(AvaloniaPublicKey)" />
@ -28,5 +29,4 @@
<ItemGroup> <ItemGroup>
<Folder Include="Properties\" /> <Folder Include="Properties\" />
</ItemGroup> </ItemGroup>
</Project> </Project>

2
src/Windows/Avalonia.Win32/Automation/AutomationNode.cs

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
@ -16,6 +17,7 @@ using AAP = Avalonia.Automation.Provider;
namespace Avalonia.Win32.Automation namespace Avalonia.Win32.Automation
{ {
[ComVisible(true)] [ComVisible(true)]
[RequiresUnreferencedCode("Requires .NET COM interop")]
internal partial class AutomationNode : MarshalByRefObject, internal partial class AutomationNode : MarshalByRefObject,
IRawElementProviderSimple, IRawElementProviderSimple,
IRawElementProviderSimple2, IRawElementProviderSimple2,

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save