Skip to content

[typemap] Validate exported Java fields - #12596

Open
simonrozsival wants to merge 7 commits into
mainfrom
simonrozsival-export-field-parity
Open

[typemap] Validate exported Java fields#12596
simonrozsival wants to merge 7 commits into
mainfrom
simonrozsival-export-field-parity

Conversation

@simonrozsival

@simonrozsival simonrozsival commented Aug 31, 2026

Copy link
Copy Markdown
Member

Summary

  • match legacy [ExportField] initializer validation in the trimmable scanner with localized XA4205/XA4207/XA4208 diagnostics
  • match Java.Interop.ExportFieldAttribute by full identity during validation, field collection, and registration parsing
  • reject invalid initializer members before adding Java fields or marshal methods
  • add focused build parity coverage for isolated and combined invalid initializers across LLVM-IR CoreCLR, trimmable CoreCLR, and trimmable NativeAOT
  • add on-device runtime parity coverage for instance field initialization alongside the existing static field tests

Behavior

Parameterized and void [ExportField] initializers now report XA4205 and XA4208 respectively, matching LLVM-IR. Generic declaring types report XA4207 before initializer signature validation in both trimmable runtimes.

Combined-invalid coverage verifies the same diagnostic precedence: XA4205 wins for a parameterized void initializer, while XA4207 wins when that initializer is declared on a generic type.

The scanner skips invalid initializer members instead of generating invalid Java fields and marshal methods. Attribute matching now uses the full Java.Interop.ExportFieldAttribute identity so unrelated user-defined attributes with the same short name are ignored.

Validation

  • 776 Microsoft.Android.Sdk.TrimmableTypeMap.Tests tests on the final head
  • focused 15-case build matrix covering isolated and combined invalid shapes across three supported runtime/typemap configurations
  • on-device Export coverage under LLVM-IR CoreCLR, trimmable CoreCLR, and trimmable NativeAOT
  • git diff --check

Root of GitHub Stack #12627. Tracks #12561 and #11289.

Copilot AI lite review requested due to automatic review settings August 31, 2026 07:15

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

🟡 Changes recommended

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review tier: Lite
Findings: 1 Medium severity · 1 Low severity

New issues introduced by this change (2)
Severity Finding
Medium severity src/​Xamarin.Android.Build.Tasks/​Tests/​Xamarin.Android.Build.Tests/​TrimmableTypeMapBuildTests.cs — ❌ error — The typemap output assertion only checks for *.TypeMap.dll, but trimmable typemap…
Low severity src/​Microsoft.Android.Sdk.TrimmableTypeMap/​Scanner/​JavaPeerScanner.cs — 💡 suggestion — ValidateExportField() introduces an extra per-method custom-attribute scan and…
What changed in this PR

This PR tightens trimmable typemap parity with the legacy [ExportField] pipeline by validating invalid exported-field initializer shapes early (parameterized/void), emitting the corresponding XA4205/XA4208 diagnostics, and ensuring the generator stops before writing partial typemap/Java outputs. It also expands the Java-source semantic parity fixture and adds new host/device coverage for static/instance/protected exported fields.

Changes:

  • Add [ExportField] signature validation in the trimmable scanner and surface XA4205/XA4208 through the shared logger/task plumbing.
  • Extend generator + integration fixtures/tests to assert “no partial Java fields / marshal methods” for invalid [ExportField] shapes and to validate ordered field semantics (static/instance/protected).
  • Add on-device coverage for instance primitive [ExportField] initialization visibility.
