Skip to content

[typemap] Preserve supported Unicode JCW names - #12607

Open
simonrozsival wants to merge 7 commits into
mainfrom
simonrozsival-unicode-jcw-identifiers
Open

[typemap] Preserve supported Unicode JCW names#12607
simonrozsival wants to merge 7 commits into
mainfrom
simonrozsival-unicode-jcw-identifiers

Conversation

@simonrozsival

Copy link
Copy Markdown
Member

Summary

  • preserve supported BMP Unicode Java identifiers across trimmable JCW source paths, declarations, manifest names, ACW mappings, typemap keys, DEX, and JNI activation
  • reject combining/format characters, supplementary code points, malformed segments, and reserved identifiers early with XA4258 before trimmable outputs are written
  • add semantic javac/classfile, three-runtime host, and three-runtime device activation coverage

Fixes part of #12561.

Validation

  • 887 trimmable typemap unit tests
  • generated Java semantic parity + javac tests
  • 12-case llvm-ir/CoreCLR/NativeAOT host matrix
  • llvm-ir CoreCLR, trimmable CoreCLR, and trimmable NativeAOT device activation matrix
  • legacy JCW identifier and package-name diagnostic tests

CopilotAI lite review requested due to automatic review settings August 31, 2026 20:13

CopilotAI 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 Low severity

New issues introduced by this change (1)
SeverityFinding
Low severitysrc/​Microsoft.Android.Sdk.TrimmableTypeMap/​JavaNameValidator.cs — 💡 suggestion — When a package/JNI name contains an empty segment (e.g. consecutive separators),…
What changed in this PR

This PR extends the trimmable typemap/JCW pipeline to preserve supported BMP Unicode Java identifiers end-to-end (typemap keys, JCW source paths/declarations, ACW mappings, manifest component names, DEX, and runtime/JNI activation), while rejecting unsupported Unicode forms early via XA4258.

Changes:

  • Tighten Java/JNI name validation to accept a constrained set of stable BMP identifiers and reject combining/format/supplementary code points with XA4258.
  • Add generator + integration + device/runtime coverage to prove Unicode identifiers survive generation/compilation/activation across llvm-ir/CoreCLR/NativeAOT matrices.
  • Update XA4258 wording and documentation to reflect the broader “invalid or unsupported” identifier class.
FileDescription
tests/​MSBuildDeviceIntegration/​Tests/​InstallAndRunTests.csAdds device activation test for an Activity with a Unicode Java identifier.
tests/​Mono.Android-Tests/​Mono.Android-Tests/​Java.Interop/​ConstructorActivationTests.csAdds Java-side constructor/peer-registration test for a Unicode-registered type.
tests/​Microsoft.Android.Sdk.TrimmableTypeMap.Tests/​Generator/​TypeMapModelBuilderTests.csVerifies typemap model preserves Unicode code points in map keys/JNI names.
tests/​Microsoft.Android.Sdk.TrimmableTypeMap.Tests/​Generator/​TrimmableTypeMapGeneratorTests.csExpands XA4258 validation coverage for unsupported Unicode/identifier shapes and updates expected message text.
tests/​Microsoft.Android.Sdk.TrimmableTypeMap.Tests/​Generator/​ManifestGeneratorTests.csEnsures manifest component names preserve Unicode code points.
tests/​Microsoft.Android.Sdk.TrimmableTypeMap.Tests/​Generator/​JcwJavaSourceGeneratorTests.csExtends JNI name validation tests for decomposed/supplementary forms and validates a Unicode-good case.
tests/​Microsoft.Android.Sdk.TrimmableTypeMap.Tests/​Generator/​JavaNameValidatorTests.csAdds focused unit tests for valid BMP Unicode identifiers and rejected unsupported cases.
tests/​Microsoft.Android.Sdk.TrimmableTypeMap.Tests/​Generator/​AcwMapWriterTests.csVerifies ACW map writing preserves Unicode identifiers.
tests/​Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/​JavaSourceSemanticParityTests.csAdds semantic parity compilation path assertions for Unicode-generated Java artifacts.
tests/​Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/​JavaSourceParityFixture/​JavaSourceParityTypes.csAdds a fixture Activity registered under a Unicode Java name.
src/​Xamarin.Android.Build.Tasks/​Tests/​Xamarin.Android.Build.Tests/​TrimmableTypeMapBuildTests.csAdds build-time assertions that Unicode names survive intermediate outputs/manifest/acw-map and documents DEX limitations for supplementary code points.
src/​Xamarin.Android.Build.Tasks/​Properties/​Resources.resxUpdates XA4258 resource text to “invalid or unsupported”.
src/​Xamarin.Android.Build.Tasks/​Properties/​Resources.Designer.csRegenerates designer text for the updated XA4258 resource.
src/​Microsoft.Android.Sdk.TrimmableTypeMap/​JavaNameValidator.csImplements restricted Unicode identifier support/validation logic for stable toolchain behavior.
src/​Microsoft.Android.Sdk.TrimmableTypeMap/​Generator/​JniSignatureHelper.csRoutes JNI-name validation through the centralized JavaNameValidator checks and updates exception text.
src/​Microsoft.Android.Sdk.TrimmableTypeMap/​Generator/​JcwJavaSourceGenerator.csUpdates documentation for what JNI-name validation now enforces.
Documentation/​docs-mobile/​messages/​xa4258.mdUpdates XA4258 docs to explain unsupported Unicode categories and toolchain constraints.
Documentation/​docs-mobile/​messages/​index.mdUpdates XA4258 index entry to match new wording.
Files not reviewed (1)
  • src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs: Generated file
