[typemap] Validate exported Java fields - #12596
Conversation
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review tier: Lite
Findings: 1
New issues introduced by this change (2)
| Severity | Finding |
|---|---|
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… |
|
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. |
03d31af to
658036b
Compare
658036b to
43a6569
Compare
871230e to
27baef7
Compare
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>
27baef7 to
5a3ce62
Compare
|
/review |
|
✅ Android PR Reviewer completed successfully!
|
There was a problem hiding this comment.
Review summary
Verdict:
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>


Summary
[ExportField]initializer validation in the trimmable scanner with localized XA4205/XA4207/XA4208 diagnosticsJava.Interop.ExportFieldAttributeby full identity during validation, field collection, and registration parsingBehavior
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
voidinitializer, 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.ExportFieldAttributeidentity so unrelated user-defined attributes with the same short name are ignored.Validation
Microsoft.Android.Sdk.TrimmableTypeMap.Teststests on the final headExportcoverage under LLVM-IR CoreCLR, trimmable CoreCLR, and trimmable NativeAOTgit diff --checkRoot of GitHub Stack #12627. Tracks #12561 and #11289.