Skip to content

Commit 4a456bc

Browse files
[java.interop] address some "easy" trimmer warnings
Context: #1157 On the path to enabling `IsAotCompatible`, we can enable some settings to get started: <IsTrimmable>true</IsTrimmable> <EnableSingleFileAnalyzer>true</EnableSingleFileAnalyzer> <EnableAotAnalyzer>true</EnableAotAnalyzer> This opts into the analyzers without declaring the assembly is fully AOT-compatible. Starting out, I got 33 warnings: this is an attempt to address the ones that don't require too much thinking. Unfortunately, solving 1 warning likely will create dozens more -- as you have to update all callers. This results in 24 warnings remaining. Since `Release` builds have `$(TreatWarningsAsErrors)`, I will wait to enable the analyzers until all warnings are addressed. ~~ Example Warnings ~~ `System.Linq.Expression` usage: src\Java.Interop\Java.Interop\JniRuntime.JniValueManager.cs(672,58): warning IL2026: Using member 'System.Linq.Expressions.Expression.Property(Expression, String)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Creating Expressions requires unreferenced code because the members being referenced by the Expression may be trimmed. I decorated this one with: [RequiresUnreferencedCode (ExpressionRequiresUnreferencedCode)] `Type.GetNestedType()` usage: src\Java.Interop\Java.Interop\JniRuntime.JniTypeManager.cs(447,28): warning IL2070: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.NonPublicNestedTypes' in call to 'System.Type.GetNestedType(String, BindingFlags)'. The parameter 'type' of method 'Java.Interop.JniRuntime.JniTypeManager.TryLoadJniMarshalMethods(JniType, Type, String)' 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. Added: [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] `Activator.CreateInstance()` usage: src\Java.Interop\Java.Interop\JniRuntime.JniValueManager.cs(542,33): warning IL2072: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicParameterlessConstructor' in call to 'System.Activator.CreateInstance(Type)'. The return value of method 'Java.Interop.JniValueMarshalerAttribute.MarshalerType.get' 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. Added: [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] ~~ Code that Actually Changed ~~ As I enabled more attributes, these snowball into more and more warnings! I eventually had to make `GetPeerType()` look like: [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] static Type GetPeerType ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type type) The analyzer was not able to understand code like: static readonly KeyValuePair<Type, Type>[] PeerTypeMappings = new []{ new KeyValuePair<Type, Type>(typeof (object), typeof (JavaObject)), new KeyValuePair<Type, Type>(typeof (IJavaPeerable), typeof (JavaObject)), new KeyValuePair<Type, Type>(typeof (Exception), typeof (JavaException)), }; //... foreach (var m in PeerTypeMappings) { if (m.Key == type) return m.Value; } Simply removing the `PeerTypeMappings` array and using `if` statements solved the warnings. This may be the only real code change if any.
1 parent 07c7300 commit 4a456bc

14 files changed

+168
-97
lines changed

src/Java.Interop/Java.Interop.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
1515
<Nullable>enable</Nullable>
1616
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
17+
<EnableSingleFileAnalyzer>true</EnableSingleFileAnalyzer>
18+
<!-- TODO: enable these when all warnings are solved -->
19+
<!--<IsTrimmable>true</IsTrimmable>-->
20+
<!--<EnableAotAnalyzer>true</EnableAotAnalyzer>-->
1721
<MSBuildWarningsAsMessages>NU1702</MSBuildWarningsAsMessages>
1822
</PropertyGroup>
1923
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">

src/Java.Interop/Java.Interop/JavaArray.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ namespace Java.Interop
1212
{
1313
public abstract class JavaArray<T> : JavaObject, IList, IList<T>
1414
{
15+
internal const DynamicallyAccessedMemberTypes ConstructorsAndInterfaces = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.Interfaces;
16+
1517
internal delegate TArray ArrayCreator<TArray> (ref JniObjectReference reference, JniObjectReferenceOptions transfer)
1618
where TArray : JavaArray<T>;
1719

@@ -362,7 +364,7 @@ public void Dispose ()
362364
}
363365
}
364366