File Description
tests/​Mono.Android-Tests/​Mono.Android-Tests/​Java.Interop/​ExportTests.cs Adds a device test validating instance primitive exported-field initialization is visible via JNI.
tests/​Microsoft.Android.Sdk.TrimmableTypeMap.Tests/​TestFixtures/​TestTypes.cs Introduces invalid [ExportField] fixture types (parameterized + void return) for regression testing.
tests/​Microsoft.Android.Sdk.TrimmableTypeMap.Tests/​Generator/​TrimmableTypeMapGeneratorTests.cs Adds generator-level assertions for legacy XA4205/XA4208 diagnostics and absence of partial Java/typemap members.
tests/​Microsoft.Android.Sdk.TrimmableTypeMap.Tests/​Generator/​ExportFieldTests.cs Adds focused unit coverage ensuring invalid export fields produce no Java field or marshal wrapper.
tests/​Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/​JavaSourceSemanticParityTests.cs Extends the semantic parity fixture to cover field ordering/modifiers and adds a Java consumer for reads.
tests/​Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/​JavaSourceParityFixture/​JavaSourceParityTypes.cs Adds a protected exported field to increase fixture coverage for visibility and instance fields.
src/​Xamarin.Android.Build.Tasks/​Tests/​Xamarin.Android.Build.Tests/​TrimmableTypeMapBuildTests.cs Adds build-time coverage asserting invalid [ExportField] stops before writing typemap/Java outputs and matches legacy diagnostics.
src/​Xamarin.Android.Build.Tasks/​Tasks/​GenerateTrimmableTypeMap.cs Plumbs XA4205/XA4208 into the MSBuild logger using localized Java.Interop resources.
src/​Microsoft.Android.Sdk.TrimmableTypeMap/​Scanner/​JavaPeerScanner.cs Adds scanner-side validation to reject parameterized/void [ExportField] initializers before member emission.
src/​Microsoft.Android.Sdk.TrimmableTypeMap/​ITrimmableTypeMapLogger.cs Extends the shared logger interface with new ExportField-specific diagnostic hooks.

Comment thread src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/JavaPeerScanner.cs Outdated
@simonrozsival
simonrozsival force-pushed the simonrozsival-export-field-parity branch from 03d31af to 658036b Compare September 1, 2026 12:42
@simonrozsival
simonrozsival force-pushed the simonrozsival-export-field-parity branch from 658036b to 43a6569 Compare September 1, 2026 12:50
@simonrozsival
simonrozsival force-pushed the simonrozsival-export-field-parity branch 2 times, most recently from 871230e to 27baef7 Compare September 1, 2026 13:33
simonrozsival and others added 6 commits September 1, 2026 15:48
Match legacy XA4205 and XA4208 validation in the trimmable scanner, before invalid field members can reach generated typemap or Java outputs. Extend semantic, build, and device coverage for valid static and instance ExportField behavior and classify legacy-unsupported field names.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Prove that parameter-count validation takes precedence over void-return validation for an initializer violating both rules, matching measured llvm-ir behavior across trimmable CoreCLR and NativeAOT without partial outputs.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Match legacy XA4207 precedence for ExportField methods declared on generic types before parameter-count or void-return validation, and reject them before typemap or Java outputs are written.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Ignore unrelated attributes that share the ExportFieldAttribute simple name by matching the Java.Interop namespace consistently during validation, field collection, and marshal-method registration.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Remove duplicated scanner fixtures and keep focused build/runtime parity coverage.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@simonrozsival
simonrozsival force-pushed the simonrozsival-export-field-parity branch from 27baef7 to 5a3ce62 Compare September 1, 2026 13:54
@simonrozsival
simonrozsival changed the base branch from simonrozsival-jcw-interface-parity to main September 1, 2026 13:54
@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 #12596

@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.

Review summary

Verdict: ⚠️ Needs changes — 0 errors, 1 warning, 0 suggestions.

The validation logic matches the measured legacy diagnostic precedence, invalid members are excluded before field/marshal-method collection, and the localized task logging is wired consistently. The remaining issue is regression coverage: the final matrix no longer exercises combined-invalid signatures, so the precedence behavior is not protected.

CI build #1576821 is still in progress with no reported failures at review time.

Generated by Android PR Reviewer for #12596 · gpt56 · 243.4 AIC · ⌖ 9 AIC · ⊞ 25.7K
Comment /review to run again

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants