From bb9ac8b5ad9f0a4b23b8d858fd126662818eff8a Mon Sep 17 00:00:00 2001 From: Simon Rozsival Date: Thu, 23 Apr 2026 17:39:19 +0200 Subject: [PATCH 1/4] Replace startup hook with direct TypeMapLoader.Initialize() call Replace the DOTNET_STARTUP_HOOKS mechanism for trimmable typemap initialization with a direct call from JNIEnvInit.Initialize() to TypeMapLoader.Initialize(). This fixes NativeAOT compatibility (startup hooks don't work with NativeAOT) and removes the reflection-based startup hook discovery overhead. Changes: - Add ref assembly project (src/Microsoft.Android.TypeMaps.Ref/) that Mono.Android compiles against. At app build time, the generated impl assembly replaces it. - Call TypeMapLoader.Initialize() directly from JNIEnvInit when TrimmableTypeMap feature is enabled - Make TrimmableTypeMap.Initialize() public (both overloads) - Update generator to emit public TypeMapLoader class (in Microsoft.Android.Runtime namespace) instead of internal StartupHook - Remove _ConfigureTrimmableTypeMapStartupHook target and StartupHookSupport=true from trimmable typemap targets (startup hooks remain for HotReload) Fixes: https://github.com/dotnet/android/issues/11196 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Generator/RootTypeMapAssemblyGenerator.cs | 57 ++++++++++--------- .../Microsoft.Android.TypeMaps.Ref.csproj | 14 +++++ .../TypeMapLoader.cs | 17 ++++++ .../Android.Runtime/JNIEnvInit.cs | 3 + .../TrimmableTypeMap.cs | 12 ++-- src/Mono.Android/Mono.Android.csproj | 6 ++ .../Microsoft.Android.Sdk.HotReload.targets | 2 +- ...soft.Android.Sdk.TypeMap.Trimmable.targets | 25 -------- .../RootTypeMapAssemblyGeneratorTests.cs | 4 +- 9 files changed, 79 insertions(+), 61 deletions(-) create mode 100644 src/Microsoft.Android.TypeMaps.Ref/Microsoft.Android.TypeMaps.Ref.csproj create mode 100644 src/Microsoft.Android.TypeMaps.Ref/TypeMapLoader.cs diff --git a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/RootTypeMapAssemblyGenerator.cs b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/RootTypeMapAssemblyGenerator.cs index e1763c9dd7f..d6b7bae9a22 100644 --- a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/RootTypeMapAssemblyGenerator.cs +++ b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/RootTypeMapAssemblyGenerator.cs @@ -11,7 +11,7 @@ namespace Microsoft.Android.Sdk.TrimmableTypeMap; /// Generates the root _Microsoft.Android.TypeMaps.dll assembly that: /// /// References all per-assembly typemap assemblies via [assembly: TypeMapAssemblyTargetAttribute<__TypeMapAnchor>("name")]. -/// Emits a StartupHook class whose Initialize() method calls +/// Emits a TypeMapLoader class whose Initialize() method calls /// with the appropriate /// type mapping dictionaries. /// @@ -25,26 +25,29 @@ namespace Microsoft.Android.Sdk.TrimmableTypeMap; /// [assembly: TypeMapAssemblyTarget<__TypeMapAnchor>("_Mono.Android.TypeMap")] /// [assembly: TypeMapAssemblyTarget<__TypeMapAnchor>("_MyApp.TypeMap")] /// -/// // Startup hook — called by DOTNET_STARTUP_HOOKS: -/// internal static class StartupHook +/// namespace Microsoft.Android.Runtime /// { -/// internal static void Initialize () +/// // Called directly from JNIEnvInit.Initialize(): +/// public static class TypeMapLoader /// { -/// // Option A: Shared universe -/// TrimmableTypeMap.Initialize( -/// TypeMapping.GetOrCreateExternalTypeMapping<Java.Lang.Object>(), -/// TypeMapping.GetOrCreateProxyTypeMapping<Java.Lang.Object>()); +/// public static void Initialize () +/// { +/// // Option A: Shared universe +/// TrimmableTypeMap.Initialize( +/// TypeMapping.GetOrCreateExternalTypeMapping<Java.Lang.Object>(), +/// TypeMapping.GetOrCreateProxyTypeMapping<Java.Lang.Object>()); /// -/// // Option B: Per-assembly universes (aggregated) -/// var typeMaps = new IReadOnlyDictionary<string, Type>[] { -/// TypeMapping.GetOrCreateExternalTypeMapping<_Mono_Android_TypeMap.__TypeMapAnchor>(), -/// TypeMapping.GetOrCreateExternalTypeMapping<_MyApp_TypeMap.__TypeMapAnchor>(), -/// }; -/// var proxyMaps = new IReadOnlyDictionary<Type, Type>[] { -/// TypeMapping.GetOrCreateProxyTypeMapping<_Mono_Android_TypeMap.__TypeMapAnchor>(), -/// TypeMapping.GetOrCreateProxyTypeMapping<_MyApp_TypeMap.__TypeMapAnchor>(), -/// }; -/// TrimmableTypeMap.Initialize(typeMaps, proxyMaps); +/// // Option B: Per-assembly universes (aggregated) +/// var typeMaps = new IReadOnlyDictionary<string, Type>[] { +/// TypeMapping.GetOrCreateExternalTypeMapping<_Mono_Android_TypeMap.__TypeMapAnchor>(), +/// TypeMapping.GetOrCreateExternalTypeMapping<_MyApp_TypeMap.__TypeMapAnchor>(), +/// }; +/// var proxyMaps = new IReadOnlyDictionary<Type, Type>[] { +/// TypeMapping.GetOrCreateProxyTypeMapping<_Mono_Android_TypeMap.__TypeMapAnchor>(), +/// TypeMapping.GetOrCreateProxyTypeMapping<_MyApp_TypeMap.__TypeMapAnchor>(), +/// }; +/// TrimmableTypeMap.Initialize(typeMaps, proxyMaps); +/// } /// } /// } /// @@ -108,8 +111,8 @@ public void Generate (IReadOnlyList perAssemblyTypeMapNames, bool useSha // Emit [assembly: TypeMapAssemblyTargetAttribute<__TypeMapAnchor>("name")] for each per-assembly typemap EmitAssemblyTargetAttributes (pe, anchorTypeHandle, perAssemblyTypeMapNames); - // Emit [assembly: IgnoresAccessChecksTo("...")] so the startup hook can access - // internal types (SingleUniverseTypeMap, AggregateTypeMap, TrimmableTypeMap in Mono.Android, + // Emit [assembly: IgnoresAccessChecksTo("...")] so TypeMapLoader.Initialize() can access + // internal types (SingleUniverseTypeMap, AggregateTypeMap in Mono.Android, // and __TypeMapAnchor in each per-assembly typemap DLL). var accessTargets = new List { "Mono.Android" }; if (!useSharedTypemapUniverse) { @@ -117,8 +120,8 @@ public void Generate (IReadOnlyList perAssemblyTypeMapNames, bool useSha } pe.EmitIgnoresAccessChecksToAttribute (accessTargets); - // Emit StartupHook class with Initialize() method - EmitStartupHook (pe, anchorTypeHandle, perAssemblyTypeMapNames, useSharedTypemapUniverse); + // Emit TypeMapLoader class with Initialize() method + EmitTypeMapLoader (pe, anchorTypeHandle, perAssemblyTypeMapNames, useSharedTypemapUniverse); pe.WritePE (stream); } @@ -142,7 +145,7 @@ static void EmitAssemblyTargetAttributes (PEAssemblyBuilder pe, EntityHandle anc } } - static void EmitStartupHook (PEAssemblyBuilder pe, EntityHandle anchorTypeHandle, IReadOnlyList perAssemblyTypeMapNames, bool useSharedTypemapUniverse) + static void EmitTypeMapLoader (PEAssemblyBuilder pe, EntityHandle anchorTypeHandle, IReadOnlyList perAssemblyTypeMapNames, bool useSharedTypemapUniverse) { var metadata = pe.Metadata; @@ -167,11 +170,11 @@ static void EmitStartupHook (PEAssemblyBuilder pe, EntityHandle anchorTypeHandle var getProxyMemberRef = AddTypeMappingMethodRef (pe, typeMappingRef, "GetOrCreateProxyTypeMapping", iReadOnlyDictOpenRef, systemTypeRef, keyIsString: false); - // Define the StartupHook type + // Define the TypeMapLoader type (public static class in Microsoft.Android.Runtime namespace) metadata.AddTypeDefinition ( - TypeAttributes.NotPublic | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.Class, - default, - metadata.GetOrAddString ("StartupHook"), + TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.Class, + metadata.GetOrAddString ("Microsoft.Android.Runtime"), + metadata.GetOrAddString ("TypeMapLoader"), metadata.AddTypeReference (pe.SystemRuntimeRef, metadata.GetOrAddString ("System"), metadata.GetOrAddString ("Object")), MetadataTokens.FieldDefinitionHandle (metadata.GetRowCount (TableIndex.Field) + 1), diff --git a/src/Microsoft.Android.TypeMaps.Ref/Microsoft.Android.TypeMaps.Ref.csproj b/src/Microsoft.Android.TypeMaps.Ref/Microsoft.Android.TypeMaps.Ref.csproj new file mode 100644 index 00000000000..18845a48ffd --- /dev/null +++ b/src/Microsoft.Android.TypeMaps.Ref/Microsoft.Android.TypeMaps.Ref.csproj @@ -0,0 +1,14 @@ + + + + + $(DotNetTargetFramework) + _Microsoft.Android.TypeMaps + Microsoft.Android.Runtime + enable + true + + + + diff --git a/src/Microsoft.Android.TypeMaps.Ref/TypeMapLoader.cs b/src/Microsoft.Android.TypeMaps.Ref/TypeMapLoader.cs new file mode 100644 index 00000000000..8060cdbebe8 --- /dev/null +++ b/src/Microsoft.Android.TypeMaps.Ref/TypeMapLoader.cs @@ -0,0 +1,17 @@ +using System; + +namespace Microsoft.Android.Runtime; + +/// +/// Entry point for typemap initialization. The implementation is generated at build time +/// by the trimmable typemap generator, replacing this reference assembly. +/// +public static class TypeMapLoader +{ + /// + /// Initializes the trimmable typemap by constructing the type mapping dictionaries + /// and calling TrimmableTypeMap.Initialize(). + /// + public static void Initialize () => throw new NotImplementedException ( + "This is a reference assembly stub. The real implementation is generated at build time."); +} diff --git a/src/Mono.Android/Android.Runtime/JNIEnvInit.cs b/src/Mono.Android/Android.Runtime/JNIEnvInit.cs index 52677116363..bba43f87c94 100644 --- a/src/Mono.Android/Android.Runtime/JNIEnvInit.cs +++ b/src/Mono.Android/Android.Runtime/JNIEnvInit.cs @@ -179,6 +179,9 @@ internal static unsafe void Initialize (JnienvInitializeArgs* args) if (!RuntimeFeature.TrimmableTypeMap) { args->registerJniNativesFn = (IntPtr)(delegate* unmanaged)&RegisterJniNatives; } + if (RuntimeFeature.TrimmableTypeMap) { + TypeMapLoader.Initialize (); + } RunStartupHooksIfNeeded (); SetSynchronizationContext (); } diff --git a/src/Mono.Android/Microsoft.Android.Runtime/TrimmableTypeMap.cs b/src/Mono.Android/Microsoft.Android.Runtime/TrimmableTypeMap.cs index 2272fc1d9dc..5b68ce6c50e 100644 --- a/src/Mono.Android/Microsoft.Android.Runtime/TrimmableTypeMap.cs +++ b/src/Mono.Android/Microsoft.Android.Runtime/TrimmableTypeMap.cs @@ -38,10 +38,10 @@ class TrimmableTypeMap /// /// Initializes the singleton with a single merged typemap universe. - /// Called from the startup hook in the generated root assembly (_Microsoft.Android.TypeMaps) - /// when assembly typemaps are merged (Release builds). + /// Called from in the generated root assembly + /// (_Microsoft.Android.TypeMaps) when assembly typemaps are merged (Release builds). /// - internal static void Initialize (IReadOnlyDictionary typeMap, IReadOnlyDictionary proxyMap) + public static void Initialize (IReadOnlyDictionary typeMap, IReadOnlyDictionary proxyMap) { ArgumentNullException.ThrowIfNull (typeMap); ArgumentNullException.ThrowIfNull (proxyMap); @@ -50,10 +50,10 @@ internal static void Initialize (IReadOnlyDictionary typeMap, IRea /// /// Initializes the singleton with multiple per-assembly typemap universes. - /// Called from the startup hook in the generated root assembly (_Microsoft.Android.TypeMaps) - /// when each assembly has its own typemap universe (Debug builds). + /// Called from in the generated root assembly + /// (_Microsoft.Android.TypeMaps) when each assembly has its own typemap universe (Debug builds). /// - internal static void Initialize (IReadOnlyDictionary[] typeMaps, IReadOnlyDictionary[] proxyMaps) + public static void Initialize (IReadOnlyDictionary[] typeMaps, IReadOnlyDictionary[] proxyMaps) { ArgumentNullException.ThrowIfNull (typeMaps); ArgumentNullException.ThrowIfNull (proxyMaps); diff --git a/src/Mono.Android/Mono.Android.csproj b/src/Mono.Android/Mono.Android.csproj index 55352540d70..89bf52ac3b1 100644 --- a/src/Mono.Android/Mono.Android.csproj +++ b/src/Mono.Android/Mono.Android.csproj @@ -61,6 +61,12 @@ + + + false + all + ILLink.LinkAttributes.xml diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.HotReload.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.HotReload.targets index 4156e0db1b5..7654d9bf248 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.HotReload.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.HotReload.targets @@ -43,7 +43,7 @@ See: https://github.com/dotnet/sdk/pull/52581 diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.Trimmable.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.Trimmable.targets index 40a2c1519c3..52ce49be5cf 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.Trimmable.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.Trimmable.targets @@ -11,9 +11,6 @@ <_TypeMapAssemblyName>_Microsoft.Android.TypeMaps - - true @@ -34,28 +31,6 @@ Condition=" '$(_AndroidRuntime)' == 'CoreCLR' " /> - - - - <_ExistingStartupHooks Include="@(RuntimeEnvironmentVariable)" Condition=" '%(Identity)' == 'DOTNET_STARTUP_HOOKS' " /> - - - - <_ExistingStartupHooks Remove="@(_ExistingStartupHooks)" /> - - - diff --git a/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Generator/RootTypeMapAssemblyGeneratorTests.cs b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Generator/RootTypeMapAssemblyGeneratorTests.cs index 0acd64e1812..a61e42c63c0 100644 --- a/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Generator/RootTypeMapAssemblyGeneratorTests.cs +++ b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Generator/RootTypeMapAssemblyGeneratorTests.cs @@ -139,11 +139,11 @@ public void Generate_BothMergeModes_ProduceValidPEAssembly (bool useSharedTypema var reader = pe.GetMetadataReader (); - // Both modes should have StartupHook type with Initialize method + // Both modes should have TypeMapLoader type with Initialize method var typeDefs = reader.TypeDefinitions .Select (h => reader.GetTypeDefinition (h)) .ToList (); - Assert.Contains (typeDefs, t => reader.GetString (t.Name) == "StartupHook"); + Assert.Contains (typeDefs, t => reader.GetString (t.Name) == "TypeMapLoader"); // Both modes should have assembly target attributes var targetAttrs = GetTypeMapAssemblyTargetAttributes (reader); From 3bbf00459032d04e8310be16e6c9f6ae8bc85616 Mon Sep 17 00:00:00 2001 From: Simon Rozsival Date: Thu, 23 Apr 2026 22:18:09 +0200 Subject: [PATCH 2/4] Address PR review comments - Add namespace and visibility assertions to TypeMapLoader test - Fix IgnoresAccessChecksTo comment to include TrimmableTypeMap (class is still internal) - Clarify ProduceOnlyReferenceAssembly intent in ref assembly csproj Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Generator/RootTypeMapAssemblyGenerator.cs | 2 +- .../Microsoft.Android.TypeMaps.Ref.csproj | 2 ++ .../Generator/RootTypeMapAssemblyGeneratorTests.cs | 6 ++++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/RootTypeMapAssemblyGenerator.cs b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/RootTypeMapAssemblyGenerator.cs index d6b7bae9a22..88707e3cce8 100644 --- a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/RootTypeMapAssemblyGenerator.cs +++ b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/RootTypeMapAssemblyGenerator.cs @@ -112,7 +112,7 @@ public void Generate (IReadOnlyList perAssemblyTypeMapNames, bool useSha EmitAssemblyTargetAttributes (pe, anchorTypeHandle, perAssemblyTypeMapNames); // Emit [assembly: IgnoresAccessChecksTo("...")] so TypeMapLoader.Initialize() can access - // internal types (SingleUniverseTypeMap, AggregateTypeMap in Mono.Android, + // internal types (TrimmableTypeMap, SingleUniverseTypeMap, AggregateTypeMap in Mono.Android, // and __TypeMapAnchor in each per-assembly typemap DLL). var accessTargets = new List { "Mono.Android" }; if (!useSharedTypemapUniverse) { diff --git a/src/Microsoft.Android.TypeMaps.Ref/Microsoft.Android.TypeMaps.Ref.csproj b/src/Microsoft.Android.TypeMaps.Ref/Microsoft.Android.TypeMaps.Ref.csproj index 18845a48ffd..a9830cdb95a 100644 --- a/src/Microsoft.Android.TypeMaps.Ref/Microsoft.Android.TypeMaps.Ref.csproj +++ b/src/Microsoft.Android.TypeMaps.Ref/Microsoft.Android.TypeMaps.Ref.csproj @@ -6,6 +6,8 @@ _Microsoft.Android.TypeMaps Microsoft.Android.Runtime enable + true diff --git a/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Generator/RootTypeMapAssemblyGeneratorTests.cs b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Generator/RootTypeMapAssemblyGeneratorTests.cs index a61e42c63c0..84dd6a0a2f4 100644 --- a/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Generator/RootTypeMapAssemblyGeneratorTests.cs +++ b/tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Generator/RootTypeMapAssemblyGeneratorTests.cs @@ -139,11 +139,13 @@ public void Generate_BothMergeModes_ProduceValidPEAssembly (bool useSharedTypema var reader = pe.GetMetadataReader (); - // Both modes should have TypeMapLoader type with Initialize method + // Both modes should have TypeMapLoader type in the correct namespace, with public visibility and Initialize method var typeDefs = reader.TypeDefinitions .Select (h => reader.GetTypeDefinition (h)) .ToList (); - Assert.Contains (typeDefs, t => reader.GetString (t.Name) == "TypeMapLoader"); + var typeMapLoader = typeDefs.Single (t => reader.GetString (t.Name) == "TypeMapLoader"); + Assert.Equal ("Microsoft.Android.Runtime", reader.GetString (typeMapLoader.Namespace)); + Assert.True (typeMapLoader.Attributes.HasFlag (System.Reflection.TypeAttributes.Public)); // Both modes should have assembly target attributes var targetAttrs = GetTypeMapAssemblyTargetAttributes (reader); From dcf4ef9d8e6232fd1a6e81f14a885d39ed1cad2d Mon Sep 17 00:00:00 2001 From: Simon Rozsival Date: Thu, 23 Apr 2026 22:27:53 +0200 Subject: [PATCH 3/4] Extract TypeMapLoader.Initialize() into separate NoInlining method Prevents the JIT from trying to resolve TypeMapLoader (from _Microsoft.Android.TypeMaps.dll) when compiling JNIEnvInit.Initialize() in non-trimmable builds where that assembly isn't present. This is the standard .NET pattern for conditional dependencies on assemblies that may not be available at runtime. Per docs: "runtimes will refuse to load reference assemblies for execution" so shipping the ref assembly as a fallback wouldn't work either. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Mono.Android/Android.Runtime/JNIEnvInit.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Mono.Android/Android.Runtime/JNIEnvInit.cs b/src/Mono.Android/Android.Runtime/JNIEnvInit.cs index bba43f87c94..f59a8568f66 100644 --- a/src/Mono.Android/Android.Runtime/JNIEnvInit.cs +++ b/src/Mono.Android/Android.Runtime/JNIEnvInit.cs @@ -180,7 +180,7 @@ internal static unsafe void Initialize (JnienvInitializeArgs* args) args->registerJniNativesFn = (IntPtr)(delegate* unmanaged)&RegisterJniNatives; } if (RuntimeFeature.TrimmableTypeMap) { - TypeMapLoader.Initialize (); + InitializeTrimmableTypeMap (); } RunStartupHooksIfNeeded (); SetSynchronizationContext (); @@ -190,6 +190,14 @@ internal static unsafe void Initialize (JnienvInitializeArgs* args) [UnmanagedCallConv (CallConvs = new[] { typeof (CallConvCdecl) })] private static unsafe partial void xamarin_app_init (IntPtr env, delegate* unmanaged get_function_pointer); + // Separate method so the JIT doesn't try to resolve TypeMapLoader (from _Microsoft.Android.TypeMaps.dll) + // when compiling JNIEnvInit.Initialize() in non-trimmable builds where that assembly isn't present. + [MethodImpl (MethodImplOptions.NoInlining)] + static void InitializeTrimmableTypeMap () + { + TypeMapLoader.Initialize (); + } + static void RunStartupHooksIfNeeded () { // Return if startup hooks are disabled or not CoreCLR From ce02913befbbf83022fb9e53f1e51ec1080f134b Mon Sep 17 00:00:00 2001 From: Simon Rozsival Date: Fri, 24 Apr 2026 07:43:20 +0200 Subject: [PATCH 4/4] Make TrimmableTypeMap class public The generated TypeMapLoader.Initialize() calls TrimmableTypeMap.Initialize() which is now public. Making the class public means IgnoresAccessChecksTo is no longer needed for this specific type (still needed for SingleUniverseTypeMap, AggregateTypeMap, and __TypeMapAnchor). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Generator/RootTypeMapAssemblyGenerator.cs | 2 +- src/Mono.Android/Microsoft.Android.Runtime/TrimmableTypeMap.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/RootTypeMapAssemblyGenerator.cs b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/RootTypeMapAssemblyGenerator.cs index 88707e3cce8..d6b7bae9a22 100644 --- a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/RootTypeMapAssemblyGenerator.cs +++ b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/RootTypeMapAssemblyGenerator.cs @@ -112,7 +112,7 @@ public void Generate (IReadOnlyList perAssemblyTypeMapNames, bool useSha EmitAssemblyTargetAttributes (pe, anchorTypeHandle, perAssemblyTypeMapNames); // Emit [assembly: IgnoresAccessChecksTo("...")] so TypeMapLoader.Initialize() can access - // internal types (TrimmableTypeMap, SingleUniverseTypeMap, AggregateTypeMap in Mono.Android, + // internal types (SingleUniverseTypeMap, AggregateTypeMap in Mono.Android, // and __TypeMapAnchor in each per-assembly typemap DLL). var accessTargets = new List { "Mono.Android" }; if (!useSharedTypemapUniverse) { diff --git a/src/Mono.Android/Microsoft.Android.Runtime/TrimmableTypeMap.cs b/src/Mono.Android/Microsoft.Android.Runtime/TrimmableTypeMap.cs index 5b68ce6c50e..7b94c8f2184 100644 --- a/src/Mono.Android/Microsoft.Android.Runtime/TrimmableTypeMap.cs +++ b/src/Mono.Android/Microsoft.Android.Runtime/TrimmableTypeMap.cs @@ -17,7 +17,7 @@ namespace Microsoft.Android.Runtime; /// and provides peer creation, invoker resolution, container factories, and native /// method registration. All proxy attribute access is encapsulated here. /// -class TrimmableTypeMap +public class TrimmableTypeMap { static readonly Lock s_initLock = new (); static readonly JavaPeerProxy s_noPeerSentinel = new MissingJavaPeerProxy ();