365-
public abstract class JavaPrimitiveArray<T> : JavaArray<T> {
367+
public abstract class JavaPrimitiveArray<[DynamicallyAccessedMembers (ConstructorsAndInterfaces)] T> : JavaArray<T> {
366368

367369
internal JavaPrimitiveArray (ref JniObjectReference reference, JniObjectReferenceOptions transfer)
368370
: base (ref reference, transfer)

src/Java.Interop/Java.Interop/JavaObjectArray.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#nullable enable
1+
#nullable enable
22

33
using System;
44
using System.Collections.Generic;
@@ -7,7 +7,7 @@
77

88
namespace Java.Interop
99
{
10-
public class JavaObjectArray<T> : JavaArray<T>
10+
public class JavaObjectArray<[DynamicallyAccessedMembers (ConstructorsAndInterfaces)] T> : JavaArray<T>
1111
{
1212
internal static readonly ValueMarshaler Instance = new ValueMarshaler ();
1313

@@ -164,7 +164,7 @@ internal override bool TargetTypeIsCurrentType (Type? targetType)
164164

165165
internal sealed class ValueMarshaler : JniValueMarshaler<IList<T>> {
166166

167-
public override IList<T> CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType)
167+
public override IList<T> CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, [DynamicallyAccessedMembers (ConstructorsAndInterfaces)] Type? targetType)
168168
{
169169
return JavaArray<T>.CreateValue (ref reference, options, targetType, (ref JniObjectReference h, JniObjectReferenceOptions t) => new JavaObjectArray<T> (ref h, t) {
170170
forMarshalCollection = true,
@@ -194,7 +194,7 @@ partial class JniEnvironment {
194194
[SuppressMessage ("Design", "CA1034", Justification = "https://github.com/xamarin/Java.Interop/commit/bb7ca5d02aa3fc2b447ad57af1256e74e5f954fa")]
195195
partial class Arrays {
196196

197-
public static JavaObjectArray<T>? CreateMarshalObjectArray<T> (IEnumerable<T>? value)
197+
public static JavaObjectArray<T>? CreateMarshalObjectArray<[DynamicallyAccessedMembers (JavaArray<T>.ConstructorsAndInterfaces)] T> (IEnumerable<T>? value)
198198
{
199199
if (value == null) {
200200
return null;

src/Java.Interop/Java.Interop/JavaPrimitiveArrays.cs

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -244,14 +244,14 @@ internal override bool TargetTypeIsCurrentType (Type? targetType)
244244
typeof (JavaBooleanArray) == targetType;
245245
}
246246

247-
public static object? CreateMarshaledValue (IntPtr handle, Type? targetType)
247+
public static object? CreateMarshaledValue (IntPtr handle, [DynamicallyAccessedMembers(JniValueMarshaler.ConstructorsAndInterfaces)] Type? targetType)
248248
{
249249
return ArrayMarshaler.CreateValue (handle, targetType);
250250
}
251251

252252
internal sealed class ValueMarshaler : JniValueMarshaler<IList<Boolean>> {
253253

254-
public override IList<Boolean> CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType)
254+
public override IList<Boolean> CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, [DynamicallyAccessedMembers (ConstructorsAndInterfaces)] Type? targetType)
255255
{
256256
return JavaArray<Boolean>.CreateValue (
257257
ref reference,
@@ -276,6 +276,7 @@ public override void DestroyGenericArgumentState ([AllowNull] IList<Boolean> val
276276
JavaArray<Boolean>.DestroyArgumentState<JavaBooleanArray> (value, ref state, synchronize);
277277
}
278278

279+
[RequiresUnreferencedCode (ExpressionRequiresUnreferencedCode)]
279280
public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null)
280281
{
281282
Func<IntPtr, Type?, object?> m = JavaBooleanArray.CreateMarshaledValue;
@@ -439,14 +440,14 @@ internal override bool TargetTypeIsCurrentType (Type? targetType)
439440
typeof (JavaSByteArray) == targetType;
440441
}
441442

442-
public static object? CreateMarshaledValue (IntPtr handle, Type? targetType)
443+
public static object? CreateMarshaledValue (IntPtr handle, [DynamicallyAccessedMembers (JniValueMarshaler.ConstructorsAndInterfaces)] Type? targetType)
443444
{
444445
return ArrayMarshaler.CreateValue (handle, targetType);
445446
}
446447

447448
internal sealed class ValueMarshaler : JniValueMarshaler<IList<SByte>> {
448449

449-
public override IList<SByte> CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType)
450+
public override IList<SByte> CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, [DynamicallyAccessedMembers (ConstructorsAndInterfaces)] Type? targetType)
450451
{
451452
return JavaArray<SByte>.CreateValue (
452453
ref reference,
@@ -471,6 +472,7 @@ public override void DestroyGenericArgumentState ([AllowNull] IList<SByte> value
471472
JavaArray<SByte>.DestroyArgumentState<JavaSByteArray> (value, ref state, synchronize);
472473
}
473474

475+
[RequiresUnreferencedCode (ExpressionRequiresUnreferencedCode)]
474476
public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null)
475477
{
476478
Func<IntPtr, Type?, object?> m = JavaSByteArray.CreateMarshaledValue;
@@ -634,14 +636,14 @@ internal override bool TargetTypeIsCurrentType (Type? targetType)
634636
typeof (JavaCharArray) == targetType;
635637
}
636638

637-
public static object? CreateMarshaledValue (IntPtr handle, Type? targetType)
639+
public static object? CreateMarshaledValue (IntPtr handle, [DynamicallyAccessedMembers (JniValueMarshaler.ConstructorsAndInterfaces)] Type? targetType)
638640
{
639641
return ArrayMarshaler.CreateValue (handle, targetType);
640642
}
641643

642644
internal sealed class ValueMarshaler : JniValueMarshaler<IList<Char>> {
643645

644-
public override IList<Char> CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType)
646+
public override IList<Char> CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, [DynamicallyAccessedMembers (ConstructorsAndInterfaces)] Type? targetType)
645647
{
646648
return JavaArray<Char>.CreateValue (
647649
ref reference,
@@ -666,6 +668,7 @@ public override void DestroyGenericArgumentState ([AllowNull] IList<Char> value,
666668
JavaArray<Char>.DestroyArgumentState<JavaCharArray> (value, ref state, synchronize);
667669
}
668670

671+
[RequiresUnreferencedCode (ExpressionRequiresUnreferencedCode)]
669672
public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null)
670673
{
671674
Func<IntPtr, Type?, object?> m = JavaCharArray.CreateMarshaledValue;
@@ -829,14 +832,14 @@ internal override bool TargetTypeIsCurrentType (Type? targetType)
829832
typeof (JavaInt16Array) == targetType;
830833
}
831834

832-
public static object? CreateMarshaledValue (IntPtr handle, Type? targetType)
835+
public static object? CreateMarshaledValue (IntPtr handle, [DynamicallyAccessedMembers (JniValueMarshaler.ConstructorsAndInterfaces)] Type? targetType)
833836
{
834837
return ArrayMarshaler.CreateValue (handle, targetType);
835838
}
836839

837840
internal sealed class ValueMarshaler : JniValueMarshaler<IList<Int16>> {
838841

839-
public override IList<Int16> CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType)
842+
public override IList<Int16> CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, [DynamicallyAccessedMembers (ConstructorsAndInterfaces)] Type? targetType)
840843
{
841844
return JavaArray<Int16>.CreateValue (
842845
ref reference,
@@ -861,6 +864,7 @@ public override void DestroyGenericArgumentState ([AllowNull] IList<Int16> value
861864
JavaArray<Int16>.DestroyArgumentState<JavaInt16Array> (value, ref state, synchronize);
862865
}
863866

867+
[RequiresUnreferencedCode (ExpressionRequiresUnreferencedCode)]
864868
public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null)
865869
{
866870
Func<IntPtr, Type?, object?> m = JavaInt16Array.CreateMarshaledValue;
@@ -1024,14 +1028,14 @@ internal override bool TargetTypeIsCurrentType (Type? targetType)
10241028
typeof (JavaInt32Array) == targetType;
10251029
}
10261030

1027-
public static object? CreateMarshaledValue (IntPtr handle, Type? targetType)
1031+
public static object? CreateMarshaledValue (IntPtr handle, [DynamicallyAccessedMembers (JniValueMarshaler.ConstructorsAndInterfaces)] Type? targetType)
10281032
{
10291033
return ArrayMarshaler.CreateValue (handle, targetType);
10301034
}
10311035

10321036
internal sealed class ValueMarshaler : JniValueMarshaler<IList<Int32>> {
10331037

1034-
public override IList<Int32> CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType)
1038+
public override IList<Int32> CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, [DynamicallyAccessedMembers (ConstructorsAndInterfaces)] Type? targetType)
10351039
{
10361040
return JavaArray<Int32>.CreateValue (
10371041
ref reference,
@@ -1056,6 +1060,7 @@ public override void DestroyGenericArgumentState ([AllowNull] IList<Int32> value
10561060
JavaArray<Int32>.DestroyArgumentState<JavaInt32Array> (value, ref state, synchronize);
10571061
}
10581062

1063+
[RequiresUnreferencedCode (ExpressionRequiresUnreferencedCode)]
10591064
public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null)
10601065
{
10611066
Func<IntPtr, Type?, object?> m = JavaInt32Array.CreateMarshaledValue;
@@ -1219,14 +1224,14 @@ internal override bool TargetTypeIsCurrentType (Type? targetType)
12191224
typeof (JavaInt64Array) == targetType;
12201225
}
12211226

1222-
public static object? CreateMarshaledValue (IntPtr handle, Type? targetType)
1227+
public static object? CreateMarshaledValue (IntPtr handle, [DynamicallyAccessedMembers (JniValueMarshaler.ConstructorsAndInterfaces)] Type? targetType)
12231228
{
12241229
return ArrayMarshaler.CreateValue (handle, targetType);
12251230
}
12261231

12271232
internal sealed class ValueMarshaler : JniValueMarshaler<IList<Int64>> {
12281233

1229-
public override IList<Int64> CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType)
1234+
public override IList<Int64> CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, [DynamicallyAccessedMembers (ConstructorsAndInterfaces)] Type? targetType)
12301235
{
12311236
return JavaArray<Int64>.CreateValue (
12321237
ref reference,
@@ -1251,6 +1256,7 @@ public override void DestroyGenericArgumentState ([AllowNull] IList<Int64> value
12511256
JavaArray<Int64>.DestroyArgumentState<JavaInt64Array> (value, ref state, synchronize);
12521257
}
12531258

1259+
[RequiresUnreferencedCode (ExpressionRequiresUnreferencedCode)]
12541260
public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null)
12551261
{
12561262
Func<IntPtr, Type?, object?> m = JavaInt64Array.CreateMarshaledValue;
@@ -1414,14 +1420,14 @@ internal override bool TargetTypeIsCurrentType (Type? targetType)
14141420
typeof (JavaSingleArray) == targetType;
14151421
}
14161422

1417-
public static object? CreateMarshaledValue (IntPtr handle, Type? targetType)
1423+
public static object? CreateMarshaledValue (IntPtr handle, [DynamicallyAccessedMembers (JniValueMarshaler.ConstructorsAndInterfaces)] Type? targetType)
14181424
{
14191425
return ArrayMarshaler.CreateValue (handle, targetType);
14201426
}
14211427

14221428
internal sealed class ValueMarshaler : JniValueMarshaler<IList<Single>> {
14231429

1424-
public override IList<Single> CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType)
1430+
public override IList<Single> CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, [DynamicallyAccessedMembers (ConstructorsAndInterfaces)] Type? targetType)
14251431
{
14261432
return JavaArray<Single>.CreateValue (
14271433
ref reference,
@@ -1446,6 +1452,7 @@ public override void DestroyGenericArgumentState ([AllowNull] IList<Single> valu
14461452
JavaArray<Single>.DestroyArgumentState<JavaSingleArray> (value, ref state, synchronize);
14471453
}
14481454

1455+
[RequiresUnreferencedCode (ExpressionRequiresUnreferencedCode)]
14491456
public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null)
14501457
{
14511458
Func<IntPtr, Type?, object?> m = JavaSingleArray.CreateMarshaledValue;
@@ -1609,14 +1616,14 @@ internal override bool TargetTypeIsCurrentType (Type? targetType)
16091616
typeof (JavaDoubleArray) == targetType;
16101617
}
16111618

1612-
public static object? CreateMarshaledValue (IntPtr handle, Type? targetType)
1619+
public static object? CreateMarshaledValue (IntPtr handle, [DynamicallyAccessedMembers (JniValueMarshaler.ConstructorsAndInterfaces)] Type? targetType)
16131620
{
16141621
return ArrayMarshaler.CreateValue (handle, targetType);
16151622
}
16161623

16171624
internal sealed class ValueMarshaler : JniValueMarshaler<IList<Double>> {
16181625

1619-
public override IList<Double> CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType)
1626+
public override IList<Double> CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, [DynamicallyAccessedMembers (ConstructorsAndInterfaces)] Type? targetType)
16201627
{
16211628
return JavaArray<Double>.CreateValue (
16221629
ref reference,
@@ -1641,6 +1648,7 @@ public override void DestroyGenericArgumentState ([AllowNull] IList<Double> valu
16411648
JavaArray<Double>.DestroyArgumentState<JavaDoubleArray> (value, ref state, synchronize);
16421649
}
16431650

1651+
[RequiresUnreferencedCode (ExpressionRequiresUnreferencedCode)]
16441652
public override Expression CreateParameterToManagedExpression (JniValueMarshalerContext context, ParameterExpression sourceValue, ParameterAttributes synchronize = 0, Type? targetType = null)
16451653
{
16461654
Func<IntPtr, Type?, object?> m = JavaDoubleArray.CreateMarshaledValue;

src/Java.Interop/Java.Interop/JavaPrimitiveArrays.tt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ namespace Java.Interop {
248248

249249
internal sealed class ValueMarshaler : JniValueMarshaler<IList<<#= info.TypeModifier #>>> {
250250

251-
public override IList<<#= info.TypeModifier #>> CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, Type? targetType)
251+
public override IList<<#= info.TypeModifier #>> CreateGenericValue (ref JniObjectReference reference, JniObjectReferenceOptions options, [DynamicallyAccessedMembers (ConstructorsAndInterfaces)] Type? targetType)
252252
{
253253
return JavaArray<<#= info.TypeModifier #>>.CreateValue (
254254
ref reference,

0 commit comments

Comments
 (0)