Skip to content

[typemap] Match legacy JCW interface declarations - #12585

Open
simonrozsival wants to merge 2 commits into
mainfrom
simonrozsival-jcw-interface-parity
Open

[typemap] Match legacy JCW interface declarations#12585
simonrozsival wants to merge 2 commits into
mainfrom
simonrozsival-jcw-interface-parity

Conversation

@simonrozsival

@simonrozsival simonrozsival commented Aug 29, 2026

Copy link
Copy Markdown
Member

Summary

  • preserve the scanner's complete ordered direct-interface list for typemap and alias semantics
  • add an internal JCW declaration list that filters redundant parent interfaces and deduplicates Java names in first-seen order, matching legacy CecilImporter
  • add focused scanner and Java source tests for parent/derived redundancy, colliding managed aliases, stable order, and an unrelated-interface control

Regression coverage

Before the fix, the trimmable generator emitted the parent interface, derived interface, and a second managed alias for the same derived Java interface. The duplicate Java name produced an invalid implements declaration.

The focused fixture declares all four inputs directly. Scanner coverage verifies the complete ordered metadata list remains available for typemap semantics, while generator coverage verifies the JCW emits only the derived and unrelated interfaces in stable order.

Validation

  • Microsoft.Android.Sdk.TrimmableTypeMap.Tests
  • focused scanner and JCW source regression tests
  • git diff --check

Tracks #12561.

Copilot AI lite review requested due to automatic review settings August 29, 2026 03:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

Review tier: Lite
Findings: 1 Medium severity

New issues introduced by this change (1)
Severity Finding
Medium severity src/​Microsoft.Android.Sdk.TrimmableTypeMap/​Scanner/​JavaPeerScanner.cs⚠️ Performance — This interfaces.Any(...) inside the per-interface loop creates an O(n²) scan and…
What changed in this PR

This PR updates the trimmable typemap Java peer scanning/generation pipeline so generated Java callable wrappers emit an interface implements list that matches legacy CecilImporter semantics (stable order, no redundant parent interfaces, no duplicate Java names), while still preserving the full ordered direct-interface list from managed metadata for other semantics.

Changes:

  • Add JavaCallableWrapperInterfaceJavaNames on JavaPeerInfo and compute it in the scanner by filtering redundant parent interfaces and deduplicating Java names in first-seen order.
  • Update JCW Java source generation and Java-name validation to use the filtered interface list when available.
  • Extend the shared semantic parity fixture + integration/build tests to cover parent/derived redundancy, colliding managed aliases, stable ordering, and compilation via javac.
File Description
tests/​Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/​JavaSourceSemanticParityTests.cs Extends semantic parity coverage for redundant/colliding interfaces and adds Java stub types required for javac compilation.
tests/​Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/​JavaSourceParityFixture/​JavaSourceParityTypes.cs Expands the managed fixture with interface hierarchy + alias collision scenarios used by both legacy and trimmable pipelines.
src/​Xamarin.Android.Build.Tasks/​Tests/​Xamarin.Android.Build.Tests/​TrimmableTypeMapBuildTests.cs Extends build validation to ensure the semantic parity fixture compiles across llvm-ir/trimmable and CoreCLR/NativeAOT configurations.
src/​Microsoft.Android.Sdk.TrimmableTypeMap/​TrimmableTypeMapGenerator.cs Validates interface names against the JCW-emitted interface list (when available) to match generated Java behavior.
src/​Microsoft.Android.Sdk.TrimmableTypeMap/​Scanner/​JavaPeerScanner.cs Computes both the full direct-interface list and the filtered JCW declaration list (dedupe + most-derived filtering).
src/​Microsoft.Android.Sdk.TrimmableTypeMap/​Scanner/​JavaPeerInfo.cs Adds an internal property to carry the JCW-specific interface declaration list alongside the full direct-interface list.
src/​Microsoft.Android.Sdk.TrimmableTypeMap/​Generator/​JcwJavaSourceGenerator.cs Emits the JCW implements clause from the filtered interface list to avoid redundant/duplicate declarations.

Comment thread src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/JavaPeerScanner.cs Outdated
@jonathanpeppers
jonathanpeppers force-pushed the simonrozsival-jcw-semantic-parity branch from caa6506 to 252fd7d Compare August 31, 2026 13:47
@simonrozsival
simonrozsival force-pushed the simonrozsival-jcw-interface-parity branch from b477490 to 41401a8 Compare September 1, 2026 12:37
@simonrozsival
simonrozsival changed the base branch from simonrozsival-jcw-semantic-parity to main September 1, 2026 12:44
@simonrozsival
simonrozsival force-pushed the simonrozsival-jcw-interface-parity branch from 41401a8 to f7caab7 Compare September 1, 2026 12:45
Filter redundant parent interfaces and duplicate Java names from generated callable-wrapper declarations while retaining the complete ordered interface list for scanner and typemap semantics. Add focused scanner and Java source regression coverage for parent, alias, and ordering behavior.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@simonrozsival
simonrozsival force-pushed the simonrozsival-jcw-interface-parity branch from f7caab7 to 8d1c574 Compare September 1, 2026 13:06
@simonrozsival

Copy link
Copy Markdown
Member Author

/review

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Android PR Reviewer completed successfully!

Generated by Android PR Reviewer for #12585

Replace the captured LINQ predicate with explicit iteration and reuse the interface-assignability visited set across comparisons.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM on code (CI pending)

Findings: 0 errors · 0 warnings · 1 suggestion

The split between the complete direct-interface list and the filtered JCW declaration list preserves typemap/alias semantics while matching Java interface inheritance and erasure. The first-seen ordering, duplicate JNI-name handling, parent elimination, generator fallback, and source-name validation are coherent and covered by focused same-assembly regression tests.

Azure DevOps build 1576771 is still running: CLA has passed, with the currently published dotnet-android lanes in progress or queued and no failures reported yet.

Generated by Android PR Reviewer for #12585 · gpt56 · 190.5 AIC · ⌖ 8.92 AIC · ⊞ 25.7K
Comment /review to run again

}

[Fact]
public void Scan_JavaCallableWrapperInterfaces_OmitsParentsAndDuplicateJavaNames ()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 💡 Testing — Please consider adding a cross-assembly variant of this regression: put the derived interface in the scanned app assembly and its parent in a referenced fixture/framework assembly. IsInterfaceAssignableFrom() now depends on TryResolveType() and ResolveEntityHandle() while crossing assembly indexes, but this fixture keeps both interfaces in TestFixtures, so the most common app-interface → bound-framework-interface path is not exercised.

Rule: Cover cross-assembly scanner behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants