Browse Source

More trimming fixes, enable analyzers unconditionally (#15815)

* Use UnconditionalSuppressMessage instead of #pragma in DefaultConverter

* Add missing DynamicallyAccessedMembers on WinRTInspectable

* Add missing UnconditionalSuppressMessage on Expression.OperatorName

* Use UnconditionalSuppressMessage instead of #pragma warning disable for all trimming warnings

* Don't even create ReflectionMethodAccessorPlugin if IsDynamicCodeSupported is false

* Remove old condition, as we are ready to be fully AOT compatible
Max Katz 1 year ago
parent
commit
e7b196cf03

+ 1 - 2
build/TrimmingEnable.props

@@ -11,8 +11,7 @@
     <IsAotCompatible Condition="'$(IsAotCompatible)' == ''">true</IsAotCompatible>
   </PropertyGroup>
 
-  <!-- Remove check for the AOT when we get rid of dependencies with reflection -->
-  <PropertyGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net6.0')) and '$(PublishAot)' != 'true'">
+  <PropertyGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net6.0'))">
     <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>

+ 14 - 1
src/Avalonia.Base/Data/Core/Plugins/BindingPlugins.cs

@@ -12,7 +12,6 @@ namespace Avalonia.Data.Core.Plugins
         internal static readonly List<IPropertyAccessorPlugin> s_propertyAccessors = new()
         {
             new AvaloniaPropertyAccessorPlugin(),
-            new ReflectionMethodAccessorPlugin(),
             new InpcPropertyAccessorPlugin(),
         };
 
@@ -29,6 +28,20 @@ namespace Avalonia.Data.Core.Plugins
             new ObservableStreamPlugin(),
         };
 
+        static BindingPlugins()
+        {
+            // When building with AOT, don't create ReflectionMethodAccessorPlugin instance.
+            // This branch can be eliminated in compile time with AOT.
+#if NET6_0_OR_GREATER
+            if (System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported)
+#else
+            if (true)
+#endif
+            {
+                s_propertyAccessors.Insert(1, new ReflectionMethodAccessorPlugin());
+            }
+        }
+
         /// <summary>
         /// An ordered collection of property accessor plugins that can be used to customize
         /// the reading and subscription of property values on a type.

+ 5 - 5
src/Avalonia.Base/Data/Core/TargetTypeConverter.cs

@@ -23,6 +23,11 @@ internal abstract class TargetTypeConverter
 
     private class DefaultConverter : TargetTypeConverter
     {
+        // TypeDescriptor.GetConverter might require unreferenced code for some generic types.
+        // But it's normally not the case in Avalonia. Additionally, compiled bindings will preserve referenced types. 
+        [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = TrimmingMessages.TypeConversionSupressWarningMessage)]
+        [UnconditionalSuppressMessage("Trimming", "IL2067", Justification = TrimmingMessages.TypeConversionSupressWarningMessage)]
+        [UnconditionalSuppressMessage("Trimming", "IL2072", Justification = TrimmingMessages.TypeConversionSupressWarningMessage)]
         public override bool TryConvert(object? value, Type type, CultureInfo culture, out object? result)
         {
             if (value?.GetType() == type)
@@ -66,9 +71,6 @@ internal abstract class TargetTypeConverter
                 return true;
             }
 
-#pragma warning disable IL2026
-#pragma warning disable IL2067
-#pragma warning disable IL2072
             // TODO: TypeConverters are not trimming friendly in some edge cases, we probably need
             // to make compiled bindings emit conversion code at compile-time.
             var toTypeConverter = TypeDescriptor.GetConverter(t);
@@ -122,8 +124,6 @@ internal abstract class TargetTypeConverter
                     return false;
                 }
             }
-#pragma warning restore IL2067
-#pragma warning restore IL2026
 
             if (value is IConvertible convertible)
             {

+ 1 - 0
src/Avalonia.Base/Diagnostics/TrimmingMessages.cs

@@ -27,4 +27,5 @@ internal static class TrimmingMessages
     public const string XamlTypeResolvedRequiresUnreferenceCodeMessage = "XamlTypeResolver might require unreferenced code.";
 
     public const string IgnoreNativeAotSupressWarningMessage = "This method is not supported by NativeAOT.";
+    public const string DesignTimeSupressWarningMessage = "This method is design time only.";
 }

+ 2 - 0
src/Avalonia.Base/Rendering/Composition/Expressions/Expression.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
 using System.Globalization;
 using System.Reflection;
 using Avalonia.Rendering.Composition.Server;
@@ -27,6 +28,7 @@ namespace Avalonia.Rendering.Composition.Expressions
         protected abstract string Print();
         public override string ToString() => Print();
 
+        [UnconditionalSuppressMessage("Trimming", "IL3050", Justification = TrimmingMessages.DesignTimeSupressWarningMessage)]
         internal static string OperatorName(ExpressionType t)
         {
             var attr = typeof(ExpressionType).GetMember(t.ToString())[0]

+ 2 - 5
src/Browser/Avalonia.Browser/Rendering/RenderWorker.cs

@@ -58,12 +58,10 @@ public partial class RenderWorker
             "System.Runtime.InteropServices.JavaScript")]
         [DynamicDependency(DynamicallyAccessedMemberTypes.All, "System.Runtime.InteropServices.JavaScript.JSHostImplementation", 
             "System.Runtime.InteropServices.JavaScript")]
-        [UnconditionalSuppressMessage("Trimming", 
-            "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code",
-            Justification = "Private runtime API")]
+        [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Private runtime API")]
+        [UnconditionalSuppressMessage("Trimming", "IL2075", Justification = "Private runtime API")]
         static JSWebWorkerClone()
         {
-#pragma warning disable IL2075
             var syncContext = typeof(System.Runtime.InteropServices.JavaScript.JSHost)
                 .Assembly!.GetType("System.Runtime.InteropServices.JavaScript.JSSynchronizationContext")!;
             var hostImpl = typeof(System.Runtime.InteropServices.JavaScript.JSHost)
@@ -71,7 +69,6 @@ public partial class RenderWorker
             
             _setExtLoop = hostImpl.GetMethod("SetHasExternalEventLoop")!;
             _intallInterop = syncContext.GetMethod("InstallWebWorkerInterop")!;
-#pragma warning restore IL2075
         }
 
         public static Task RunAsync(Func<Task> run)

+ 2 - 0
src/Windows/Avalonia.Win32/WinRT/WinRTInspectable.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Diagnostics.CodeAnalysis;
 using System.Linq;
 using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
@@ -6,6 +7,7 @@ using MicroCom.Runtime;
 
 namespace Avalonia.Win32.WinRT
 {
+    [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
     internal class WinRTInspectable : IInspectable, IMicroComShadowContainer
     {
         public virtual void Dispose()