Skip to content

Proposal: Replace emitter with syntax tree transformations and a simplified node emitter. #5595

Closed
@rbuckton

Description

@rbuckton

In an effort to better support down-level transformations for complex emit like generators and Async Functions, and to be able to add new down-level transformations for the evolving ECMA-262 specification, we propose to replace the current emitter logic for the TypeScript compiler with an implementation that relies on transformations of the source tree.

Our current emitter is not built to handle the requirements for some of the more complex rewriting needed to support features such as generators (ES6/ES2015) and Async Functions (ES2016). In addition, as time goes on we will need to add more and more branching logic to handle down-level emit of new language features due to the yearly cadence that TC39 is adopting for the ECMAScript specification.

Syntax tree transformations will give us the ability to transform our source tree in an iterative fashion, allowing us to inject new transformations at the head of a transformation chain so that few (if any) changes need to be made to existing transformations in later iterations. As a result, there would be minimal maintenance for the complex transformations needed for down-level generators, as long as new features are already transformed into a syntactically valid ES6 tree.

Generally this will also help to reduce the branching logic of our current emitter, and keep syntactic transformations isolated to an individual file for a language version or feature. As a result, the emitter itself can be simplified drastically and focus specifically on emitting the given syntax tree with almost no branching logic.

Requirements:

  • No transformation should directly modify the original source tree.
  • Transformations should be isolated to a specific language version or, when necessary, a language feature (i.e. TypeScript to ES6, ES6 to ES5, AMD module transformations, etc.).
  • Transformations should reuse existing syntax tree nodes when possible.
  • Transformations should employ a mechanism to quickly identify whether a node or subtree requires transformation to avoid a full walk of a source tree for each iteration.
  • Transformations should preserve source locations for use with source maps.
  • Transformations should not significantly impact the performance of the compiler, and ideally should improve compile time.

Goals:

  • Transform a TypeScript syntax tree into a compatible JavaScript syntax tree based on compiler settings.
  • Source Map emit should behave as it does in the current compiler.
  • Comment preservation should behave as it does in the current compiler.

Non-Goals:

  • We will not be replacing our declaration emitter with transformations at this time, though we may consider this in a future proposal.
  • We will not support end-user extensibility of these transformations at this time, though we may consider this in a future proposal.

Remaining Tasks:

  • Update to support block-scoped declarations captured in loops.
  • Verify comment preservation
  • Investigate comment preservation performance issues
  • Verify/adjust source map output
  • Fix failing tests
  • Update transformations to match recent changes to the emitter.
  • Investigate/improve performance of tree-transforming emitter.

Metadata

Metadata

Assignees

Labels

CommittedThe team has roadmapped this issueFixedA PR has been merged for this issueSuggestionAn idea for TypeScript

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions