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