From 7482f462ca658387611cda8d5dd0223ce328bd5f Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Mon, 12 Feb 2024 21:22:06 -0600 Subject: [PATCH 01/11] [Java.Interop] ignore remaining trimming warnings Fixes: https://github.com/xamarin/java.interop/issues/1157 The remaining trimmer warnings are around usage of System.Reflection such as: * Create an `Invoker` type from an original type via `Type.Assembly.GetType()` * Create a `Type` based on a `ParameterInfo.ParameterType` and/or create instances * Use `Type.MakeGenericType()` * Use `Type.MakeArrayType()` The trimming warnings themselves all indicate that these types "might be trimmed", in that nothing explicitly preserves them. However, we have a plethora of custom trimmer steps that work to preserve these types involved in Java interop, such as: * https://github.com/xamarin/xamarin-android/blob/main/src/Microsoft.Android.Sdk.ILLink/PreserveApplications.cs * https://github.com/xamarin/xamarin-android/blob/main/src/Microsoft.Android.Sdk.ILLink/PreserveExportedTypes.cs * https://github.com/xamarin/xamarin-android/blob/main/src/Microsoft.Android.Sdk.ILLink/PreserveJavaExceptions.cs * https://github.com/xamarin/xamarin-android/blob/main/src/Microsoft.Android.Sdk.ILLink/PreserveJavaInterfaces.cs * https://github.com/xamarin/xamarin-android/blob/main/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs One day, in a perfect world, we could remove these trimmer steps and completely rely on the trimmer's warnings & attributing mechanisms. That day doesn't have to be today -- as our goal is begin surfacing trimmer warnings to users in their own code and dependencies. With these warnings ignored, we can fully enable analyzers with: true true We can then remove: [assembly: AssemblyMetadata ("IsTrimmable", "True")] As the MSBuild property does this for us, in addition to enabling analyzers. I don't think we should enable `$(IsAotCompatible)` quite yet, as `Java.Interop.dll` likely *won't work* yet on NativeAOT, and this places metadata that says an assembly is supported. We should just use the `$(EnableAotAnalyzer)` analyzers for now, so we don't introduce new issues. --- src/Java.Interop/Java.Interop.csproj | 5 ++--- .../JniRuntime.JniMarshalMemberBuilder.cs | 1 + .../Java.Interop/JniRuntime.JniTypeManager.cs | 9 +++++++++ .../Java.Interop/JniRuntime.JniValueManager.cs | 11 +++++++++++ src/Java.Interop/Java.Interop/ManagedPeer.cs | 1 + src/Java.Interop/Properties/AssemblyInfo.cs | 1 - 6 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/Java.Interop/Java.Interop.csproj b/src/Java.Interop/Java.Interop.csproj index 51bb3a90d..80eb91aee 100644 --- a/src/Java.Interop/Java.Interop.csproj +++ b/src/Java.Interop/Java.Interop.csproj @@ -15,9 +15,8 @@ enable true true - - - + true + true NU1702 diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs index e52bae71b..e72089de9 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs @@ -150,6 +150,7 @@ string GetTypeSignature (ParameterInfo p) throw new NotSupportedException ("Don't know how to determine JNI signature for parameter type: " + p.ParameterType.FullName + "."); } + [UnconditionalSuppressMessage ("Trimming", "IL2072", Justification = "Method parameter types should be preserved via other means.")] public JniValueMarshaler GetParameterMarshaler (ParameterInfo parameter) { if (parameter.ParameterType == typeof (IntPtr)) diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs index 12bbff89b..c6669a074 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs @@ -271,6 +271,7 @@ protected virtual IEnumerable GetSimpleReferences (Type type) static readonly Type[] EmptyTypeArray = Array.Empty (); + [UnconditionalSuppressMessage ("Trimming", "IL2073", Justification = "Types returned here should be preserved via other means.")] [return: DynamicallyAccessedMembers (MethodsConstructorsInterfaces)] public Type? GetType (JniTypeSignature typeSignature) { @@ -288,6 +289,8 @@ public virtual IEnumerable GetTypes (JniTypeSignature typeSignature) return CreateGetTypesEnumerator (typeSignature); } + [UnconditionalSuppressMessage ("Trimming", "IL2075", Justification = "JavaObjectArray types should be preserved via other means.")] + [UnconditionalSuppressMessage ("AOT", "IL3050", Justification = "Array types should be preserved via other means.")] IEnumerable CreateGetTypesEnumerator (JniTypeSignature typeSignature) { if (!typeSignature.IsValid) @@ -325,6 +328,8 @@ IEnumerable CreateGetTypesEnumerator (JniTypeSignature typeSignature) } } + [UnconditionalSuppressMessage ("Trimming", "IL2075", Justification = "JavaObjectArray types should be preserved via other means.")] + [UnconditionalSuppressMessage ("AOT", "IL3050", Justification = "Array types should be preserved via other means.")] IEnumerable GetPrimitiveArrayTypesForSimpleReference (JniTypeSignature typeSignature, Type type) { int index = -1; @@ -462,6 +467,10 @@ protected bool TryRegisterNativeMembers ( static Type [] registerMethodParameters = new Type [] { typeof (JniNativeMethodRegistrationArguments) }; + const string MarshalMethods = "'jni_marshal_methods' should be preserved via other means."; + + [UnconditionalSuppressMessage ("Trimming", "IL2072", Justification = MarshalMethods)] + [UnconditionalSuppressMessage ("Trimming", "IL2075", Justification = MarshalMethods)] bool TryLoadJniMarshalMethods ( JniType nativeClass, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs index 91e862dc7..fc64df39f 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs @@ -355,7 +355,14 @@ static Type GetPeerType ([DynamicallyAccessedMembers (Constructors)] Type type) return null; } + const string AssemblyGetType = "'Invoker' types are preserved via other means."; + const string MakeGenericType = "Generic 'Invoker' types are preserved via other means."; + [return: DynamicallyAccessedMembers (Constructors)] + [UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = AssemblyGetType)] + [UnconditionalSuppressMessage ("Trimming", "IL2073", Justification = AssemblyGetType)] + [UnconditionalSuppressMessage ("Trimming", "IL2055", Justification = MakeGenericType)] + [UnconditionalSuppressMessage ("AOT", "IL3050", Justification = MakeGenericType)] static Type? GetInvokerType (Type type) { const string suffix = "Invoker"; @@ -632,6 +639,10 @@ public JniValueMarshaler GetValueMarshaler ( return GetValueMarshalerCore (type); } + const string MakeGenericMethod = "Generic methods used here, should be preserved via other means."; + + [UnconditionalSuppressMessage ("Trimming", "IL2060", Justification = MakeGenericMethod)] + [UnconditionalSuppressMessage ("AOT", "IL3050", Justification = MakeGenericMethod)] static JniValueMarshaler GetObjectArrayMarshaler (Type elementType) { Func indirect = GetObjectArrayMarshalerHelper; diff --git a/src/Java.Interop/Java.Interop/ManagedPeer.cs b/src/Java.Interop/Java.Interop/ManagedPeer.cs index f3874b635..0c13dcda6 100644 --- a/src/Java.Interop/Java.Interop/ManagedPeer.cs +++ b/src/Java.Interop/Java.Interop/ManagedPeer.cs @@ -227,6 +227,7 @@ static List[] GetConstructorCandidateParameterTypes (string signature) return candidateParameterTypes; } + [UnconditionalSuppressMessage ("Trimming", "IL2072", Justification = "Constructor parameter types should be preserved via other means.")] static object?[]? GetValues (JniRuntime runtime, JniObjectReference values, ConstructorInfo cinfo) { if (!values.IsValid) diff --git a/src/Java.Interop/Properties/AssemblyInfo.cs b/src/Java.Interop/Properties/AssemblyInfo.cs index b32e4cf93..01afd8e26 100644 --- a/src/Java.Interop/Properties/AssemblyInfo.cs +++ b/src/Java.Interop/Properties/AssemblyInfo.cs @@ -6,7 +6,6 @@ [assembly: AssemblyDescription ("")] [assembly: AssemblyCulture ("")] [assembly: AssemblyTrademark ("Microsoft Corporation")] -[assembly: AssemblyMetadata ("IsTrimmable", "True")] [assembly: InternalsVisibleTo ( "Java.Interop.GenericMarshaler, PublicKey=" + From 33bd50195eec18640d8f1c86692abd07e5b68e93 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Tue, 13 Feb 2024 12:36:47 -0600 Subject: [PATCH 02/11] Cleaner suppressions around `Invoker` types --- .../JniRuntime.JniValueManager.cs | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs index fc64df39f..7d31a3446 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs @@ -355,29 +355,40 @@ static Type GetPeerType ([DynamicallyAccessedMembers (Constructors)] Type type) return null; } - const string AssemblyGetType = "'Invoker' types are preserved via other means."; - const string MakeGenericType = "Generic 'Invoker' types are preserved via other means."; - [return: DynamicallyAccessedMembers (Constructors)] - [UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = AssemblyGetType)] - [UnconditionalSuppressMessage ("Trimming", "IL2073", Justification = AssemblyGetType)] - [UnconditionalSuppressMessage ("Trimming", "IL2055", Justification = MakeGenericType)] - [UnconditionalSuppressMessage ("AOT", "IL3050", Justification = MakeGenericType)] static Type? GetInvokerType (Type type) { const string suffix = "Invoker"; + + // https://github.com/xamarin/xamarin-android/blob/5472eec991cc075e4b0c09cd98a2331fb93aa0f3/src/Microsoft.Android.Sdk.ILLink/MarkJavaObjects.cs#L176-L186 + const string assemblyGetTypeMessage = "'Invoker' types are preserved by the MarkJavaObjects trimmer step."; + const string makeGenericTypeMessage = "Generic 'Invoker' types are preserved by the MarkJavaObjects trimmer step."; + + [UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = assemblyGetTypeMessage)] + [UnconditionalSuppressMessage ("Trimming", "IL2073", Justification = assemblyGetTypeMessage)] + [return: DynamicallyAccessedMembers (Constructors)] + static Type? AssemblyGetType(Assembly assembly, string typeName) => + assembly.GetType (typeName); + + [UnconditionalSuppressMessage ("Trimming", "IL2055", Justification = makeGenericTypeMessage)] + // FIXME: https://github.com/xamarin/java.interop/issues/1192 + [UnconditionalSuppressMessage ("AOT", "IL3050", Justification = makeGenericTypeMessage)] + [return: DynamicallyAccessedMembers (Constructors)] + static Type MakeGenericType (Type type, Type [] arguments) => + type.MakeGenericType (arguments); + Type[] arguments = type.GetGenericArguments (); if (arguments.Length == 0) - return type.Assembly.GetType (type + suffix); + return AssemblyGetType (type.Assembly, type + suffix); Type definition = type.GetGenericTypeDefinition (); int bt = definition.FullName!.IndexOf ("`", StringComparison.Ordinal); if (bt == -1) throw new NotSupportedException ("Generic type doesn't follow generic type naming convention! " + type.FullName); - Type? suffixDefinition = definition.Assembly.GetType ( + Type? suffixDefinition = AssemblyGetType (definition.Assembly, definition.FullName.Substring (0, bt) + suffix + definition.FullName.Substring (bt)); if (suffixDefinition == null) return null; - return suffixDefinition.MakeGenericType (arguments); + return MakeGenericType (suffixDefinition, arguments); } public object? CreateValue ( From 4522d35c7ffb55456db2cd10466946fb504f84b8 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Tue, 13 Feb 2024 13:17:01 -0600 Subject: [PATCH 03/11] Cleaner suppressions for `GetObjectArrayMarshaler` --- .../Java.Interop/JniRuntime.JniValueManager.cs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs index 7d31a3446..8a2dee2af 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs @@ -370,8 +370,8 @@ static Type GetPeerType ([DynamicallyAccessedMembers (Constructors)] Type type) static Type? AssemblyGetType(Assembly assembly, string typeName) => assembly.GetType (typeName); - [UnconditionalSuppressMessage ("Trimming", "IL2055", Justification = makeGenericTypeMessage)] // FIXME: https://github.com/xamarin/java.interop/issues/1192 + [UnconditionalSuppressMessage ("Trimming", "IL2055", Justification = makeGenericTypeMessage)] [UnconditionalSuppressMessage ("AOT", "IL3050", Justification = makeGenericTypeMessage)] [return: DynamicallyAccessedMembers (Constructors)] static Type MakeGenericType (Type type, Type [] arguments) => @@ -650,15 +650,19 @@ public JniValueMarshaler GetValueMarshaler ( return GetValueMarshalerCore (type); } - const string MakeGenericMethod = "Generic methods used here, should be preserved via other means."; - - [UnconditionalSuppressMessage ("Trimming", "IL2060", Justification = MakeGenericMethod)] - [UnconditionalSuppressMessage ("AOT", "IL3050", Justification = MakeGenericMethod)] static JniValueMarshaler GetObjectArrayMarshaler (Type elementType) { + const string makeGenericMethodMessage = "This code path is not used in Android projects."; + + // FIXME: https://github.com/xamarin/java.interop/issues/1192 + [UnconditionalSuppressMessage ("Trimming", "IL2060", Justification = makeGenericMethodMessage)] + [UnconditionalSuppressMessage ("AOT", "IL3050", Justification = makeGenericMethodMessage)] + static MethodInfo MakeGenericMethod (MethodInfo method, Type type) => + method.MakeGenericMethod (type); + Func indirect = GetObjectArrayMarshalerHelper; - var reifiedMethodInfo = indirect.Method.GetGenericMethodDefinition () - .MakeGenericMethod (elementType); + var reifiedMethodInfo = MakeGenericMethod ( + indirect.Method.GetGenericMethodDefinition (), elementType); Func direct = (Func) Delegate.CreateDelegate (typeof (Func), reifiedMethodInfo); return direct (); } From 9c7a05af6349f195b6c60a1150a156d53f8887e2 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Tue, 13 Feb 2024 13:29:03 -0600 Subject: [PATCH 04/11] Cleaner suppressions for GetParameterMarshaler --- .../Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs | 9 +++++++-- .../Java.Interop/JniValueMarshalerAttribute.cs | 9 ++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs index e72089de9..e2c6047cf 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniMarshalMemberBuilder.cs @@ -150,9 +150,14 @@ string GetTypeSignature (ParameterInfo p) throw new NotSupportedException ("Don't know how to determine JNI signature for parameter type: " + p.ParameterType.FullName + "."); } - [UnconditionalSuppressMessage ("Trimming", "IL2072", Justification = "Method parameter types should be preserved via other means.")] public JniValueMarshaler GetParameterMarshaler (ParameterInfo parameter) { + // Activator.CreateInstance requires DynamicallyAccessedMemberTypes.PublicParameterlessConstructor + // GetValueMarshaler requires DynamicallyAccessedMemberTypes.Interfaces + [UnconditionalSuppressMessage ("Trimming", "IL2072", Justification = "JniValueMarshalerAttribute is decorated with [DynamicallyAccessedMembers]")] + static JniValueMarshaler GetValueMarshaler (JniValueManager manager, ParameterInfo parameter) => + manager.GetValueMarshaler (parameter.ParameterType); + if (parameter.ParameterType == typeof (IntPtr)) return IntPtrValueMarshaler.Instance; @@ -165,7 +170,7 @@ public JniValueMarshaler GetParameterMarshaler (ParameterInfo parameter) if (attr != null) { return (JniValueMarshaler) Activator.CreateInstance (attr.MarshalerType)!; } - return Runtime.ValueManager.GetValueMarshaler (parameter.ParameterType); + return GetValueMarshaler (Runtime.ValueManager, parameter); } // Heuristic: if first two parameters are IntPtr, this is a "direct" wrapper. diff --git a/src/Java.Interop/Java.Interop/JniValueMarshalerAttribute.cs b/src/Java.Interop/Java.Interop/JniValueMarshalerAttribute.cs index f4869fcf1..b674094be 100644 --- a/src/Java.Interop/Java.Interop/JniValueMarshalerAttribute.cs +++ b/src/Java.Interop/Java.Interop/JniValueMarshalerAttribute.cs @@ -1,4 +1,4 @@ -#nullable enable +#nullable enable using System; using System.Diagnostics.CodeAnalysis; @@ -8,13 +8,16 @@ namespace Java.Interop { [AttributeUsage (Targets, AllowMultiple=false)] public class JniValueMarshalerAttribute : Attribute { + const DynamicallyAccessedMemberTypes ParameterlessConstructorsInterfaces = DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.Interfaces; const AttributeTargets Targets = AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Interface | AttributeTargets.Struct | AttributeTargets.Parameter | AttributeTargets.ReturnValue; - public JniValueMarshalerAttribute (Type marshalerType) + public JniValueMarshalerAttribute ( + [DynamicallyAccessedMembers (ParameterlessConstructorsInterfaces)] + Type marshalerType) { if (marshalerType == null) throw new ArgumentNullException (nameof (marshalerType)); @@ -27,7 +30,7 @@ public JniValueMarshalerAttribute (Type marshalerType) } public Type MarshalerType { - [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + [return: DynamicallyAccessedMembers (ParameterlessConstructorsInterfaces)] get; } } From 530068250bc25d3cada857683400339805557621 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Tue, 13 Feb 2024 13:39:30 -0600 Subject: [PATCH 05/11] Cleaner suppression for ManagedPeer --- src/Java.Interop/Java.Interop/ManagedPeer.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Java.Interop/Java.Interop/ManagedPeer.cs b/src/Java.Interop/Java.Interop/ManagedPeer.cs index 0c13dcda6..4311a1c50 100644 --- a/src/Java.Interop/Java.Interop/ManagedPeer.cs +++ b/src/Java.Interop/Java.Interop/ManagedPeer.cs @@ -227,9 +227,13 @@ static List[] GetConstructorCandidateParameterTypes (string signature) return candidateParameterTypes; } - [UnconditionalSuppressMessage ("Trimming", "IL2072", Justification = "Constructor parameter types should be preserved via other means.")] static object?[]? GetValues (JniRuntime runtime, JniObjectReference values, ConstructorInfo cinfo) { + // https://github.com/xamarin/xamarin-android/blob/5472eec991cc075e4b0c09cd98a2331fb93aa0f3/src/Microsoft.Android.Sdk.ILLink/MarkJavaObjects.cs#L51-L132 + [UnconditionalSuppressMessage ("Trimming", "IL2072", Justification = "Constructors are preserved by the MarkJavaObjects trimmer step.")] + static object? ValueManagerGetValue(JniRuntime runtime, ref JniObjectReference value, ParameterInfo parameter) => + runtime.ValueManager.GetValue (ref value, JniObjectReferenceOptions.CopyAndDispose, parameter.ParameterType); + if (!values.IsValid) return null; @@ -241,7 +245,7 @@ static List[] GetConstructorCandidateParameterTypes (string signature) var pvalues = new object? [len]; for (int i = 0; i < len; ++i) { var n_value = JniEnvironment.Arrays.GetObjectArrayElement (values, i); - var value = runtime.ValueManager.GetValue (ref n_value, JniObjectReferenceOptions.CopyAndDispose, parameters [i].ParameterType); + var value = ValueManagerGetValue (runtime, ref n_value, parameters [i]); pvalues [i] = value; } From 502e852c1673cba1a0803bd5ccdf3f008faf8312 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Tue, 13 Feb 2024 16:34:27 -0600 Subject: [PATCH 06/11] Cleaner suppression for JniRuntime.JniTypeManager.cs --- .../Java.Interop/JniRuntime.JniTypeManager.cs | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs index c6669a074..819746098 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs @@ -270,6 +270,15 @@ protected virtual IEnumerable GetSimpleReferences (Type type) static readonly string[] EmptyStringArray = Array.Empty (); static readonly Type[] EmptyTypeArray = Array.Empty (); + // FIXME: https://github.com/xamarin/java.interop/issues/1192 + [UnconditionalSuppressMessage ("AOT", "IL3050", Justification = "This code path is not used in Android projects")] + static Type MakeArrayType (Type type) => type.MakeArrayType (); + + // FIXME: https://github.com/xamarin/java.interop/issues/1192 + [UnconditionalSuppressMessage ("Trimming", "IL2055", Justification = "This code path is not used in Android projects")] + [UnconditionalSuppressMessage ("AOT", "IL3050", Justification = "This code path is not used in Android projects")] + static Type MakeGenericType (Type type, Type arrayType) => type.MakeGenericType (arrayType); + [UnconditionalSuppressMessage ("Trimming", "IL2073", Justification = "Types returned here should be preserved via other means.")] [return: DynamicallyAccessedMembers (MethodsConstructorsInterfaces)] @@ -289,8 +298,6 @@ public virtual IEnumerable GetTypes (JniTypeSignature typeSignature) return CreateGetTypesEnumerator (typeSignature); } - [UnconditionalSuppressMessage ("Trimming", "IL2075", Justification = "JavaObjectArray types should be preserved via other means.")] - [UnconditionalSuppressMessage ("AOT", "IL3050", Justification = "Array types should be preserved via other means.")] IEnumerable CreateGetTypesEnumerator (JniTypeSignature typeSignature) { if (!typeSignature.IsValid) @@ -312,7 +319,7 @@ IEnumerable CreateGetTypesEnumerator (JniTypeSignature typeSignature) var rank = typeSignature.ArrayRank; var arrayType = type; while (rank-- > 0) { - arrayType = typeof (JavaObjectArray<>).MakeGenericType (arrayType); + arrayType = MakeGenericType(typeof(JavaObjectArray<>), arrayType); } yield return arrayType; } @@ -321,15 +328,13 @@ IEnumerable CreateGetTypesEnumerator (JniTypeSignature typeSignature) var rank = typeSignature.ArrayRank; var arrayType = type; while (rank-- > 0) { - arrayType = arrayType.MakeArrayType (); + arrayType = MakeArrayType (arrayType); } yield return arrayType; } } } - [UnconditionalSuppressMessage ("Trimming", "IL2075", Justification = "JavaObjectArray types should be preserved via other means.")] - [UnconditionalSuppressMessage ("AOT", "IL3050", Justification = "Array types should be preserved via other means.")] IEnumerable GetPrimitiveArrayTypesForSimpleReference (JniTypeSignature typeSignature, Type type) { int index = -1; @@ -346,14 +351,14 @@ IEnumerable GetPrimitiveArrayTypesForSimpleReference (JniTypeSignature typ var rank = typeSignature.ArrayRank-1; var arrayType = t; while (rank-- > 0) { - arrayType = typeof (JavaObjectArray<>).MakeGenericType (arrayType); + arrayType = MakeGenericType (typeof (JavaObjectArray<>), arrayType); } yield return arrayType; rank = typeSignature.ArrayRank-1; arrayType = t; while (rank-- > 0) { - arrayType = arrayType.MakeArrayType (); + arrayType = MakeArrayType (arrayType); } yield return arrayType; } From a493d157295c47ca5e72bafbb24a14c343a711b1 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Tue, 13 Feb 2024 16:36:14 -0600 Subject: [PATCH 07/11] Formatting --- src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs index 819746098..ce1ceaf93 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs @@ -319,7 +319,7 @@ IEnumerable CreateGetTypesEnumerator (JniTypeSignature typeSignature) var rank = typeSignature.ArrayRank; var arrayType = type; while (rank-- > 0) { - arrayType = MakeGenericType(typeof(JavaObjectArray<>), arrayType); + arrayType = MakeGenericType (typeof (JavaObjectArray<>), arrayType); } yield return arrayType; } From ea2ff539e2b1c45592be1664b46fb799233cfa8a Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Tue, 13 Feb 2024 16:41:47 -0600 Subject: [PATCH 08/11] Update JniRuntime.JniTypeManager.cs --- src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs index ce1ceaf93..34f60b76f 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs @@ -472,7 +472,8 @@ protected bool TryRegisterNativeMembers ( static Type [] registerMethodParameters = new Type [] { typeof (JniNativeMethodRegistrationArguments) }; - const string MarshalMethods = "'jni_marshal_methods' should be preserved via other means."; + // https://github.com/xamarin/xamarin-android/blob/5472eec991cc075e4b0c09cd98a2331fb93aa0f3/src/Microsoft.Android.Sdk.ILLink/PreserveRegistrations.cs#L85 + const string MarshalMethods = "'jni_marshal_methods' is preserved by the PreserveRegistrations trimmer step."; [UnconditionalSuppressMessage ("Trimming", "IL2072", Justification = MarshalMethods)] [UnconditionalSuppressMessage ("Trimming", "IL2075", Justification = MarshalMethods)] From ad5019d31c910e4f1d2fdfbfbd893d55e726069a Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Tue, 13 Feb 2024 16:43:13 -0600 Subject: [PATCH 09/11] Update JniRuntime.JniTypeManager.cs --- src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs index 34f60b76f..df1c6e772 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs @@ -269,14 +269,15 @@ protected virtual IEnumerable GetSimpleReferences (Type type) static readonly string[] EmptyStringArray = Array.Empty (); static readonly Type[] EmptyTypeArray = Array.Empty (); + const string NotUsedInAndroid = "This code path is not used in Android projects."; // FIXME: https://github.com/xamarin/java.interop/issues/1192 - [UnconditionalSuppressMessage ("AOT", "IL3050", Justification = "This code path is not used in Android projects")] + [UnconditionalSuppressMessage ("AOT", "IL3050", Justification = NotUsedInAndroid)] static Type MakeArrayType (Type type) => type.MakeArrayType (); // FIXME: https://github.com/xamarin/java.interop/issues/1192 - [UnconditionalSuppressMessage ("Trimming", "IL2055", Justification = "This code path is not used in Android projects")] - [UnconditionalSuppressMessage ("AOT", "IL3050", Justification = "This code path is not used in Android projects")] + [UnconditionalSuppressMessage ("Trimming", "IL2055", Justification = NotUsedInAndroid)] + [UnconditionalSuppressMessage ("AOT", "IL3050", Justification = NotUsedInAndroid)] static Type MakeGenericType (Type type, Type arrayType) => type.MakeGenericType (arrayType); From f6bb01051baa7d3971dc474eb36d57449143c384 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Wed, 14 Feb 2024 10:49:56 -0600 Subject: [PATCH 10/11] Formatting --- src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs | 2 +- src/Java.Interop/Java.Interop/ManagedPeer.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs index 8a2dee2af..181469f6d 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs @@ -367,7 +367,7 @@ static Type GetPeerType ([DynamicallyAccessedMembers (Constructors)] Type type) [UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = assemblyGetTypeMessage)] [UnconditionalSuppressMessage ("Trimming", "IL2073", Justification = assemblyGetTypeMessage)] [return: DynamicallyAccessedMembers (Constructors)] - static Type? AssemblyGetType(Assembly assembly, string typeName) => + static Type? AssemblyGetType (Assembly assembly, string typeName) => assembly.GetType (typeName); // FIXME: https://github.com/xamarin/java.interop/issues/1192 diff --git a/src/Java.Interop/Java.Interop/ManagedPeer.cs b/src/Java.Interop/Java.Interop/ManagedPeer.cs index 4311a1c50..763e439f2 100644 --- a/src/Java.Interop/Java.Interop/ManagedPeer.cs +++ b/src/Java.Interop/Java.Interop/ManagedPeer.cs @@ -231,7 +231,7 @@ static List[] GetConstructorCandidateParameterTypes (string signature) { // https://github.com/xamarin/xamarin-android/blob/5472eec991cc075e4b0c09cd98a2331fb93aa0f3/src/Microsoft.Android.Sdk.ILLink/MarkJavaObjects.cs#L51-L132 [UnconditionalSuppressMessage ("Trimming", "IL2072", Justification = "Constructors are preserved by the MarkJavaObjects trimmer step.")] - static object? ValueManagerGetValue(JniRuntime runtime, ref JniObjectReference value, ParameterInfo parameter) => + static object? ValueManagerGetValue (JniRuntime runtime, ref JniObjectReference value, ParameterInfo parameter) => runtime.ValueManager.GetValue (ref value, JniObjectReferenceOptions.CopyAndDispose, parameter.ParameterType); if (!values.IsValid) From aea690e4bb23d8825e3898d1bc7e1685047b2f3e Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Wed, 14 Feb 2024 10:50:33 -0600 Subject: [PATCH 11/11] Extra newline --- src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs index df1c6e772..6e4867192 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs @@ -280,7 +280,6 @@ protected virtual IEnumerable GetSimpleReferences (Type type) [UnconditionalSuppressMessage ("AOT", "IL3050", Justification = NotUsedInAndroid)] static Type MakeGenericType (Type type, Type arrayType) => type.MakeGenericType (arrayType); - [UnconditionalSuppressMessage ("Trimming", "IL2073", Justification = "Types returned here should be preserved via other means.")] [return: DynamicallyAccessedMembers (MethodsConstructorsInterfaces)] public Type? GetType (JniTypeSignature typeSignature)