Repository navigation
[Xamarin.Android.Build.Tasks] Retain only typemap class mappings - #13022
Closed
simonrozsival wants to merge 1 commit into
Closed
simonrozsival wants to merge 1 commit into
simonrozsival wants to merge 1 commit into
Conversation
A surviving Java TypeMap attribute establishes class identity, not that every R8-mapped member still has a managed consumer. Recording all members restores remapping entries for methods and fields absent from final linked metadata. Record only the class mapping and leave member retention to surviving JNI metadata. Remove the unused all-member helper. Cover class-only and mixed fixtures, both attribute forms, forward/reverse XML, field descriptor variants, and byte-for-byte input assembly immutability. Context: #12848 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
Runtime remapping behavior lacks validation through the standard repository build, CI, and integration test paths.
Review effort: Balanced
Findings: 1
Open (1)
What changed in this PR
Restricts TypeMap-based R8 retention to class mappings while preserving member mappings only when surviving JNI metadata references them.
Changes:
- Replaces all-member retention with class-only retention.
- Adds regression coverage for TypeMap forms and surviving members.
- Documents class-versus-member retention semantics.
| File | Description |
|---|---|
JniRemappingAssemblyScanner.cs |
Records only TypeMap class access. |
JniRemappingAssemblyScannerTests.cs |
Expands retention and immutability tests. |
JavaJNI_Interop.md |
Documents retention behavior. |
| { | ||
| /// <summary> | ||
| /// Reads linked managed metadata to identify JNI mappings that still have managed consumers. | ||
| /// TypeMap attributes retain class identity, not members lacking surviving JNI metadata. |
Member
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Context: #12848
Related pending consumer: #12692.
Xamarin.Android.Tasks.JniRemapping.JniRemappingAssemblyScanner.ScanTypeMapAttributes()callsRecordAllMappings()for every surviving Java TypeMap key. That helper records every R8-mapped method and field, even when those members have disappeared from final managed metadata. A class-only TypeMap therefore bypasses the scanner's surviving-consumer filter and restores unused member replacements.Record only class identity with
R8Mapping.TryGetRenamedClass()and remove the now-unused all-member helper. Forward/reverse type mappings remain available; legitimate method and field retention continues through surviving JNI metadata. Framework attribute/group/assembly identity checks, alias normalization, malformed-input diagnostics, field descriptor semantics, input assembly immutability, public signatures, and the separate NativeAOT retention path are unchanged.Correct the existing TypeMap retention expectation rather than deleting it. Extend class-only generation fixtures with renamed methods/fields and real local proxy/target types without Register metadata, covering both two- and three-argument TypeMap forms and framework implementation identities. Mixed fixtures retain the registered method and both field descriptor variants, but not unused members or an unused overload. Assertions inspect actual accessed entries and generated XML, and compare input assembly bytes. Document the class/member distinction.
This is a new standalone fix based exactly on
8de547b9a2962a0383c57a418777c8add7bdaf1c. It does not change any existing PR or stack metadata.Validation
The worktree has no local Android SDK. The following repository host-test command failed before test execution with
You need to run 'make prepare' first.:Used an authorized scratch source harness in the session artifact directory instead. It compiles the actual current-worktree scanner, R8 mapping/parser, descriptor helpers, GenerateR8JniRemapping, NativeAOT retention/readers, MergeRemapXml, metadata helpers, resources, and original focused NUnit test files—not stale product DLLs. Only SDK-wide encoding/logging and test-environment infrastructure are adapted. It runs on the installed .NET 11 RC runtime; the actual source compatibility build targets the product's
netstandard2.0.linked.runsettingsenables the existing real ILLink identity test using cached ILLink11.0.0-rc.2.26475.136and its matching installed framework.Commands below were executed from the session-area
typemap-retention-harnessdirectory:Before the production fix: 19 expected retention failures, 143 passed, 0 skipped, 162 total. Production scanner source was verified unchanged against the exact main baseline. Class-only fixtures emitted unwanted
replace-method/replace-field; mixed fixtures recorded unused members and an unused overload.After the fix: 162 passed, 0 failed, 0 skipped: 31 scanner, 74 generator/retention/malformed-XML, 41 mapping, and 16 descriptor cases. The real ILLink identity case passed. Test compilation reports two unchanged nullable warnings in baseline R8Mapping/MergeRemapXml sources.
Results: source compatibility build passed with 0 warnings and 0 errors; diff check passed. Full Android SDK builds, app-level R2R/device tests, and pipelines were not run; no broad bootstrap was performed per the requested scope. Before/after TRX results, logs, runsettings, and harness sources remain in session artifacts.