Skip to content

[typemap] Preserve exported constructor throws metadata - #12564

Merged
jonathanpeppers merged 3 commits into
mainfrom
simonrozsival-trimmable-typemap-parity-gaps
Aug 31, 2026
Merged

[typemap] Preserve exported constructor throws metadata#12564
jonathanpeppers merged 3 commits into
mainfrom
simonrozsival-trimmable-typemap-parity-gaps

Conversation

@simonrozsival

Copy link
Copy Markdown
Member

Summary

  • preserve [Export(Throws = ...)] metadata on generated Java constructors
  • convert JNI exception names to valid Java source names for constructor and method throws clauses
  • validate converted exception names for reserved Java identifiers
  • add scanner, generator, integration, and constructor activation coverage
  • add closed-generic wrapping coverage for exactly-once activation and stable peer identity

TDD matrix

The constructor fixture passed with llvm-ir and failed with the original trimmable typemap because its generated Java constructor omitted the checked exception declaration. After the fix, the unchanged constructor parity category passes under:

  • llvm-ir + CoreCLR: 2/2
  • trimmable + CoreCLR: 2/2
  • trimmable + NativeAOT: 2/2

Additional validation:

  • Microsoft.Android.Sdk.TrimmableTypeMap.Tests: 771/771
  • Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests: 24/24

Fixes #12561

simonrozsival and others added 2 commits August 28, 2026 12:54
Carry exported constructor exception metadata through scanning and Java source generation, and add constructor activation coverage for checked exceptions and caller-directed closed generic wrappers.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Convert JNI exception names before checking Java source identifiers so reserved package and nested-type segments are diagnosed for constructors and methods.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings August 28, 2026 12:07

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

Review tier: Lite
Findings: 1 Medium severity

New issues introduced by this change (1)
Severity Finding
Medium severity tests/​Mono.Android-Tests/​Mono.Android-Tests/​Java.Interop/​JnienvTest.cs⚠️ Resource management — second is not disposed when Assert.AreSame fails. If GetObject ever…
What changed in this PR

This PR closes a remaining trimmable typemap parity gap by carrying [Export(... Throws = ...)] exception metadata through scanning and into generated JCW Java constructors (not just methods), while validating/normalizing exception type names for Java source emission. It also adds targeted runtime/integration/unit test coverage for constructor throws propagation and for stable peer identity / exactly-once activation in closed-generic wrapping scenarios.

Changes:

  • Propagate [Export] constructor thrown exception metadata through the trimmable typemap scanner model and into the JCW Java source generator (throws clauses for constructors).
  • Normalize/validate thrown exception names via JNI→Java-source conversion before reserved-identifier validation.
  • Add/extend runtime, integration, and generator tests to cover constructor throws clauses and closed-generic wrapper activation/identity.
File Description
tests/​Mono.Android-Tests/​Mono.Android-Tests/​Java.Interop/​JnienvTest.cs Adds runtime coverage for wrapping an existing Java handle as a known closed generic type and ensuring stable peer identity / single activation.
tests/​Mono.Android-Tests/​Mono.Android-Tests/​Java.Interop/​ConstructorActivationTests.cs Adds Java-side activation coverage for an [Export] constructor declaring Throws.
tests/​Microsoft.Android.Sdk.TrimmableTypeMap.Tests/​TestFixtures/​TestTypes.cs Extends fixture types to include an [Export] constructor with declared thrown exception names.
tests/​Microsoft.Android.Sdk.TrimmableTypeMap.Tests/​TestFixtures/​StubAttributes.cs Updates stub Java.Interop.ExportAttribute to support constructors and SuperArgumentsString for scanning/generation tests.
tests/​Microsoft.Android.Sdk.TrimmableTypeMap.Tests/​Generator/​TrimmableTypeMapGeneratorTests.cs Updates reserved-name validation coverage to include thrown exception references in constructor/method validation.
tests/​Microsoft.Android.Sdk.TrimmableTypeMap.Tests/​Generator/​JcwJavaSourceGeneratorTests.cs Adds unit coverage asserting generated Java constructors include a throws clause.
tests/​Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/​UserTypesFixture/​UserTypes.cs Adds an [Export] constructor with Throws to the integration fixture.
tests/​Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/​ScannerExportShapesTests.cs Adds integration assertions that constructor thrown exceptions are surfaced by the scanner model.
src/​Microsoft.Android.Sdk.TrimmableTypeMap/​TrimmableTypeMapGenerator.cs Validates constructor/method thrown exception names after JNI→Java conversion for Java-source identifier checks.
src/​Microsoft.Android.Sdk.TrimmableTypeMap/​Scanner/​JavaPeerScanner.cs Propagates ThrownNames from constructor marshal-methods into JavaConstructorInfo.
src/​Microsoft.Android.Sdk.TrimmableTypeMap/​Scanner/​JavaPeerInfo.cs Extends JavaConstructorInfo model with ThrownNames metadata.
src/​Microsoft.Android.Sdk.TrimmableTypeMap/​Generator/​JcwJavaSourceGenerator.cs Emits throws clauses for generated Java constructors and centralizes throws-clause formatting with JNI→Java conversion.
Comment thread tests/Mono.Android-Tests/Mono.Android-Tests/Java.Interop/JnienvTest.cs Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@jonathanpeppers
jonathanpeppers merged commit 3606de0 into main Aug 31, 2026
44 checks passed
@jonathanpeppers
jonathanpeppers deleted the simonrozsival-trimmable-typemap-parity-gaps branch August 31, 2026 13:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

3 participants