-
Notifications
You must be signed in to change notification settings - Fork 763
--experimentalDecorators and --emitDecoratorMetadata #2343
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this 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__paramhelper 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 |
jakebailey
left a comment
There was a problem hiding this 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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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")
There was a problem hiding this comment.
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.
jakebailey
left a comment
There was a problem hiding this 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!
|
The only other thing is to remove |
|
Thank you for tackling this 🙏 |
Perhaps you're thinking of https://evanw.github.io/source-map-visualization |
AFAIK that's already gone, replaced with the error requiring |
This PR ports emit for
--experimentalDecoratorsand--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:
EFNoSourceMapsthat 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...target: es5test 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 targetinges6now (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
BigIntglobal 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 withSymboldefinitely 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