build: fix async private method token fusion; inlineChat: adopt native private fields#308797
Merged
build: fix async private method token fusion; inlineChat: adopt native private fields#308797
Conversation
…ewrite In minified code, `async#method()` has no space between `async` and `#method`. The `#` naturally starts a new token, but when replaced with `$a`, the `$` is a valid identifier character — `async$a` fuses into a single identifier. This makes any `await` inside the method body a syntax error. Fix: when the character immediately before the `#` is an identifier character, prepend a space to the replacement text. Add 3 tests covering async, static async, and the readable variant.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR addresses a build-time bug in the private-field rewrite (token fusion for minified async#method patterns) and modernizes the inline chat implementation by switching from TypeScript private _field members to native ES #private fields.
Changes:
- Fix
convertPrivateFieldsto insert a separating space when aPrivateIdentifierfollows an identifier character (preventsasync$atoken fusion). - Add/extend unit tests covering async private method minified forms.
- Convert inline chat browser code to use native
#privatefields for state and injected services.
Show a summary per file
| File | Description |
|---|---|
| build/next/private-to-property.ts | Prevents token fusion by conditionally prefixing replacements with a space based on preceding character. |
| build/next/test/private-to-property.test.ts | Adds tests intended to cover async/static-async private method minified cases. |
| src/vs/workbench/contrib/inlineChat/browser/inlineChatZoneWidget.ts | Migrates internal state/options/logging to native #private fields. |
| src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts | Migrates widget internals and injected services to #private fields. |
| src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionServiceImpl.ts | Migrates service internals/events/session map to #private fields. |
| src/vs/workbench/contrib/inlineChat/browser/inlineChatOverlayWidget.ts | Migrates overlay widgets’ DOM/state/history interactions to #private fields. |
| src/vs/workbench/contrib/inlineChat/browser/inlineChatNotebook.ts | Migrates disposable store to #private field. |
| src/vs/workbench/contrib/inlineChat/browser/inlineChatHistoryService.ts | Migrates storage/history handling to #private fields/method. |
| src/vs/workbench/contrib/inlineChat/browser/inlineChatEditorAffordance.ts | Migrates widget state/editor refs to #private fields and methods. |
| src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts | Migrates controller state/services and internal helpers to #private fields/methods. |
Copilot's findings
- Files reviewed: 10/10 changed files
- Comments generated: 1
Convert inlineChat module from TypeScript private (`private _field`) to native ES private fields (`#field`) for better encapsulation and V8 performance (after the private-to-property build step mangles them).
8f08454 to
8f9f550
Compare
alexr00
approved these changes
Apr 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fix async private method token fusion in the private-to-property build rewrite, and adopt native ES private fields in the inlineChat module.
Session Context
Key decisions from the development session:
#is an identifier character (e.g.async#run), the replacement is prefixed with a space (async $ainstead ofasync$a). This is safe because an extra space in a non-minified position never changes semantics, and in minified code it's the minimal fix to prevent the$from fusing with the preceding keyword.isIdentifierCharhelper: Checksa-z,A-Z,0-9,_,$— the characters that can continue an identifier in JS. Placed outsideconvertPrivateFieldsas a module-level utility since it's pure and stateless.async#method, minifiedstatic async#method, and non-minifiedasync #method(which already had a space and passed before the fix).esbuild.transform()syntax check added in the prior PR is what caught this bug during the build — it works as intended.Changes
Commit 1:
build: fix async private method token fusionprivate-to-property.ts: When emitting a replacement for aPrivateIdentifier, check if the preceding character is an identifier char. If so, prepend a space to prevent token fusion (e.g.async#run→async $anotasync$a).private-to-property.ts: AddisIdentifierChar()helper.test/private-to-property.test.ts: 3 new tests for async, static async, and readable async private methods.Commit 2:
inlineChat: adopt native ES private fieldsprivate _fieldto#fieldpattern.