Skip to content

Commit 81405c2

Browse files
[Java.Interop.Tools.TypeNameMappings] fix trimmer warnings
Context: https://github.com/xamarin/xamarin-android/blob/e987ac458536e59a8329a06d5c5d5f4d4ea2c6b6/src/Mono.Android/Mono.Android.csproj#L69-L71 In xamarin/xamarin-android, we import the source for `Java.Interop.Tools.TypeNameMappings\JavaNativeTypeManager.cs`, and unfortunately there are some trimmer warnings: external\Java.Interop\src\Java.Interop.Tools.TypeNameMappings\Java.Interop.Tools.TypeNameMappings\JavaNativeTypeManager.cs(182,9): error IL2070: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.Interfaces' in call to 'System.Type.GetInterfaces()'. The parameter 'type' of method 'Java.Interop.Tools.TypeNameMappings.JavaNativeTypeManager.ToJniName(Type, ExportParameterKind)' 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. From the code: if (!type.GetInterfaces ().Any (t => t.FullName == "Android.Runtime.IJavaObject")) It appears we can instead look for `IJavaPeerable` and use trim-safe behavior instead: if (Type.GetType ("Java.Interop.IJavaPeerable, Java.Interop", throwOnError: true) .IsAssignableFrom (type)) I also cached the `Type.GetType()` call with `Lazy<T>`. To catch warnings in this project going forward: * Multi-target to `netstandard2.0` and `net8.0` using `$(DotNetTargetFramework)`. `netstandard2.0` is used for MSBuild-task assemblies inside VS. * Enable trimmer warnings for `net8.0` As I targeted `net8.0`, various null-reference-type warnings appeared, which I also fixed.
1 parent c6e3893 commit 81405c2

File tree

4 files changed

+28
-14
lines changed

4 files changed

+28
-14
lines changed

src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers.csproj

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>netstandard2.0</TargetFramework>
4+
<XAConfigPath>..\..\bin\Build$(Configuration)\XAConfig.props</XAConfigPath>
5+
</PropertyGroup>
6+
<Import Condition="Exists ('$(XAConfigPath)')" Project="$(XAConfigPath)" />
7+
8+
<PropertyGroup>
9+
<TargetFrameworks>netstandard2.0;$(DotNetTargetFramework)</TargetFrameworks>
510
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
611
<LangVersion>8.0</LangVersion>
712
<Nullable>enable</Nullable>
@@ -17,13 +22,19 @@
1722
<OutputPath>$(ToolOutputFullPath)</OutputPath>
1823
</PropertyGroup>
1924

25+
<PropertyGroup Condition=" '$(TargetFramework)' != 'netstandard2.0' ">
26+
<IsTrimmable>true</IsTrimmable>
27+
<EnableSingleFileAnalyzer>true</EnableSingleFileAnalyzer>
28+
<EnableAotAnalyzer>true</EnableAotAnalyzer>
29+
</PropertyGroup>
30+
2031
<Import Project="..\..\build-tools\scripts\cecil.projitems" />
2132

2233
<ItemGroup>
2334
<Compile Include="..\Java.Interop.Tools.TypeNameMappings\Java.Interop.Tools.TypeNameMappings\JavaNativeTypeManager.cs">
2435
<Link>JavaNativeTypeManager.cs</Link>
2536
</Compile>
26-
<Compile Include="..\utils\NullableAttributes.cs">
37+
<Compile Include="..\utils\NullableAttributes.cs" Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
2738
<Link>NullableAttributes.cs</Link>
2839
</Compile>
2940
</ItemGroup>

src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers/JavaCallableWrapperGenerator.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ void AddNestedTypes (TypeDefinition type)
203203
};
204204
foreach (var bt in type.GetBaseTypes (cache)) {
205205
ctorTypes.Add (bt);
206-
RegisterAttribute rattr = GetMethodRegistrationAttributes (bt).FirstOrDefault ();
206+
RegisterAttribute? rattr = GetMethodRegistrationAttributes (bt).FirstOrDefault ();
207207
if (rattr != null && rattr.DoNotGenerateAcw)
208208
break;
209209
}
@@ -296,7 +296,7 @@ void AddConstructor (MethodDefinition ctor, TypeDefinition type, string? outerTy
296296
return;
297297
}
298298

