Part of #10958.
The binding generator still emits a Java.Interop.__TypeRegistrations class into every binding assembly (including Mono.Android.dll itself), but the runtime code that consumed it was removed in #9471 (commit 6ac69bee2, 2024-11-08). The generated class is now pure dead code — it is never invoked and the dictionary it populates is never read. We should stop generating it.
Background: how it used to work
__TypeRegistrations.RegisterPackages() called Java.Interop.TypeManager.RegisterPackages(string[] packages, Converter<string, Type?>[] lookups), which populated a packageLookup dictionary. The Java→managed type resolver (GetJavaToManagedTypeCore) had a TypeRegistrationFallback(class_name) path that lazily invoked __TypeRegistrations.RegisterPackages() and then read packageLookup to resolve a managed Type by package + class name.
This fallback was:
Today, GetJavaToManagedTypeCore resolves types exclusively via the native typemap (monovm_typemap_java_to_managed / clr_typemap_java_to_managed) or, on the trimmable path, TrimmableTypeMapTypeManager. The [TrimmableTypeMap] work makes this generated class even more clearly obsolete.
Evidence it is dead code (verified on main)
- No caller of the no-arg
__TypeRegistrations.RegisterPackages () exists anywhere in source. The generated class has no [ModuleInitializer]/static-ctor hook, so it is never auto-invoked.
Java.Interop.TypeManager.packageLookup is write-only: RegisterPackage / RegisterPackages populate it (src/Mono.Android/Java.Interop/TypeManager.cs:465-497); nothing reads it.
- The
Lookup(...) helper and per-package lookup_<pkg>_package converters in the generated file are unreferenced.
- Mono.Android's own emitted copy is 2448 lines / 174 converters (
src/Mono.Android/obj/.../mcw/Java.Interop.__TypeRegistrations.cs) of dead code; every binding assembly carries a similar file.
Current locations
- Generator (primary target):
external/Java.Interop/tools/generator/Java.Interop.Tools.Generator.ObjectModel/ClassGen.cs
GenerateTypeRegistrations(opt, gen_info) (line ~172) writes the partial class __TypeRegistrations with RegisterPackages(), Lookup(...), and the per-package converters. It already early-returns for CodeGenerationTarget.JavaInterop1.
- Generator call site:
external/Java.Interop/tools/generator/CodeGenerator.cs:251 (ClassGen.GenerateTypeRegistrations(opt, gen_info);).
- Runtime plumbing now unused:
src/Mono.Android/Java.Interop/TypeManager.cs
packageLookup field + LazyInitPackageLookup() (lines ~456-463)
RegisterPackage(string, Converter<string, Type>) (line ~465)
RegisterPackages(string[], Converter<string, Type?>[]) (line ~476)
LookupTypeMapping(string[], string) (line ~90) — only used by the generated Lookup.
- Public shim:
src/Mono.Android/Android.Runtime/TypeManager.cs (the [Obsolete] wrappers forwarding to the above).
- Generator test baselines:
external/Java.Interop/tests/generator-Tests/expected.xaji/*/Java.Interop.__TypeRegistrations.cs (one per fixture) plus the generator-Tests support TypeManager.cs.
Suggested implementation
- Stop generating
__TypeRegistrations for the XAJavaInterop1 target as well (the method already no-ops for JavaInterop1). Simplest: make GenerateTypeRegistrations return early for all targets, or remove the method and its call in CodeGenerator.cs.
- Update / delete the
expected.xaji generator-test baselines accordingly so generator-Tests stay green.
- Remove the now-unused runtime plumbing in
Java.Interop/TypeManager.cs (packageLookup, LazyInitPackageLookup, RegisterPackage, the internal RegisterPackages body, and LookupTypeMapping if it has no remaining callers).
Public API consideration
Java.Interop.TypeManager.RegisterPackages(string[], Converter<string, Type?>[]), RegisterPackage(...), LookupTypeMapping(...) and the [Obsolete] Android.Runtime.TypeManager shims are shipped public API (present in src/Mono.Android/PublicAPI/*/PublicAPI.Shipped.txt). Removing the generation is safe and self-contained; removing the public members must go through the normal API-removal process (or they can be kept as no-op stubs). This issue can be split into two PRs: (a) stop generating __TypeRegistrations, (b) retire the public API.
Acceptance criteria
- The binding generator no longer emits
Java.Interop.__TypeRegistrations for any codegen target.
- generator-Tests baselines updated; generator-Tests pass.
Mono.Android.dll and customer binding assemblies no longer contain the dead class (verify the file disappears from obj/.../mcw/ and from a built binding).
- No behavioral change: Java→managed type resolution continues to go through the native typemap /
TrimmableTypeMapTypeManager.
- Existing Mono.Android and device tests pass.
References
Part of #10958.
The binding generator still emits a
Java.Interop.__TypeRegistrationsclass into every binding assembly (includingMono.Android.dllitself), but the runtime code that consumed it was removed in #9471 (commit6ac69bee2, 2024-11-08). The generated class is now pure dead code — it is never invoked and the dictionary it populates is never read. We should stop generating it.Background: how it used to work
__TypeRegistrations.RegisterPackages()calledJava.Interop.TypeManager.RegisterPackages(string[] packages, Converter<string, Type?>[] lookups), which populated apackageLookupdictionary. The Java→managed type resolver (GetJavaToManagedTypeCore) had aTypeRegistrationFallback(class_name)path that lazily invoked__TypeRegistrations.RegisterPackages()and then readpackageLookupto resolve a managedTypeby package + class name.This fallback was:
AppContextswitch in [illink] Type registrations fallback switch #5629 (commit5b3d8cdd1, "[illink] Type registrations fallback switch"), with a linker substitution stubbingRegisterPackagesout for linked apps,Xamarin.Android.VSAndroidDesigner.IsSupportedfeature switch #9471 (commit6ac69bee2) — that diff deletesTypeRegistrationFallback, the__TypeRegistrations.RegisterPackages ()call, and thepackageLookup.TryGetValue(...)read.Today,
GetJavaToManagedTypeCoreresolves types exclusively via the native typemap (monovm_typemap_java_to_managed/clr_typemap_java_to_managed) or, on the trimmable path,TrimmableTypeMapTypeManager. The[TrimmableTypeMap]work makes this generated class even more clearly obsolete.Evidence it is dead code (verified on
main)__TypeRegistrations.RegisterPackages ()exists anywhere in source. The generated class has no[ModuleInitializer]/static-ctor hook, so it is never auto-invoked.Java.Interop.TypeManager.packageLookupis write-only:RegisterPackage/RegisterPackagespopulate it (src/Mono.Android/Java.Interop/TypeManager.cs:465-497); nothing reads it.Lookup(...)helper and per-packagelookup_<pkg>_packageconverters in the generated file are unreferenced.src/Mono.Android/obj/.../mcw/Java.Interop.__TypeRegistrations.cs) of dead code; every binding assembly carries a similar file.Current locations
external/Java.Interop/tools/generator/Java.Interop.Tools.Generator.ObjectModel/ClassGen.csGenerateTypeRegistrations(opt, gen_info)(line ~172) writes thepartial class __TypeRegistrationswithRegisterPackages(),Lookup(...), and the per-package converters. It already early-returns forCodeGenerationTarget.JavaInterop1.external/Java.Interop/tools/generator/CodeGenerator.cs:251(ClassGen.GenerateTypeRegistrations(opt, gen_info);).src/Mono.Android/Java.Interop/TypeManager.cspackageLookupfield +LazyInitPackageLookup()(lines ~456-463)RegisterPackage(string, Converter<string, Type>)(line ~465)RegisterPackages(string[], Converter<string, Type?>[])(line ~476)LookupTypeMapping(string[], string)(line ~90) — only used by the generatedLookup.src/Mono.Android/Android.Runtime/TypeManager.cs(the[Obsolete]wrappers forwarding to the above).external/Java.Interop/tests/generator-Tests/expected.xaji/*/Java.Interop.__TypeRegistrations.cs(one per fixture) plus the generator-Tests supportTypeManager.cs.Suggested implementation
__TypeRegistrationsfor theXAJavaInterop1target as well (the method already no-ops forJavaInterop1). Simplest: makeGenerateTypeRegistrationsreturn early for all targets, or remove the method and its call inCodeGenerator.cs.expected.xajigenerator-test baselines accordingly so generator-Tests stay green.Java.Interop/TypeManager.cs(packageLookup,LazyInitPackageLookup,RegisterPackage, the internalRegisterPackagesbody, andLookupTypeMappingif it has no remaining callers).Public API consideration
Java.Interop.TypeManager.RegisterPackages(string[], Converter<string, Type?>[]),RegisterPackage(...),LookupTypeMapping(...)and the[Obsolete]Android.Runtime.TypeManagershims are shipped public API (present insrc/Mono.Android/PublicAPI/*/PublicAPI.Shipped.txt). Removing the generation is safe and self-contained; removing the public members must go through the normal API-removal process (or they can be kept as no-op stubs). This issue can be split into two PRs: (a) stop generating__TypeRegistrations, (b) retire the public API.Acceptance criteria
Java.Interop.__TypeRegistrationsfor any codegen target.Mono.Android.dlland customer binding assemblies no longer contain the dead class (verify the file disappears fromobj/.../mcw/and from a built binding).TrimmableTypeMapTypeManager.References
Xamarin.Android.VSAndroidDesigner.IsSupportedfeature switch #9471 — removed the runtime fallback that was the sole consumer (commit6ac69bee2)5b3d8cdd1)