Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Mono.Android] is now "trimming safe" (#8778)
Fixes: #5652 Add `build-tools/trim-analyzers/trim-analyzers.props`, which when `<Import/>`ed into a project will enable trimmer analyzers and enable `$(WarningsAsErrors)` for the warnings listed below so that that these trimmer warnings need to be fixed as part of the build: * IL2000 through IL2129 * IL3050 through IL3056 Update `Mono.Android.csproj` to import `trim-analyzers.props`. Address the trimmer warnings that are now errors ~~ `$(AndroidHttpClientHandlerType)` and AndroidEnvironment ~~ The default `HttpClientHandler` type used with `new HttpClient()` can be controlled via the [`$(AndroidHttpClientHandlerType)`][0] MSBuild property, which sets the `$XA_HTTP_CLIENT_HANDLER_TYPE` environment variable, which is used with `Type.GetType()`. (Setting `$(AndroidHttpClientHandlerType)` [is rare][1], has not been deprecated, and thus is supported.) The trimmer only supports `Type.GetType()` with string constants, not with runtime values such as environment variables. This results in numerous trimmer warnings: src\Mono.Android\Android.Runtime\AndroidEnvironment.cs(373,19): error IL2057: Unrecognized value passed to the parameter 'typeName' of method 'System.Type.GetType(String, Boolean)'. It's not possible to guarantee the availability of the target type. src\Mono.Android\Android.Runtime\AndroidEnvironment.cs(379,22): error IL2057: Unrecognized value passed to the parameter 'typeName' of method 'System.Type.GetType(String, Boolean)'. It's not possible to guarantee the availability of the target type. src\Mono.Android\Android.Runtime\AndroidEnvironment.cs(342,20): error IL2057: Unrecognized value passed to the parameter 'typeName' of method 'System.Type.GetType(String, Boolean)'. It's not possible to guarantee the availability of the target type. src\Mono.Android\Android.Runtime\AndroidEnvironment.cs(352,11): error IL2077: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicParameterlessConstructor' in call to 'System.Activator.CreateInstance(Type)'. The field 'Android.Runtime.AndroidEnvironment.httpMessageHandlerType' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. Partially address these issues by: * Using string constants instead of default parameter values. // This works static Type GetFallbackHttpMessageHandlerType() { const string typeName = "Xamarin.Android.Net.AndroidMessageHandler, Mono.Android"; Type.GetType(typeName, …); } // This does not, as the *caller* gets the value static Type GetFallbackHttpMessageHandlerType(string typeName = "Xamarin.Android.Net.AndroidMessageHandler, Mono.Android") { Type.GetType(typeName, …); } * Spread `[DynamicallyAccessedMembers]` around to fix IL2077. * Use `[UnconditionalSuppressMessage]` to explicitly suppress IL2057 TODO: we need to *actually preserve* the type referenced by `$(AndroidHttpClientHandlerType)`. * #8797 ~~ JavaConvert ~~ `JavaConvert` is used internally to marshal between Java and managed types, and elicits numerous trimmer warnings: src\Mono.Android\Java.Interop\JavaConvert.cs(223,12): error IL2091: 'TResult' generic argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors', 'DynamicallyAccessedMemberTypes.NonPublicConstructors' in 'Java.Interop.JavaObjectExtensions._JavaCast<TResult>(IJavaObject)'. The generic parameter 'T' of 'Java.Interop.JavaConvert.FromJavaObject<T>(IJavaObject, out Boolean)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. src\Mono.Android\Java.Interop\JavaConvert.cs(254,12): error IL2067: 'resultType' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors', 'DynamicallyAccessedMemberTypes.NonPublicConstructors' in call to 'Java.Interop.JavaObjectExtensions.JavaCast(IJavaObject, Type)'. The parameter 'targetType' of method 'Java.Interop.JavaConvert.FromJavaObject(IJavaObject, Type)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. src\Mono.Android\Java.Interop\JavaConvert.cs(67,14): error IL3050: Using member 'System.Type.MakeGenericType(params Type[])' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. The native code for this instantiation might not be available at runtime. src\Mono.Android\Java.Interop\JavaConvert.cs(73,14): error IL3050: Using member 'System.Type.MakeGenericType(params Type[])' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. The native code for this instantiation might not be available at runtime. src\Mono.Android\Java.Interop\JavaConvert.cs(79,14): error IL3050: Using member 'System.Type.MakeGenericType(params Type[])' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. The native code for this instantiation might not be available at runtime. Address these by adding `[DynamicallyAccessedMembers]` to assist the trimmer, `#pragma warning disable` to suppress the IL3050 warning, and `[UnconditionalSuppressMessage]` to ignore the IL2055 warnings. This trickled over to require more attributes for: * `AdapterView` * `ArrayAdapter` * `AsyncTask` * `JavaCollection` * `JavaDictionary` * `JavaList` * `JavaList` * `JavaObjectExtensions` * `JavaSet` * `SparseArray` * `System.Linq\Extensions` ~~ JNIEnv ~~ `JNIEnv` is also used internally to marshal between Java and managed types, and elicits numerous trimmer warnings: src\Mono.Android\Android.Runtime\JNIEnv.cs(810,38): error IL3050: Using member 'System.Type.MakeArrayType()' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. The code for an array of the specified type might not be available. src\Mono.Android\Android.Runtime\JNIEnv.cs(953,33): error IL3050: Using member 'System.Type.MakeArrayType()' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. The code for an array of the specified type might not be available. src\Mono.Android\Android.Runtime\JNIEnv.cs(1078,44): error IL3050: Using member 'System.Type.MakeArrayType()' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. The code for an array of the specified type might not be available. src\Mono.Android\Android.Runtime\JNIEnv.cs(1139,15): error IL2091: 'T' generic argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors', 'DynamicallyAccessedMemberTypes.NonPublicConstructors' in 'Java.Interop.JavaConvert.FromJavaObject<T>(IJavaObject)'. The generic parameter 'T' of 'Android.Runtime.JNIEnv.GetArray<T>(Object[])' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. src\Mono.Android\Android.Runtime\JNIEnv.cs(1060,14): error IL3050: Using member 'System.Array.CreateInstance(Type, Int32)' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. The code for an array of the specified type might not be available. src\Mono.Android\Android.Runtime\JNIEnv.cs(1065,14): error IL3050: Using member 'System.Array.CreateInstance(Type, Int32)' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. The code for an array of the specified type might not be available. src\Mono.Android\Android.Runtime\JNIEnv.cs(1257,23): error IL2091: 'T' generic argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors', 'DynamicallyAccessedMemberTypes.NonPublicConstructors' in 'Java.Interop.JavaConvert.FromJniHandle<T>(nint, JniHandleOwnership)'. The generic parameter 'T' of 'Android.Runtime.JNIEnv.CopyObjectArray<T>(nint, T[])' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. Adding `[DynamicallyAccessedMembers]` fixes the IL2091 warnings. Use `#pragma warning disable` to ignore the IL3050 warnings around `Array.CreateInstance()` and `Type.MakeArrayType()`. TODO: try to fix these issues instead of suppressing them: * #8724 [0]: https://github.com/xamarin/xamarin-android/blob/c20d51fcf8e910b8fb46c5351c26e55ed1fab90c/Documentation/guides/building-apps/build-properties.md#androidhttpclienthandlertype [1]: https://github.com/search?q=%3CAndroidHttpClientHandlerType%3E+NOT+Xamarin.Android.Net+NOT+System.Net.Http+NOT+Default&type=code
- Loading branch information