299-
ExportAttribute eattr = GetExportAttributes (ctor).FirstOrDefault ();
299+
ExportAttribute? eattr = GetExportAttributes (ctor).FirstOrDefault ();
300300
if (eattr != null) {
301301
if (!string.IsNullOrEmpty (eattr.Name)) {
302302
// Diagnostic.Warning (log, "Use of ExportAttribute.Name property is invalid on constructors");
@@ -306,7 +306,7 @@ void AddConstructor (MethodDefinition ctor, TypeDefinition type, string? outerTy
306306
return;
307307
}
308308

309-
RegisterAttribute rattr = GetMethodRegistrationAttributes (ctor).FirstOrDefault ();
309+
RegisterAttribute? rattr = GetMethodRegistrationAttributes (ctor).FirstOrDefault ();
310310
if (rattr != null) {
311311
if (ctors.Any (c => c.JniSignature == rattr.Signature))
312312
return;
@@ -513,7 +513,7 @@ static IEnumerable<ExportFieldAttribute> GetExportFieldAttributes (Mono.Cecil.IC
513513
static IEnumerable<TAttribute> GetAttributes<TAttribute> (Mono.Cecil.ICustomAttributeProvider p, Func<CustomAttribute, TAttribute?> selector)
514514
where TAttribute : class
515515
{
516-
return GetAttributes (p, typeof (TAttribute).FullName, selector);
516+
return GetAttributes (p, typeof (TAttribute).FullName!, selector);
517517
}
518518

519519
static IEnumerable<TAttribute> GetAttributes<TAttribute> (Mono.Cecil.ICustomAttributeProvider p, string attributeName, Func<CustomAttribute, TAttribute?> selector)
@@ -702,13 +702,13 @@ static void WriteAnnotations (string indent, TextWriter sw, IEnumerable<CustomAt
702702
static string ManagedValueToJavaSource (object value)
703703
{
704704
if (value is string)
705-
return "\"" + value.ToString ().Replace ("\"", "\"\"") + '"';
705+
return "\"" + value.ToString ()?.Replace ("\"", "\"\"") + '"';
706706
else if (value.GetType ().FullName == "Java.Lang.Class")
707707
return value.ToString () + ".class";
708708
else if (value is bool)
709709
return ((bool) value) ? "true" : "false";
710710
else
711-
return value.ToString ();
711+
return value.ToString () ?? "";
712712
}
713713

714714
void GenerateHeader (TextWriter sw)
@@ -1160,7 +1160,7 @@ void WriteInstrumentationOnCreate (TextWriter sw, Action<TextWriter> extra)
11601160
StreamWriter OpenStream (string outputPath)
11611161
{
11621162
string destination = GetDestinationPath (outputPath);
1163-
Directory.CreateDirectory (Path.GetDirectoryName (destination));
1163+
Directory.CreateDirectory (Path.GetDirectoryName (destination)!);
11641164
return new StreamWriter (new FileStream (destination, FileMode.Create, FileAccess.Write));
11651165
}
11661166

src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers/TypeNameMapGenerator.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ Dictionary<string, string> GetTypeMapping (Func<TypeDefinition, bool> skipType,
179179

180180
var k = key (type, Cache);
181181

182-
TypeDefinition e;
182+
TypeDefinition? e;
183183
if (!typeMap.TryGetValue (k, out e)) {
184184
typeMap.Add (k, type);
185185
} else if (type.IsAbstract || type.IsInterface || e.IsAbstract || e.IsInterface) {
@@ -190,7 +190,7 @@ Dictionary<string, string> GetTypeMapping (Func<TypeDefinition, bool> skipType,
190190
b = type;
191191
typeMap [k] = b;
192192
} else {
193-
List<string> a;
193+
List<string>? a;
194194
if (!aliases.TryGetValue (k, out a)) {
195195
aliases.Add (k, a = new List<string> ());
196196
a.Add (value (e, Cache));
@@ -266,7 +266,7 @@ public void WriteManagedToJava (Stream output)
266266

267267
class ArrayComparer<T> : IComparer<T[]> {
268268

269-
public int Compare (T[] x, T[] y)
269+
public int Compare (T []? x, T []? y)
270270
{
271271
if (x == null && y == null)
272272
return 0;

src/Java.Interop.Tools.TypeNameMappings/Java.Interop.Tools.TypeNameMappings/JavaNativeTypeManager.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,10 @@ public static string ToJniName (Type type)
167167
"java/lang/Object";
168168
}
169169

170+
static readonly Lazy<Type> IJavaPeerableType = new Lazy<Type> (() =>
171+
Type.GetType ("Java.Interop.IJavaPeerable, Java.Interop", throwOnError: true)!
172+
);
173+
170174
static string? ToJniName (Type type, ExportParameterKind exportKind)
171175
{
172176
if (type == null)
@@ -178,8 +182,7 @@ public static string ToJniName (Type type)
178182
if (type == typeof (string))
179183
return "java/lang/String";
180184

181-
182-
if (!type.GetInterfaces ().Any (t => t.FullName == "Android.Runtime.IJavaObject"))
185+
if (IJavaPeerableType.Value.IsAssignableFrom (type))
183186
return GetSpecialExportJniType (type.FullName!, exportKind);
184187

185188
return ToJniName (type, t => t.DeclaringType!, t => t.Name, GetPackageName, t => {

0 commit comments

Comments
 (0)