Skip to content

Commit ad96a52

Browse files
authored
fix: IOSession access this before calling super (microsoft#40645)
* fix: IOSession access this before calling super close microsoft#40399 This makes the TS server crashes if the build target is ES6 or higher. * fix * revert unrelated changes * revert unrelated changes * revert unrelated changes * better way
1 parent 9e5a779 commit ad96a52

File tree

1 file changed

+8
-13
lines changed

1 file changed

+8
-13
lines changed

src/tsserver/server.ts

+8-13
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,11 @@ namespace ts.server {
323323
this.installer = childProcess.fork(combinePaths(__dirname, "typingsInstaller.js"), args, { execArgv });
324324
this.installer.on("message", m => this.handleMessage(m));
325325

326-
this.event({ pid: this.installer.pid }, "typingsInstallerPid");
326+
// We have to schedule this event to the next tick
327+
// cause this fn will be called during
328+
// new IOSession => super(which is Session) => new ProjectService => NodeTypingsInstaller.attach
329+
// and if "event" is referencing "this" before super class is initialized, it will be a ReferenceError in ES6 class.
330+
this.host.setImmediate(() => this.event({ pid: this.installer.pid }, "typingsInstallerPid"));
327331

328332
process.on("exit", () => {
329333
this.installer.kill();
@@ -481,21 +485,12 @@ namespace ts.server {
481485
private eventPort: number | undefined;
482486
private eventSocket: NodeSocket | undefined;
483487
private socketEventQueue: { body: any, eventName: string }[] | undefined;
488+
/** No longer needed if syntax target is es6 or above. Any access to "this" before initialized will be a runtime error. */
484489
private constructed: boolean | undefined;
485490

486491
constructor() {
487-
const event: Event | undefined = (body: object, eventName: string) => {
488-
if (this.constructed) {
489-
this.event(body, eventName);
490-
}
491-
else {
492-
// It is unsafe to dereference `this` before initialization completes,
493-
// so we defer until the next tick.
494-
//
495-
// Construction should finish before the next tick fires, so we do not need to do this recursively.
496-
// eslint-disable-next-line no-restricted-globals
497-
setImmediate(() => this.event(body, eventName));
498-
}
492+
const event = (body: object, eventName: string) => {
493+
this.event(body, eventName);
499494
};
500495

501496
const host = sys;

0 commit comments

Comments
 (0)