Skip to content

Fix escaped keyword ASI (#64883) and new-expression emit parens (#64981) - #65013

Closed
Timur Vural (timurzvural) wants to merge 1 commit into
microsoft:mainfrom
timurzvural:fix/64883-64981
Closed

Timur Vural (timurzvural) wants to merge 1 commit into
microsoft:mainfrom
timurzvural:fix/64883-64981

Conversation

@timurzvural

Copy link
Copy Markdown

Summary

Fixes two native Go / TS7+ bugs:

Fixes #64883 — Escaped in / instanceof after class field initializers

After a class field initializer, Unicode-escaped \u{69}n / \u{69}nstanceof on the next line were parsed as the in / instanceof operators (TS1260 + parse error). Per ECMA-262, keyword terminals cannot be expressed with Unicode escapes, so these should be IdentifierNames (matching V8).

Change: Treat escaped keywords as non-operators in the binary-operator path so ASI can end the previous expression and the escaped name can start a new class member. Unescaped in after a field initializer still continues the expression (test262 fields-asi-5.js).

Fixes #64981 — new (f() as T).C() drops required parentheses on emit

new (getPlugins() as any).Linker() was emitted as new getPlugins().Linker() (i.e. (new getPlugins()).Linker()), causing a runtime TypeError.

Change: Parenthesize when the leftmost expression (stopping at calls, walking through parentheses / partially-emitted / assertion wrappers) is a CallExpression, matching classic TS6 emit: new (getPlugins().Linker)().

Test plan

  • Added Go unit tests in parser_test.go, printer_test.go, and typeeraser_test.go
  • CI / existing test suite

AI assistance disclosure

This change was authored with Cursor Agent (an LLM-based coding agent). A human operator directed the investigation at these specific open issues, reviewed the resulting patch, and is submitting it for review. Per CONTRIBUTING.md, AI tool use is disclosed here.

…ens (microsoft#64981)

- Do not treat Unicode-escaped keywords as binary operators so
  `\u{69}n` / `\u{69}nstanceof` after a class field initializer become
  IdentifierNames (microsoft#64883).
- Parenthesize new-expression operands whose leftmost expression is a
  call, including after as/satisfies/non-null erasure, so
  `new (f() as T).C()` emits as `new (f().C)()` (microsoft#64981).
- Add regression tests for parser, printer, and type eraser.

AI assistance disclosure: this change was authored with Cursor Agent.
@jakebailey

Copy link
Copy Markdown
Member

Why are there two fixes in one PR

@timurzvural

Copy link
Copy Markdown
Author

timurzvural please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.

@microsoft-github-policy-service agree [company="{your company}"]

Options:

  • (default - no company specified) I have sole ownership of intellectual property rights to my Submissions and I am not making Submissions in the course of work for my employer.
@microsoft-github-policy-service agree
  • (when company given) I am making Submissions in the course of work for my employer (or my employer has intellectual property rights in my Submissions by contract or applicable law). I have permission from my employer to make Submissions and enter into this Agreement on behalf of my employer. By signing below, the defined term “You” includes me and my employer.
@microsoft-github-policy-service agree company="Microsoft"

Contributor License Agreement

@microsoft-github-policy-service agree

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The shared helper’s deeper traversal adds redundant parentheses to already-parenthesized arrow bodies, conflicting with existing emit baselines; it should be scoped to the new-expression check.

1 open issue
What changed in this PR

This PR addresses two native TypeScript compiler bugs: escaped keywords preventing automatic semicolon insertion after class fields (#64883), and missing parentheses changing the meaning of emitted new expressions (#64981).

Changes:

  • Exclude Unicode-escaped keywords from binary-operator parsing.
  • Detect calls within constructor expressions to preserve required parentheses.
  • Add parser, printer, and type-erasure regression tests.
File Description
tsc/​internal/​transformers/​tstransforms/​typeeraser_test.go Tests constructor grouping after type syntax is erased.
tsc/​internal/​printer/​printer.go Extends call detection when emitting new expressions.
tsc/​internal/​printer/​printer_test.go Tests constructor property access rooted in a call.
tsc/​internal/​parser/​parser.go Prevents escaped keywords from acting as binary operators.
tsc/​internal/​parser/​parser_test.go Tests escaped class fields and unescaped in continuation.
tsc/​internal/​ast/​precedence.go Makes leftmost-expression traversal cross parentheses.

Review effort: Balanced

KindPropertyAccessExpression,
KindNonNullExpression,
KindPartiallyEmittedExpression,
KindParenthesizedExpression,
@timurzvural

Copy link
Copy Markdown
Author

Closing this combined PR in favor of two focused single-issue PRs (one bug each):

Please review those instead. Thanks!

@timurzvural

Copy link
Copy Markdown
Author

Replaced by focused PRs #65014 (#64883) and #65015 (#64981).

@github-project-automation github-project-automation Bot moved this from Not started to Done in PR Backlog Oct 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

For Backlog Bug PRs that fix a backlog bug

Projects

Status: Done

4 participants