Skip to content

Conversation

@weswigham
Copy link
Member

@weswigham weswigham commented Dec 11, 2025

This PR ports emit for --experimentalDecorators and --emitDecoratorMetadata, since many users of the former also enable the later (which isn't even supported with standardized decorators in strada, apparently).

This looks pretty solid from the baselines at this point, I've only noticed two things I still want to follow up on, or at least get someone else's opinion on:

  • The single sourcemap test'd diffs are still all outta line - there's just way more mappings. Something is probably missing a EFNoSourceMaps that should have it. Or it could just be class fields not being transformed yet. I'm unsure. (See sourceMapValidationDecorators.sourcemap.txt) Somewhere there's a nicer tool for viewing sourcemap diffs than our textual baselines, I just need to find it again...
  • There's a target: es5 test of a constructor reference to a decorated class within a static of that class - binding behavior here intentionally changes after es6, and the test is effectively targeting es6 now (thanks to the new minimum target), so it's probably fine, but I'm not wholly convinced.

Additionally, I haven't included the conditional lookup of the BigInt global in emit for targets < es2020 at present. I could add it back, I'm just not completely sure why it was needed in the first place, and with Symbol definitely no longer being maybe-conditional with min target es6, it was the only use of the conditional global type reference emit logic.

Most of the remaining diffs in the touched baselines that weren't outright deleted are just other unported emit features remaining in the diffs - class fields, mostly, and a little await.

Fixes #914

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 implements emit support for --experimentalDecorators and --emitDecoratorMetadata compiler options, enabling the transformation of decorator syntax into the required runtime helper code.

Key changes:

  • Added decorator emit transformation logic that removes decorator syntax from classes, methods, properties, and parameters
  • Generates __decorate, __metadata, and __param helper functions when decorators are present
  • Transforms decorated classes into expressions with decorator application calls

Reviewed changes

Copilot reviewed 299 out of 560 changed files in this pull request and generated no comments.

Show a summary per file
File Description
decoratorOnClassMethod4.js.diff Removed diff showing decorator transformation now working correctly
decoratorOnClassMethod4.js Added __decorate helper and transformed decorator application
decoratorOnClassMethod3.js.diff Similar cleanup showing convergence with TypeScript behavior
decoratorOnClassMethod3.js Added decorator helpers and transformed decorator syntax
decoratorOnClassMethod2.js.diff Diff removed as decorator emit now matches expected output
decoratorOnClassMethod2.js Decorator transformation implemented correctly
decoratorOnClassMethod19(target=esnext).js.diff Removed diff for esnext target decorator handling
decoratorOnClassMethod19(target=esnext).js Added decorator helpers with static block for private field access
decoratorOnClassMethod19(target=es2022).js.diff Removed diff for es2022 target
decoratorOnClassMethod19(target=es2022).js Matching decorator emit for es2022
decoratorOnClassMethod19(target=es2015).js.diff Reduced diff showing private field handling differences
decoratorOnClassMethod19(target=es2015).js Added decorator helpers with static blocks
decoratorOnClassMethod18.js.diff Removed diff for property decorator
decoratorOnClassMethod18.js Property decorator emit working
decoratorOnClassMethod17.js.diff Method decorator diff removed
decoratorOnClassMethod17.js Method decorator transformation complete
(additional files) Similar patterns of decorator transformation across methods, accessors, constructors, and classes
sourceMapValidationDecorators.sourcemap.txt.diff Updated source map mappings for decorator transformations
sourceMapValidationDecorators.js.diff Consolidated decorator transformation changes
parameterDecoratorsEmitCrash.js.diff Fixed constructor parameter decorator formatting
parameterDecoratorsEmitCrash.js Corrected parameter decorator placement

Copy link
Member

@jakebailey jakebailey left a comment

Choose a reason for hiding this comment

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

I read every diff and it all looks great! Awesome!

- static method(x) { }
- static set x(x) { }
+ constructor(
+ @dec
Copy link
Member

Choose a reason for hiding this comment

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

This is a new diff; what's going on here?

Copy link
Member Author

Choose a reason for hiding this comment

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

Decorators without --experimentalDecorators don't have a transform (yet), so aren't being transformed in the output. The TS transform formerly was eliding all parameter modifier/decorators until I fixed that here, which is why it's now preserved in the output.

+class C {
+}
+export { C };
+var after;
Copy link
Member

Choose a reason for hiding this comment

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

There are a few tests like this where after is misplaced; I don't know how much it matters, though, given it's a var?

(Oh, hm, maybe this is just "it's es5 so who cares")

Copy link
Member Author

Choose a reason for hiding this comment

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

Functionally identical for sure, I looked at this one and eventually just went with "eh, probably doesn't matter". I actually don't get the old behavior - hoisted variables usually get injected at the top of the scope, so I'm not sure why the old behavior had it near the bottom near the actual assignment.

Copy link
Member

@jakebailey jakebailey left a comment

Choose a reason for hiding this comment

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

Everything I mentioned above are small nits, I think, so I would be happy with this as is!

@jakebailey
Copy link
Member

The only other thing is to remove !!! emitDecoratorMetadata from program.go where we would have emitted an error on this option.

@tmm1
Copy link
Contributor

tmm1 commented Dec 11, 2025

Thank you for tackling this 🙏

@tmm1
Copy link
Contributor

tmm1 commented Dec 12, 2025

  • Somewhere there's a nicer tool for viewing sourcemap diffs than our textual baselines, I just need to find it again...

Perhaps you're thinking of https://evanw.github.io/source-map-visualization

@weswigham
Copy link
Member Author

The only other thing is to remove !!! emitDecoratorMetadata from program.go where we would have emitted an error on this option.

AFAIK that's already gone, replaced with the error requiring emitDecoratorMetadata be specified alongside experimentalDecorators.

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.

Not transpiling decorators

3 participants