Skip to content

fix(transformer/legacy-decorator): emit correct metadata types for enum#13327

Merged
overlookmotel merged 2 commits intomainfrom
08-27-fix_transformer_legacy-decorator_emit_correct_metadata_types_for_enum
Aug 28, 2025
Merged

fix(transformer/legacy-decorator): emit correct metadata types for enum#13327
overlookmotel merged 2 commits intomainfrom
08-27-fix_transformer_legacy-decorator_emit_correct_metadata_types_for_enum

Conversation

@Dunqing
Copy link
Member

@Dunqing Dunqing commented Aug 27, 2025

Copilot AI review requested due to automatic review settings August 27, 2025 13:57
@Dunqing Dunqing requested a review from overlookmotel as a code owner August 27, 2025 13:57
@github-actions github-actions bot added the A-transformer Area - Transformer / Transpiler label Aug 27, 2025
Copy link
Member Author

Dunqing commented Aug 27, 2025


How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • 0-merge - adds this PR to the back of the merge queue
  • hotfix - for urgent hot fixes, skip the queue and merge this PR next

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@github-actions github-actions bot added the C-bug Category - Bug label Aug 27, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes the metadata emission for enum types in legacy decorators by ensuring that enum references in decorator metadata emit the correct primitive types (String, Number, or Object) instead of defaulting to Object.

  • Adds enum type inference to determine whether an enum is string-based, number-based, or mixed
  • Implements optimization to only analyze enums that are actually referenced as types in decorators
  • Updates the type serialization logic to emit appropriate primitive types for enum references

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tasks/transform_conformance/tests/legacy-decorators/test/fixtures/oxc/metadata/enum-types/output.js Test output showing correct metadata emission with String/Number types for enum properties
tasks/transform_conformance/tests/legacy-decorators/test/fixtures/oxc/metadata/enum-types/input.ts Test input defining various enum types (string, number, bigint, mixed, computed) with decorated properties
tasks/transform_conformance/snapshots/oxc.snap.md Updated test results showing the new test passing
crates/oxc_transformer/src/lib.rs Adds enum statement processing to the main transformer
crates/oxc_transformer/src/decorator/mod.rs Forwards enum declaration processing to legacy decorator handler
crates/oxc_transformer/src/decorator/legacy/mod.rs Delegates statement processing to metadata collection
crates/oxc_transformer/src/decorator/legacy/metadata.rs Core implementation of enum type inference and metadata emission

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@Dunqing Dunqing force-pushed the 08-27-fix_transformer_legacy-decorator_emit_correct_metadata_types_for_enum branch from 787f328 to 8deb807 Compare August 27, 2025 14:02
@codspeed-hq
Copy link

codspeed-hq bot commented Aug 27, 2025

CodSpeed Instrumentation Performance Report

Merging #13327 will not alter performance

Comparing 08-27-fix_transformer_legacy-decorator_emit_correct_metadata_types_for_enum (0a353dd) with main (e459866)1

Summary

✅ 34 untouched benchmarks

Footnotes

  1. No successful run was found on main (34d0a01) during the generation of this report, so e459866 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@Dunqing Dunqing force-pushed the 08-27-fix_transformer_legacy-decorator_emit_correct_metadata_types_for_enum branch 2 times, most recently from a8ba87a to f9a7350 Compare August 28, 2025 03:04
@Dunqing Dunqing force-pushed the 08-27-fix_transformer_legacy-decorator_emit_correct_metadata_types_for_enum branch from f9a7350 to 4b431b2 Compare August 28, 2025 03:10
Comment on lines 269 to 273
Expression::UnaryExpression(expr)
if expr.argument.is_number_literal() && !has_string =>
{
has_number = true;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not all UnaryExpressions evaluate to a number. It depends on the operator:

  • !123 -> boolean
  • typeof 123 -> string
  • void 123 -> undefined
  • delete 123 -> boolean

The first one is not entirely stupid - !0 and !1 are sometimes used as shortcuts for true / false.

Copy link
Member Author

@Dunqing Dunqing Aug 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, I forgot the importance of the operator. In this case, we only care about +, - and ~. For the typeof 123, it isn't allowed. See TypeScript Playground

Copy link
Member

@overlookmotel overlookmotel Aug 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the typeof 123, it isn't allowed. See TypeScript Playground

Ah ha. Does this mean we can assume any computed expression (e.g. foo()) evaluates to a number?

But maybe the gain of that is not worth the trouble. Some more complex expressions that evaluate to strings seem to be allowed e.g. enum E { X = 'foo' + 'bar' + 'qux' }. So we'd need to handle those to accurately determine whether string or number.

@Dunqing Dunqing force-pushed the 08-27-fix_transformer_legacy-decorator_emit_correct_metadata_types_for_enum branch from 4b431b2 to cc3b0cf Compare August 28, 2025 13:35
@Dunqing Dunqing requested a review from overlookmotel August 28, 2025 13:42
Copy link
Member

@overlookmotel overlookmotel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pushed a commit just to update the comment about #[inline] - hope you don't mind, I thought it'd save time vs another round of review. Will merge as soon as CI passes.

@overlookmotel overlookmotel merged commit 24fee15 into main Aug 28, 2025
32 of 33 checks passed
@overlookmotel overlookmotel deleted the 08-27-fix_transformer_legacy-decorator_emit_correct_metadata_types_for_enum branch August 28, 2025 15:23
graphite-app bot pushed a commit that referenced this pull request Aug 29, 2025
Follow-on after #13327.

It seems that TS infers the type of `+x`, `-x`, and `~x` as `Number`, no matter what `x` is.

All other `UnaryOperator`s (`!x`, `void x`, `typeof x`, `delete x`) are illegal as enum initializers, so we can ignore those cases and just say all `UnaryExpression`s are `Number`s.

[TS Playground](https://www.typescriptlang.org/play/?experimentalDecorators=true&emitDecoratorMetadata=true&target=99#code/GYVwdgxgLglg9mABAcwKZQMpQE4zMgCgEpEBvRbdEbJAcgGcc9laBuRAXwCgvUwQAtogCqYAIbYAngHkoAC1TYAovyGkuiRGFTIxsAG6pEAXkQBaNJib5iAGg2IADnHowDR0wGpLWXDaL2mgBGbgDuMPQeiAB+PtaEAVzcXKCQsAiIACaoEHDYeqgEAPpQEpYAXIhiYJK2iEWO2HCOilCSlYx+yCSkyagAHs7YUIgQADZi9PSIAGJwcGQOAALZuflQqA7gEjLyigAKTY6VojuyCsqqJiLiUueKKoIAdNq67qxJXEA)

Additionally, `BigInt`s are illegal as enum initializers, so we can ignore them too.

[TS Playground](https://www.typescriptlang.org/play/?experimentalDecorators=true&emitDecoratorMetadata=true&target=99#code/KYOwrgtgBAQglgcwJIgC4FFzQN4CgpQBGiUAvFAIwAMVIANPkYgsAE5mU0324C+uQA)

We can therefore simplify type inference for decorators.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-transformer Area - Transformer / Transpiler C-bug Category - Bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

transformer: include inferred type for enums in the same module for emitDecoratorMetadata

3 participants