Skip to content

fix(compiler): match ngtsc propDecorators member shape in setClassMetadata - #543

Merged
Brooooooklyn merged 1 commit into
mainfrom
fix/issue-539-aot-propdecorators-shape
Oct 6, 2026
Merged

Brooooooklyn merged 1 commit into
mainfrom
fix/issue-539-aot-propdecorators-shape

Conversation

@Brooooooklyn

Copy link
Copy Markdown
Member

Fixes #539.

Problem

OXC's AOT setClassMetadata propDecorators (build_prop_decorators_metadata_in) diverged from ngtsc's extractClassMetadata (metadata.ts:90-115) in member shape:

  1. Static members included. Upstream filters !member.isStatic and accessLevel !== EcmaScriptPrivate; OXC didn't check r#static, so decorated static members — and static x = input(0) via the synthesized signal path — leaked into propDecorators.
  2. String-literal keys not flagged quoted. Upstream uses quoted: shouldQuoteName (ts.isStringLiteralLike), so 'x' emits "x": while OXC emitted x: — a textual divergence (illegal identifiers like 'x-y' were already quoted by the emitter's validity check, so this never produced invalid JS).

Change

  • Skip r#static class elements in build_prop_decorators_metadata_in (covers both explicit decorators and the synthesized initializer-API path).
  • New member_key_name returns (name, quoted); quoted is true for StringLiteral and bare TemplateLiteral keys and feeds both LiteralMapEntry::new calls.
  • Private #x members were already excluded (no usable key name).

Not ported: upstream's DUPLICATE_DECORATED_PROPERTIES fatal diagnostic — unreachable in practice (the only same-name pair is a getter/setter, which can't both be decorated) and this builder has no diagnostic channel. Can be added later if a reachable path is found.

Testing

  • New test_set_class_metadata_prop_decorators_member_shape asserts instance members stay, string keys emit quoted, and static/private members are excluded (including static x = input(0)).
  • cargo test -p oxc_angular_compiler: 2943 passed, 0 failed.
  • Verified end-to-end via transformAngularFileSync(..., {emitClassMetadata: true}): {instanceProp:[{type:Input}],"str-key":[{type:Input}]} — matching ngtsc.

…adata

OXC's AOT `setClassMetadata` propDecorators diverged from ngtsc's
`extractClassMetadata` (metadata.ts) in two ways:

1. Static members were included. Upstream filters `!member.isStatic`
   (and `accessLevel !== EcmaScriptPrivate`); OXC did not check
   `r#static`, so a decorated static member — or a `static x = input(0)`
   picked up by the synthesized initializer-API path — leaked into
   `propDecorators` while ngtsc omits it.

2. String-literal member keys were not marked quoted. Upstream sets
   `quoted: shouldQuoteName` when the member's name node is a string
   literal (`ts.isStringLiteralLike`), so `'x'` emits `"x":` while OXC
   emitted `x:`. (Illegal identifiers like 'x-y' were already quoted by
   the emitter's identifier check, so this is a textual divergence, not
   invalid output.)

`build_prop_decorators_metadata_in` now skips `r#static` elements and
threads a `quoted` flag from the member key (string literal or
no-substitution template literal) into both `LiteralMapEntry`s, matching
upstream's quote behavior exactly.

The upstream duplicate-decorated-members diagnostic is not ported: it is
unreachable in practice (the only same-name pair is a getter/setter,
which cannot both carry decorators) and `builders.rs` has no diagnostic
channel.

Fixes #539
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@Brooooooklyn
Brooooooklyn merged commit b5f8933 into main Oct 6, 2026
10 checks passed
@Brooooooklyn
Brooooooklyn deleted the fix/issue-539-aot-propdecorators-shape branch October 6, 2026 12:55
Sign up for free to 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.

fix(aot): setClassMetadata propDecorators includes static members and emits string-literal member keys unquoted

1 participant