diff --git a/build-tools/trim-analyzers/trim-analyzers.props b/build-tools/trim-analyzers/trim-analyzers.props new file mode 100644 index 00000000000..8000a12d74d --- /dev/null +++ b/build-tools/trim-analyzers/trim-analyzers.props @@ -0,0 +1,53 @@ + + + + + true + true + true + + true + + + $(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; + + + + $(WarningsAsErrors); + IL3050;IL3051;IL3052;IL3053;IL3054;IL3055;IL3056; + + + diff --git a/src/Mono.Android/Android.OS/AsyncTask.cs b/src/Mono.Android/Android.OS/AsyncTask.cs index ad5db1b113b..e66a162a145 100644 --- a/src/Mono.Android/Android.OS/AsyncTask.cs +++ b/src/Mono.Android/Android.OS/AsyncTask.cs @@ -9,7 +9,16 @@ namespace Android.OS { [global::System.Runtime.Versioning.ObsoletedOSPlatform ("android30.0")] [Register ("android/os/AsyncTask", DoNotGenerateAcw=true)] - public abstract class AsyncTask : AsyncTask { + public abstract class AsyncTask< + [DynamicallyAccessedMembers (Constructors)] + TParams, + [DynamicallyAccessedMembers (Constructors)] + TProgress, + [DynamicallyAccessedMembers (Constructors)] + TResult + > : AsyncTask { + + const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors; static IntPtr java_class_handle; internal static IntPtr class_ref { diff --git a/src/Mono.Android/Android.Runtime/AndroidEnvironment.cs b/src/Mono.Android/Android.Runtime/AndroidEnvironment.cs index edfe42ec449..b8959b7e5d9 100644 --- a/src/Mono.Android/Android.Runtime/AndroidEnvironment.cs +++ b/src/Mono.Android/Android.Runtime/AndroidEnvironment.cs @@ -24,6 +24,7 @@ public static class AndroidEnvironment { static IX509TrustManager? sslTrustManager; static KeyStore? certStore; static object lock_ = new object (); + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] static Type? httpMessageHandlerType; static void SetupTrustManager () @@ -335,11 +336,16 @@ static IWebProxy GetDefaultProxy () [DynamicDependency (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor, typeof (Xamarin.Android.Net.AndroidMessageHandler))] static object GetHttpMessageHandler () { + [UnconditionalSuppressMessage ("Trimming", "IL2057", Justification = "DynamicDependency should preserve AndroidMessageHandler.")] + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + static Type TypeGetType (string typeName) => + Type.GetType (typeName, throwOnError: false); + if (httpMessageHandlerType is null) { var handlerTypeName = Environment.GetEnvironmentVariable ("XA_HTTP_CLIENT_HANDLER_TYPE")?.Trim (); Type? handlerType = null; if (!String.IsNullOrEmpty (handlerTypeName)) - handlerType = Type.GetType (handlerTypeName, throwOnError: false); + handlerType = TypeGetType (handlerTypeName); // We don't do any type checking or casting here to avoid dependency on System.Net.Http in Mono.Android.dll if (handlerType is null || !IsAcceptableHttpMessageHandlerType (handlerType)) { @@ -355,27 +361,27 @@ static object GetHttpMessageHandler () static bool IsAcceptableHttpMessageHandlerType (Type handlerType) { - if (Extends (handlerType, "System.Net.Http.HttpClientHandler, System.Net.Http")) { + if (Type.GetType ("System.Net.Http.HttpClientHandler, System.Net.Http", throwOnError: false) is Type httpClientHandlerType && + httpClientHandlerType.IsAssignableFrom (handlerType)) { // It's not possible to construct HttpClientHandler in this method because it would cause infinite recursion // as HttpClientHandler's constructor calls the GetHttpMessageHandler function Logger.Log (LogLevel.Warn, "MonoAndroid", $"The type {handlerType.AssemblyQualifiedName} cannot be used as the native HTTP handler because it is derived from System.Net.Htt.HttpClientHandler. Use a type that extends System.Net.Http.HttpMessageHandler instead."); return false; } - if (!Extends (handlerType, "System.Net.Http.HttpMessageHandler, System.Net.Http")) { - Logger.Log (LogLevel.Warn, "MonoAndroid", $"The type {handlerType.AssemblyQualifiedName} set as the default HTTP handler is invalid. Use a type that extends System.Net.Http.HttpMessageHandler."); - return false; + if (Type.GetType ("System.Net.Http.HttpMessageHandler, System.Net.Http", throwOnError: false) is Type httpMessageHandlerType && + httpMessageHandlerType.IsAssignableFrom (handlerType)) { + return true; } - return true; - } - - static bool Extends (Type handlerType, string baseTypeName) { - var baseType = Type.GetType (baseTypeName, throwOnError: false); - return baseType?.IsAssignableFrom (handlerType) ?? false; + // Was not an acceptable type + Logger.Log (LogLevel.Warn, "MonoAndroid", $"The type {handlerType.AssemblyQualifiedName} set as the default HTTP handler is invalid. Use a type that extends System.Net.Http.HttpMessageHandler."); + return false; } - static Type GetFallbackHttpMessageHandlerType (string typeName = "Xamarin.Android.Net.AndroidMessageHandler, Mono.Android") + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + static Type GetFallbackHttpMessageHandlerType () { + const string typeName = "Xamarin.Android.Net.AndroidMessageHandler, Mono.Android"; var handlerType = Type.GetType (typeName, throwOnError: false) ?? throw new InvalidOperationException ($"The {typeName} was not found. The type was probably linked away."); diff --git a/src/Mono.Android/Android.Runtime/JNIEnv.cs b/src/Mono.Android/Android.Runtime/JNIEnv.cs index 80f214a1454..d5b39708168 100644 --- a/src/Mono.Android/Android.Runtime/JNIEnv.cs +++ b/src/Mono.Android/Android.Runtime/JNIEnv.cs @@ -16,11 +16,27 @@ namespace Android.Runtime { public static partial class JNIEnv { + const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors; + [ThreadStatic] static byte[]? mvid_bytes; public static IntPtr Handle => JniEnvironment.EnvironmentPointer; + static Array ArrayCreateInstance (Type elementType, int length) => + // FIXME: https://github.com/xamarin/xamarin-android/issues/8724 + // IL3050 disabled in source: if someone uses NativeAOT, they will get the warning. + #pragma warning disable IL3050 + Array.CreateInstance (elementType, length); + #pragma warning restore IL3050 + + static Type MakeArrayType (Type type) => + // FIXME: https://github.com/xamarin/xamarin-android/issues/8724 + // IL3050 disabled in source: if someone uses NativeAOT, they will get the warning. + #pragma warning disable IL3050 + type.MakeArrayType (); + #pragma warning restore IL3050 + internal static IntPtr IdentityHash (IntPtr v) { return JNIEnvInit.LocalRefsAreIndirect ? RuntimeNativeMethods._monodroid_get_identity_hash_code (Handle, v) : v; @@ -807,7 +823,7 @@ public static void CopyArray (IntPtr src, Array dest, Type? elementType = null) throw new ArgumentNullException ("dest"); if (elementType != null && elementType.IsValueType) - AssertCompatibleArrayTypes (src, elementType.MakeArrayType ()); + AssertCompatibleArrayTypes (src, MakeArrayType (elementType)); if (elementType != null && elementType.IsArray) { for (int i = 0; i < dest.Length; ++i) { @@ -950,7 +966,7 @@ public static void CopyArray (Array source, Type elementType, IntPtr dest) throw new ArgumentNullException ("elementType"); if (elementType.IsValueType) - AssertCompatibleArrayTypes (elementType.MakeArrayType (), dest); + AssertCompatibleArrayTypes (MakeArrayType (elementType), dest); Action converter = GetConverter (CopyManagedToNativeArray, elementType, dest); @@ -1057,12 +1073,12 @@ public static void CopyArray (T[] src, IntPtr dest) } } }, { typeof (IJavaObject), (type, source, len) => { - var r = Array.CreateInstance (type!, len); + var r = ArrayCreateInstance (type!, len); CopyArray (source, r, type); return r; } }, { typeof (Array), (type, source, len) => { - var r = Array.CreateInstance (type!, len); + var r = ArrayCreateInstance (type!, len); CopyArray (source, r, type); return r; } }, @@ -1075,7 +1091,7 @@ public static void CopyArray (T[] src, IntPtr dest) return null; if (element_type != null && element_type.IsValueType) - AssertCompatibleArrayTypes (array_ptr, element_type.MakeArrayType ()); + AssertCompatibleArrayTypes (array_ptr, MakeArrayType (element_type)); int cnt = _GetArrayLength (array_ptr); @@ -1130,7 +1146,10 @@ static int _GetArrayLength (IntPtr array_ptr) return ret; } - public static T[]? GetArray (Java.Lang.Object[] array) + public static T[]? GetArray< + [DynamicallyAccessedMembers (Constructors)] + T + > (Java.Lang.Object[] array) { if (array == null) return null; @@ -1244,7 +1263,10 @@ static IntPtr GetArrayElementClass(T[] values) return FindClass (elementType); } - public static void CopyObjectArray(IntPtr source, T[] destination) + public static void CopyObjectArray< + [DynamicallyAccessedMembers (Constructors)] + T + >(IntPtr source, T[] destination) { if (source == IntPtr.Zero) return; diff --git a/src/Mono.Android/Android.Runtime/JavaCollection.cs b/src/Mono.Android/Android.Runtime/JavaCollection.cs index 70660bc24a3..d14ef75766e 100644 --- a/src/Mono.Android/Android.Runtime/JavaCollection.cs +++ b/src/Mono.Android/Android.Runtime/JavaCollection.cs @@ -14,6 +14,8 @@ namespace Android.Runtime { // java.util.Collection allows null values public class JavaCollection : Java.Lang.Object, System.Collections.ICollection { + internal const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors; + internal static IntPtr collection_class = JNIEnv.FindClass ("java/util/Collection"); internal static IntPtr id_add; @@ -148,6 +150,11 @@ internal Java.Lang.Object[] ToArray () // public void CopyTo (Array array, int array_index) { + [UnconditionalSuppressMessage ("Trimming", "IL2073", Justification = "JavaCollection constructors are preserved by the MarkJavaObjects trimmer step.")] + [return: DynamicallyAccessedMembers (Constructors)] + static Type GetElementType (Array array) => + array.GetType ().GetElementType (); + if (array == null) throw new ArgumentNullException ("array"); if (array_index < 0) @@ -164,7 +171,7 @@ public void CopyTo (Array array, int array_index) JavaConvert.FromJniHandle ( JNIEnv.GetObjectArrayElement (lrefArray, i), JniHandleOwnership.TransferLocalRef, - array.GetType ().GetElementType ()), + GetElementType (array)), array_index + i); JNIEnv.DeleteLocalRef (lrefArray); } @@ -202,8 +209,13 @@ public static IntPtr ToLocalJniHandle (ICollection? items) } } + // Preserve FromJniHandle + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] [Register ("java/util/Collection", DoNotGenerateAcw=true)] - public sealed class JavaCollection : JavaCollection, ICollection { + public sealed class JavaCollection< + [DynamicallyAccessedMembers (Constructors)] + T + > : JavaCollection, ICollection { public JavaCollection (IntPtr handle, JniHandleOwnership transfer) : base (handle, transfer) diff --git a/src/Mono.Android/Android.Runtime/JavaDictionary.cs b/src/Mono.Android/Android.Runtime/JavaDictionary.cs index 80656dfc58c..cf6469f7306 100644 --- a/src/Mono.Android/Android.Runtime/JavaDictionary.cs +++ b/src/Mono.Android/Android.Runtime/JavaDictionary.cs @@ -12,6 +12,8 @@ namespace Android.Runtime { // java.util.HashMap allows null keys and values public class JavaDictionary : Java.Lang.Object, System.Collections.IDictionary { + internal const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors; + class DictionaryEnumerator : IDictionaryEnumerator { IEnumerator simple_enumerator; @@ -395,8 +397,15 @@ public static IntPtr ToLocalJniHandle (IDictionary? dictionary) // instantiates a type we don't know at this time, so we have no information about the exceptions // it may throw. // + // Preserve FromJniHandle + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] [Register ("java/util/HashMap", DoNotGenerateAcw=true)] - public class JavaDictionary : JavaDictionary, IDictionary { + public class JavaDictionary< + [DynamicallyAccessedMembers (Constructors)] + K, + [DynamicallyAccessedMembers (Constructors)] + V + > : JavaDictionary, IDictionary { [Register (".ctor", "()V", "")] public JavaDictionary () diff --git a/src/Mono.Android/Android.Runtime/JavaList.cs b/src/Mono.Android/Android.Runtime/JavaList.cs index 980b01f386e..bea4e9b0871 100644 --- a/src/Mono.Android/Android.Runtime/JavaList.cs +++ b/src/Mono.Android/Android.Runtime/JavaList.cs @@ -10,6 +10,7 @@ namespace Android.Runtime { // java.util.ArrayList allows null values public partial class JavaList : Java.Lang.Object, System.Collections.IList { + internal const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors; internal static readonly JniPeerMembers list_members = new XAPeerMembers ("java/util/List", typeof (JavaList), isInterface: true); // @@ -23,7 +24,10 @@ public partial class JavaList : Java.Lang.Object, System.Collections.IList { // // https://developer.android.com/reference/java/util/List.html?hl=en#get(int) // - internal unsafe object? InternalGet (int location, Type? targetType = null) + internal unsafe object? InternalGet ( + int location, + [DynamicallyAccessedMembers (Constructors)] + Type? targetType = null) { const string id = "get.(I)Ljava/lang/Object;"; JniObjectReference obj; @@ -266,6 +270,11 @@ public unsafe bool Contains (object? item) public void CopyTo (Array array, int array_index) { + [UnconditionalSuppressMessage ("Trimming", "IL2073", Justification = "JavaList constructors are preserved by the MarkJavaObjects trimmer step.")] + [return: DynamicallyAccessedMembers (Constructors)] + static Type GetElementType (Array array) => + array.GetType ().GetElementType (); + if (array == null) throw new ArgumentNullException ("array"); if (array_index < 0) @@ -273,7 +282,7 @@ public void CopyTo (Array array, int array_index) if (array.Length < array_index + Count) throw new ArgumentException ("array"); - var targetType = array.GetType ().GetElementType (); + var targetType = GetElementType (array); int c = Count; for (int i = 0; i < c; i++) array.SetValue (InternalGet (i, targetType), array_index + i); @@ -672,8 +681,13 @@ public virtual Java.Lang.Object [] ToArray () #endregion } + // Preserve FromJniHandle + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] [Register ("java/util/ArrayList", DoNotGenerateAcw=true)] - public class JavaList : JavaList, IList { + public class JavaList< + [DynamicallyAccessedMembers (Constructors)] + T + > : JavaList, IList { // // Exception audit: diff --git a/src/Mono.Android/Android.Runtime/JavaSet.cs b/src/Mono.Android/Android.Runtime/JavaSet.cs index c141e1058a4..b84b040289a 100644 --- a/src/Mono.Android/Android.Runtime/JavaSet.cs +++ b/src/Mono.Android/Android.Runtime/JavaSet.cs @@ -268,7 +268,10 @@ public static IntPtr ToLocalJniHandle (ICollection? items) [Register ("java/util/HashSet", DoNotGenerateAcw=true)] // java.util.HashSet allows null - public class JavaSet : JavaSet, ICollection { + public class JavaSet< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] + T + > : JavaSet, ICollection { // // Exception audit: diff --git a/src/Mono.Android/Android.Util/SparseArray.cs b/src/Mono.Android/Android.Util/SparseArray.cs index 0fcd05f31f6..2a895fb7307 100644 --- a/src/Mono.Android/Android.Util/SparseArray.cs +++ b/src/Mono.Android/Android.Util/SparseArray.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using Android.Runtime; @@ -7,7 +8,10 @@ namespace Android.Util { [Register ("android/util/SparseArray", DoNotGenerateAcw=true)] - public partial class SparseArray : SparseArray + public partial class SparseArray< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] + E + > : SparseArray { public SparseArray () { diff --git a/src/Mono.Android/Android.Widget/AdapterView.cs b/src/Mono.Android/Android.Widget/AdapterView.cs index 5ad2293d8e3..7689b0c39e3 100644 --- a/src/Mono.Android/Android.Widget/AdapterView.cs +++ b/src/Mono.Android/Android.Widget/AdapterView.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using Android.Views; using JLO = Java.Lang.Object; @@ -49,7 +50,10 @@ public event EventHandler ItemSelectionCleared { } [Register ("android/widget/AdapterView", DoNotGenerateAcw=true)] - public abstract class AdapterView : AdapterView where T : IAdapter { + public abstract class AdapterView< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] + T + > : AdapterView where T : IAdapter { public AdapterView (IntPtr handle, JniHandleOwnership transfer) : base (handle, transfer) diff --git a/src/Mono.Android/Android.Widget/ArrayAdapter.cs b/src/Mono.Android/Android.Widget/ArrayAdapter.cs index cf35e67fc07..e54ce8d7c94 100644 --- a/src/Mono.Android/Android.Widget/ArrayAdapter.cs +++ b/src/Mono.Android/Android.Widget/ArrayAdapter.cs @@ -8,7 +8,10 @@ namespace Android.Widget { [Register ("android/widget/ArrayAdapter", DoNotGenerateAcw=true)] - public partial class ArrayAdapter : ArrayAdapter { + public partial class ArrayAdapter< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] + T + > : ArrayAdapter { public ArrayAdapter (IntPtr handle, JniHandleOwnership transfer) : base (handle, transfer) diff --git a/src/Mono.Android/Java.Interop/JavaConvert.cs b/src/Mono.Android/Java.Interop/JavaConvert.cs index c98bc8cd2f2..ba3307c3fd2 100644 --- a/src/Mono.Android/Java.Interop/JavaConvert.cs +++ b/src/Mono.Android/Java.Interop/JavaConvert.cs @@ -10,6 +10,7 @@ namespace Java.Interop { static class JavaConvert { + const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors; static Dictionary> JniHandleConverters = new Dictionary>() { { typeof (bool), (handle, transfer) => { @@ -56,27 +57,42 @@ static class JavaConvert { static Func? GetJniHandleConverter (Type? target) { + const string justification = "JavaDictionary<,>, JavaList<>, and JavaCollection<> use DynamicallyAccessedMembers for PublicMethods to preserve FromJniHandle()."; + [UnconditionalSuppressMessage ("Trimming", "IL2055", Justification = justification)] + [UnconditionalSuppressMessage ("Trimming", "IL2068", Justification = justification)] + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + static Type MakeGenericType (Type type, params Type [] typeArguments) => + // FIXME: https://github.com/xamarin/xamarin-android/issues/8724 + // IL3050 disabled in source: if someone uses NativeAOT, they will get the warning. + #pragma warning disable IL3050 + type.MakeGenericType (typeArguments); + #pragma warning restore IL3050 + + [UnconditionalSuppressMessage ("Trimming", "IL2073", Justification = "Array element type's constructors should be preserved by the MarkJavaObjects trimmer step.")] + [return: DynamicallyAccessedMembers (Constructors)] + static Type GetElementType (Type type) => type.GetElementType (); + if (target == null) return null; if (JniHandleConverters.TryGetValue (target, out var converter)) return converter; if (target.IsArray) - return (h, t) => JNIEnv.GetArray (h, t, target.GetElementType ()); + return (h, t) => JNIEnv.GetArray (h, t, GetElementType (target)); if (target.IsGenericType && target.GetGenericTypeDefinition() == typeof (IDictionary<,>)) { - Type t = typeof (JavaDictionary<,>).MakeGenericType (target.GetGenericArguments ()); + Type t = MakeGenericType (typeof (JavaDictionary<,>), target.GetGenericArguments ()); return GetJniHandleConverterForType (t); } if (typeof (IDictionary).IsAssignableFrom (target)) return (h, t) => JavaDictionary.FromJniHandle (h, t); if (target.IsGenericType && target.GetGenericTypeDefinition() == typeof (IList<>)) { - Type t = typeof (JavaList<>).MakeGenericType (target.GetGenericArguments ()); + Type t = MakeGenericType (typeof (JavaList<>), target.GetGenericArguments ()); return GetJniHandleConverterForType (t); } if (typeof (IList).IsAssignableFrom (target)) return (h, t) => JavaList.FromJniHandle (h, t); if (target.IsGenericType && target.GetGenericTypeDefinition() == typeof (ICollection<>)) { - Type t = typeof (JavaCollection<>).MakeGenericType (target.GetGenericArguments ()); + Type t = MakeGenericType (typeof (JavaCollection<>), target.GetGenericArguments ()); return GetJniHandleConverterForType (t); } if (typeof (ICollection).IsAssignableFrom (target)) @@ -92,13 +108,19 @@ static Func GetJniHandleConverterForType ([D typeof (Func), m); } - public static T? FromJniHandle(IntPtr handle, JniHandleOwnership transfer) + public static T? FromJniHandle< + [DynamicallyAccessedMembers (Constructors)] + T + >(IntPtr handle, JniHandleOwnership transfer) { bool set; return FromJniHandle(handle, transfer, out set); } - public static T? FromJniHandle(IntPtr handle, JniHandleOwnership transfer, out bool set) + public static T? FromJniHandle< + [DynamicallyAccessedMembers (Constructors)] + T + >(IntPtr handle, JniHandleOwnership transfer, out bool set) { if (handle == IntPtr.Zero) { set = false; @@ -133,7 +155,11 @@ static Func GetJniHandleConverterForType ([D return (T?) Convert.ChangeType (v, typeof (T), CultureInfo.InvariantCulture); } - public static object? FromJniHandle (IntPtr handle, JniHandleOwnership transfer, Type? targetType = null) + public static object? FromJniHandle ( + IntPtr handle, + JniHandleOwnership transfer, + [DynamicallyAccessedMembers (Constructors)] + Type? targetType = null) { if (handle == IntPtr.Zero) { return null; @@ -206,13 +232,19 @@ static Func GetJniHandleConverterForType ([D return null; } - public static T? FromJavaObject(IJavaObject? value) + public static T? FromJavaObject< + [DynamicallyAccessedMembers (Constructors)] + T + >(IJavaObject? value) { bool set; return FromJavaObject(value, out set); } - public static T? FromJavaObject(IJavaObject? value, out bool set) + public static T? FromJavaObject< + [DynamicallyAccessedMembers (Constructors)] + T + >(IJavaObject? value, out bool set) { if (value == null) { set = false; @@ -245,7 +277,10 @@ static Func GetJniHandleConverterForType ([D return (T) Convert.ChangeType (value, typeof (T), CultureInfo.InvariantCulture); } - public static object? FromJavaObject (IJavaObject value, Type? targetType = null) + public static object? FromJavaObject ( + IJavaObject value, + [DynamicallyAccessedMembers (Constructors)] + Type? targetType = null) { if (value == null) return null; diff --git a/src/Mono.Android/Java.Interop/JavaObjectExtensions.cs b/src/Mono.Android/Java.Interop/JavaObjectExtensions.cs index 5b083487c5b..345c664c61d 100644 --- a/src/Mono.Android/Java.Interop/JavaObjectExtensions.cs +++ b/src/Mono.Android/Java.Interop/JavaObjectExtensions.cs @@ -17,7 +17,10 @@ public static JavaCollection ToInteroperableCollection (this ICollection instanc } [Obsolete ("Use Android.Runtime.JavaCollection.ToLocalJniHandle()")] - public static JavaCollection ToInteroperableCollection (this ICollection instance) + public static JavaCollection ToInteroperableCollection< + [DynamicallyAccessedMembers (Constructors)] + T + > (this ICollection instance) { return instance is JavaCollection ? (JavaCollection) instance : new JavaCollection (instance); } @@ -29,7 +32,10 @@ public static JavaList ToInteroperableCollection (this IList instance) } [Obsolete ("Use Android.Runtime.JavaList.ToLocalJniHandle()")] - public static JavaList ToInteroperableCollection (this IList instance) + public static JavaList ToInteroperableCollection< + [DynamicallyAccessedMembers (Constructors)] + T + > (this IList instance) { return instance is JavaList ? (JavaList) instance : new JavaList (instance); } @@ -41,7 +47,12 @@ public static JavaDictionary ToInteroperableCollection (this IDictionary instanc } [Obsolete ("Use Android.Runtime.JavaDictionary.ToLocalJniHandle()")] - public static JavaDictionary ToInteroperableCollection (this IDictionary instance) + public static JavaDictionary ToInteroperableCollection< + [DynamicallyAccessedMembers (Constructors)] + K, + [DynamicallyAccessedMembers (Constructors)] + V + > (this IDictionary instance) { return instance is JavaDictionary ? (JavaDictionary) instance : new JavaDictionary (instance); } diff --git a/src/Mono.Android/Mono.Android.csproj b/src/Mono.Android/Mono.Android.csproj index 006ebd5eb41..4ed01cacea2 100644 --- a/src/Mono.Android/Mono.Android.csproj +++ b/src/Mono.Android/Mono.Android.csproj @@ -3,6 +3,7 @@ + $(DotNetTargetFramework) diff --git a/src/Mono.Android/System.Linq/Extensions.cs b/src/Mono.Android/System.Linq/Extensions.cs index ac555e17949..c8bb0a4a740 100644 --- a/src/Mono.Android/System.Linq/Extensions.cs +++ b/src/Mono.Android/System.Linq/Extensions.cs @@ -9,6 +9,8 @@ namespace System.Linq { public static class Extensions { + const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors; + static IntPtr id_next; static Extensions () @@ -40,7 +42,10 @@ internal static IEnumerator ToEnumerator_Dispose (this Java.Util.IIterator sourc } } - public static IEnumerable ToEnumerable (this Java.Lang.IIterable source) + public static IEnumerable ToEnumerable< + [DynamicallyAccessedMembers (Constructors)] + T + > (this Java.Lang.IIterable source) { if (source == null) throw new ArgumentNullException ("source"); @@ -52,7 +57,10 @@ internal static IEnumerator ToEnumerator_Dispose (this Java.Util.IIterator sourc } } - internal static IEnumerator ToEnumerator_Dispose (this Java.Util.IIterator source) + internal static IEnumerator ToEnumerator_Dispose< + [DynamicallyAccessedMembers (Constructors)] + T + > (this Java.Util.IIterator source) { using (source) while (source.HasNext) { diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc index 7bd5cb51f7c..905a5bfcc28 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Resources/Base/BuildReleaseArm64SimpleDotNet.apkdesc @@ -5,61 +5,61 @@ "Size": 3036 }, "assemblies/_Microsoft.Android.Resource.Designer.dll": { - "Size": 1028 + "Size": 1027 }, "assemblies/Java.Interop.dll": { - "Size": 61587 + "Size": 64375 }, "assemblies/Mono.Android.dll": { - "Size": 90798 + "Size": 96440 }, "assemblies/Mono.Android.Runtime.dll": { - "Size": 5225 + "Size": 5141 }, "assemblies/rc.bin": { "Size": 1512 }, "assemblies/System.Console.dll": { - "Size": 6546 + "Size": 6544 }, "assemblies/System.Linq.dll": { - "Size": 8553 + "Size": 8557 }, "assemblies/System.Private.CoreLib.dll": { - "Size": 553721 + "Size": 565531 }, "assemblies/System.Runtime.dll": { - "Size": 2550 + "Size": 2546 }, "assemblies/System.Runtime.InteropServices.dll": { - "Size": 4026 + "Size": 4022 }, "assemblies/UnnamedProject.dll": { - "Size": 2936 + "Size": 2934 }, "classes.dex": { - "Size": 377856 + "Size": 377748 }, "lib/arm64-v8a/libmono-component-marshal-ilgen.so": { - "Size": 87080 + "Size": 87352 }, "lib/arm64-v8a/libmonodroid.so": { - "Size": 339864 + "Size": 343896 }, "lib/arm64-v8a/libmonosgen-2.0.so": { - "Size": 3186504 + "Size": 3210968 }, "lib/arm64-v8a/libSystem.IO.Compression.Native.so": { "Size": 723560 }, "lib/arm64-v8a/libSystem.Native.so": { - "Size": 94504 + "Size": 94720 }, "lib/arm64-v8a/libSystem.Security.Cryptography.Native.Android.so": { - "Size": 155560 + "Size": 155568 }, "lib/arm64-v8a/libxamarin-app.so": { - "Size": 11680 + "Size": 12424 }, "META-INF/BNDLTOOL.RSA": { "Size": 1223 @@ -95,5 +95,5 @@ "Size": 1904 } }, - "PackageSize": 2783562 + "PackageSize": 2824522 } \ No newline at end of file