Suppressed comments (1)

src/Microsoft.Android.Sdk.TrimmableTypeMap/JavaNameValidator.cs:98

  • 💡 suggestion — Similar to package validation, TryGetInvalidJniNameSegment can report an empty invalidSegment for malformed JNI names (leading/trailing/consecutive /). That produces error text like identifier ''. Substituting a placeholder makes XA4258/ArgumentException messages clearer.
 var segments = jniName.Split ('/');
for (int i = 0; i < segments.Length - 1; i++) {
if (IsInvalidIdentifier (segments [i], isTypeName: false)) {
invalidSegment = segments [i];
return true;
}

@simonrozsival
simonrozsivalforce-pushed the simonrozsival-constructor-signature-diagnostics branch from 0430b67 to 765d233CompareSeptember 1, 2026 12:42
@simonrozsival
simonrozsivalforce-pushed the simonrozsival-unicode-jcw-identifiers branch 2 times, most recently from 1736423 to 2c0c9b0CompareSeptember 1, 2026 12:50
@simonrozsival
simonrozsivalforce-pushed the simonrozsival-constructor-signature-diagnostics branch from 765d233 to 8936f2aCompareSeptember 1, 2026 12:50
@simonrozsival
simonrozsivalforce-pushed the simonrozsival-unicode-jcw-identifiers branch from 2c0c9b0 to 3a02aacCompareSeptember 1, 2026 12:54
@simonrozsival
simonrozsivalforce-pushed the simonrozsival-constructor-signature-diagnostics branch from 8936f2a to 9d75936CompareSeptember 1, 2026 12:54
@simonrozsival
simonrozsivalforce-pushed the simonrozsival-unicode-jcw-identifiers branch from 3a02aac to dbcfed4CompareSeptember 1, 2026 13:15
@simonrozsival
simonrozsivalforce-pushed the simonrozsival-constructor-signature-diagnostics branch from 9d75936 to 7854663CompareSeptember 1, 2026 13:15
@simonrozsival
simonrozsivalforce-pushed the simonrozsival-unicode-jcw-identifiers branch from dbcfed4 to 6918557CompareSeptember 1, 2026 13:33
@simonrozsival
simonrozsivalforce-pushed the simonrozsival-constructor-signature-diagnostics branch from 7854663 to 8b98f5fCompareSeptember 1, 2026 13:33
simonrozsivaland others added 4 commits September 1, 2026 15:50
Allow BMP letter identifiers to flow unchanged through trimmable JCW generation and diagnose name categories that Android tooling cannot carry consistently.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Classify BMP identifiers from OpenJDK 21 Unicode 15 data, require NFC names, and distinguish portable type starts from Android package and manifest constraints.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Resolve manifest placeholders before validation and alias rewriting, decode DEX and classfile modified UTF-8 exactly, and record the supplementary class-loader limitation.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Resolve manifest packages and placeholders consistently before deduplication, and validate DEX and modified UTF-8 inputs without lossy or unbounded decoding.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@simonrozsival
simonrozsivalforce-pushed the simonrozsival-unicode-jcw-identifiers branch from 6918557 to ab9d010CompareSeptember 1, 2026 13:54
@simonrozsival
simonrozsivalforce-pushed the simonrozsival-constructor-signature-diagnostics branch from 8b98f5f to 3ea14beCompareSeptember 1, 2026 13:54
@simonrozsival
simonrozsival changed the base branch from simonrozsival-constructor-signature-diagnostics to mainSeptember 1, 2026 13:54
simonrozsivaland others added 2 commits September 3, 2026 19:22
Keep the llvm-ir case limited to identifiers that javac rejects, while the trimmable cases cover names rejected by the frozen validation policy.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Resolve overlapping typemap generator, diagnostics, and test changes while preserving both Unicode validation and the latest export/custom-view behavior.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@simonrozsival

Copy link
Copy Markdown
MemberAuthor

/review

@github-actions

github-actionsBot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Android PR Reviewer completed successfully!

Generated by Android PR Reviewer for #12607

@github-actionsgithub-actionsBot 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.

⚠️ Needs Changes

Findings: 1 ❌ error · 0 ⚠️ warnings · 0 💡 suggestions

The Unicode identifier handling is comprehensive and well covered across source generation, typemap, manifest, DEX, and JNI activation paths. One compatibility issue remains: the new manifest validation treats an activity alias’s own name as a Java type name, rejecting aliases Android accepts. The alias target should remain validated, while the alias identifier itself should not use type-name rules.

All 44 CI checks completed successfully.

Generated by Android PR Reviewer for #12607 · gpt56 · 516.8 AIC · ⌖ 9.16 AIC · ⊞ 25.7K
Comment /review to run again

Comment threadsrc/Microsoft.Android.Sdk.TrimmableTypeMap/TrimmableTypeMapGenerator.cs Outdated
Validate activity-alias targetActivity as a Java type, but leave the alias name to Android's component-name handling. Cover non-type alias names, placeholder expansion, target rewriting and rooting, invalid targets, and manifests without scanned peers.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for freeto 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

@simonrozsival