diff --git a/src/Mono.Android/Microsoft.Android.Runtime/TrimmableTypeMapTypeManager.cs b/src/Mono.Android/Microsoft.Android.Runtime/TrimmableTypeMapTypeManager.cs index 220be6aae78..ad6c1d116d7 100644 --- a/src/Mono.Android/Microsoft.Android.Runtime/TrimmableTypeMapTypeManager.cs +++ b/src/Mono.Android/Microsoft.Android.Runtime/TrimmableTypeMapTypeManager.cs @@ -60,6 +60,18 @@ protected override IEnumerable GetSimpleReferences (Type type) return base.GetInvokerTypeCore (type); } + protected override IReadOnlyList? GetStaticMethodFallbackTypesCore (string jniSimpleReference) + { + int slash = jniSimpleReference.LastIndexOf ('/'); + var desugarType = slash > 0 + ? $"{jniSimpleReference.Substring (0, slash + 1)}Desugar{jniSimpleReference.Substring (slash + 1)}" + : $"Desugar{jniSimpleReference}"; + return new[] { + $"{desugarType}$_CC", + $"{jniSimpleReference}$-CC", + }; + } + public override void RegisterNativeMembers ( JniType nativeClass, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] diff --git a/tests/Mono.Android-Tests/Mono.Android-Tests/Java.Interop/TrimmableTypeMapTypeManagerTests.cs b/tests/Mono.Android-Tests/Mono.Android-Tests/Java.Interop/TrimmableTypeMapTypeManagerTests.cs new file mode 100644 index 00000000000..e5e7f9e134c --- /dev/null +++ b/tests/Mono.Android-Tests/Mono.Android-Tests/Java.Interop/TrimmableTypeMapTypeManagerTests.cs @@ -0,0 +1,50 @@ +using Java.Interop; +using Microsoft.Android.Runtime; +using NUnit.Framework; + +namespace Java.InteropTests +{ + [TestFixture] + public class TrimmableTypeMapTypeManagerTests + { + // Test subclass that allows instantiation without full TrimmableTypeMap initialization. + // GetStaticMethodFallbackTypesCore does not use TrimmableTypeMap.Instance, so the test + // can run without an initialized TrimmableTypeMap singleton. + sealed class TestableTrimmableTypeMapTypeManager : TrimmableTypeMapTypeManager + { + } + + [Test] + public void GetStaticMethodFallbackTypes_WithPackageName_ReturnsDesugarFallbacks () + { + using var manager = new TestableTrimmableTypeMapTypeManager (); + var fallbacks = manager.GetStaticMethodFallbackTypes ("android/app/Activity"); + Assert.IsNotNull (fallbacks); + Assert.AreEqual (2, fallbacks!.Count); + Assert.AreEqual ("android/app/DesugarActivity$_CC", fallbacks [0]); + Assert.AreEqual ("android/app/Activity$-CC", fallbacks [1]); + } + + [Test] + public void GetStaticMethodFallbackTypes_WithoutPackageName_ReturnsDesugarFallbacks () + { + using var manager = new TestableTrimmableTypeMapTypeManager (); + var fallbacks = manager.GetStaticMethodFallbackTypes ("Activity"); + Assert.IsNotNull (fallbacks); + Assert.AreEqual (2, fallbacks!.Count); + Assert.AreEqual ("DesugarActivity$_CC", fallbacks [0]); + Assert.AreEqual ("Activity$-CC", fallbacks [1]); + } + + [Test] + public void GetStaticMethodFallbackTypes_WithDeepPackageName_ReturnsDesugarFallbacks () + { + using var manager = new TestableTrimmableTypeMapTypeManager (); + var fallbacks = manager.GetStaticMethodFallbackTypes ("com/example/package/MyInterface"); + Assert.IsNotNull (fallbacks); + Assert.AreEqual (2, fallbacks!.Count); + Assert.AreEqual ("com/example/package/DesugarMyInterface$_CC", fallbacks [0]); + Assert.AreEqual ("com/example/package/MyInterface$-CC", fallbacks [1]); + } + } +} diff --git a/tests/Mono.Android-Tests/Mono.Android-Tests/Mono.Android.NET-Tests.csproj b/tests/Mono.Android-Tests/Mono.Android-Tests/Mono.Android.NET-Tests.csproj index ae33bef1571..33bb45ed65c 100644 --- a/tests/Mono.Android-Tests/Mono.Android-Tests/Mono.Android.NET-Tests.csproj +++ b/tests/Mono.Android-Tests/Mono.Android-Tests/Mono.Android.NET-Tests.csproj @@ -98,6 +98,7 @@ +