Repository navigation
Conversation
…rmat` Add the option (TransformOptions, NAPI and Vite plugin; off by default, as in the tsconfig `ng new` generates). Legacy ids are computed on the template before whitespace removal, like Angular's first I18nMetaVisitor pass, and ICU cases are now Containers so ICU digests match ngc. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #628.
Problem
ngtsc's
enableI18nLegacyMessageIdFormatwrites each message's legacy ids (computeDigest,computeDecimalDigest) into the$localizemetadata block (:@@custom␟<sha1>␟<decimal>:text). oxc had no such option and never emitted them, so translation files keyed by legacy ids could not be used. ICU digests were also wrong: the i18n parser kept a single-node ICU case as a bare node, while Angular'si18n_parser.tsvisitExpansionalways wraps it in aContainer, whichdigest.tsserializes as[...].Fix
enableI18nLegacyMessageIdFormatoption onTransformOptions(Rustenable_i18n_legacy_message_id_format), the NAPI binding and the Vite plugin. It is off by default:@angular/buildpasses the tsconfig'sangularCompilerOptionsthrough unchanged, and thetsconfig.jsonthatng newgenerates sets it tofalse(@schematics/angular22.2.3). compiler-cli's own default when unset istrue.html_to_r3sets the legacy ids on element,i18n-*attribute and ICU messages, asI18nMetaVisitor._setLegacyIds(render3/view/i18n/meta.ts) does. Element messages are digested from the template before whitespace removal (with_untrimmed_nodes), like Angular's first meta pass.serialize_i18n_headappends␟<id>for each legacy id (LocalizedString.serializeI18nHead,output/output_ast.ts). PerserializeI18nTemplatePart, an ICU placeholder only gets@@<id>when its sub-message has no legacy ids. That is also the case for an ICU inside a nested element, because Angular's meta visitor has nocurrentMessagethere.Container.With the option on and off, the
$localizestrings of 14 messages (elements, attributes, ICUs,@if,preserveWhitespacestrue/false) are identical to Angular 22.2ngcoutput with the same setting. The only difference is thei18n_Nvariable numbering, which is unrelated to this change.Checks
tests/integration_test.rs):test_i18n_legacy_message_ids(ports "should render legacy ids whenenableI18nLegacyMessageIdFormatis not false", "should render custom id and legacy ids ifenableI18nLegacyMessageIdFormatis not false" and "should not render legacy ids whenenableI18nLegacyMessageIdFormatis set to false"),test_i18n_legacy_message_ids_for_icus(ports "should also render legacy ids for ICUs when normal messages are using legacy ids"), andtest_i18n_legacy_message_ids_untrimmed_attribute_and_nested_icu(expected output fromngc).cargo test -p oxc_angular_compiler --all-features: 3519 passed, 0 failed. No snapshot changes.cargo check -p oxc_angular_compiler_napipasses.cargo clippy -p oxc_angular_compiler --all-featuresreports no warnings on changed lines.🤖 Generated with Claude Code