Skip to content

Implement ES decorator transform (ESNext -> ES2022)#2926

Merged
jakebailey merged 51 commits intomicrosoft:mainfrom
AlCalzone:transform-es-decorators
Mar 11, 2026
Merged

Implement ES decorator transform (ESNext -> ES2022)#2926
jakebailey merged 51 commits intomicrosoft:mainfrom
AlCalzone:transform-es-decorators

Conversation

@AlCalzone
Copy link
Copy Markdown
Contributor

@AlCalzone AlCalzone commented Feb 27, 2026

This PR implements the decorator transform portion of #2354

This is the only thing blocking me from adopting tsgo, so I thought I'd help out by porting the original PR.

Disclaimer: This is an entire day worth of Claude Opus tokens. I don't claim I understand how it works, but I did my best to direct Claude to minimize the baseline diffs, of which it removed quite a few.

Fixes #2354

Copilot AI review requested due to automatic review settings February 27, 2026 14:10
Copy link
Copy Markdown
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

Implements the ES decorator downlevel transform needed for --target es2022 (from esnext) in the TypeScript-Go emitter pipeline, along with the helper emit support and updated golden baselines to reflect the new output.

Changes:

  • Adds ES decorator runtime helpers (__esDecorate, __runInitializers) to the printer helper set.
  • Ensures the external helpers import declaration is passed through the module transformer visitor so it’s properly transformed for the output module kind.
  • Fixes a named-evaluation check in getAssignedNameOfPropertyName and updates many conformance/compiler baselines to match the new decorator transform output.

Reviewed changes

Copilot reviewed 154 out of 273 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
internal/printer/helpers.go Adds new emit helpers for ES decorators and initializer execution.
internal/transformers/moduletransforms/esmodule.go Visits the external helpers import declaration so it can be transformed appropriately (e.g., import = requireconst require).
internal/transformers/estransforms/namedevaluation.go Fixes a computed-property-name check to validate the correct node.
testdata/baselines/reference/submodule/compiler/importHelpersVerbatimModuleSyntax.js Baseline updated for the corrected external helpers import emission.
testdata/baselines/reference/submodule/compiler/importHelpersVerbatimModuleSyntax.js.diff Baseline diff updated accordingly.
testdata/baselines/reference/submodule/conformance/* Extensive baseline updates reflecting ES decorator downlevel transform output across many scenarios (classes, fields, accessors, private elements, metadata, named evaluation, using, etc.).

@jakebailey jakebailey marked this pull request as ready for review March 10, 2026 20:23
@jakebailey jakebailey requested review from Copilot and weswigham March 10, 2026 20:24
@jakebailey
Copy link
Copy Markdown
Member

This should be ready for a re-review. I've fixed the comments (to my eye), reordered functions, then went 1:1 down and fixed any minor mismatches. There are no longer any NewNodeVisitor calls outside of construction, too.

Copy link
Copy Markdown
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

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

@jakebailey
Copy link
Copy Markdown
Member

In any case, thanks for sending this @AlCalzone; most everything I pushed was little bits or thing that would have been a bit challenging to describe, but basically everything else seemed good to me 😄

@AlCalzone
Copy link
Copy Markdown
Contributor Author

Thanks for pushing it closer to the finish line!

Copy link
Copy Markdown
Member

@weswigham weswigham left a comment

Choose a reason for hiding this comment

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

I think we're basically good now - just some small nits.

// or the proper es class field transform for the legacy one
var (
NewESNextTransformer = transformers.Chain(newESDecoratorTransformer, newUsingDeclarationTransformer, newClassFieldsTransformer)
esDecoratorAndClassFields = transformers.Chain(newESDecoratorTransformer, newClassFieldsTransformer)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is gonna be a little spicy when decorators stablize into a year, since implicitly class fields will have to move into the same one, but also be globally first for the legacy transform still. Future problem, though.

statements = append(statements, externalHelpersImportDeclaration)
// The helpers import must be visited so that `import x = require("tslib")`
// (TypeScript-only syntax) is transformed to `const x = require("tslib")`
// for CJS output files via visitImportEqualsDeclaration.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yeah... looking at it createExternalHelpersImportDeclarationIfNeeded makes an import= and leaves it to the later transform to handle when the file/module is commonjs, however since we can't have a commonjs file that's transformed to, eg, amd or umd anymore, we really should just be making the const in that helper, since there isn't a need for variable output anymore.

We can keep doing this roundabout downleveling, but we don't really have a reason not to generate the right nodes up-front.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

For a follow-up PR, then?

@jakebailey jakebailey requested review from Copilot and weswigham March 11, 2026 21:23
Copy link
Copy Markdown
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

Copilot reviewed 213 out of 402 changed files in this pull request and generated 4 comments.


You can also share your feedback on Copilot code review. Take the survey.

@jakebailey jakebailey enabled auto-merge March 11, 2026 21:30
@jakebailey jakebailey added this pull request to the merge queue Mar 11, 2026
Merged via the queue into microsoft:main with commit f1afaf9 Mar 11, 2026
21 checks passed
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.

Implement esnext->es2022 transformer (ES decorators, using declarations)

4 participants