From 74d8d656f133c9dde87c283bf40c7953ea917dbc Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Wed, 29 Jun 2016 18:00:07 -0700 Subject: [PATCH] move setImmediate to host --- src/harness/harnessLanguageService.ts | 8 +++ src/server/session.ts | 10 +-- src/server/utilities.ts | 4 -- .../cases/unittests/cachingInServerLSHost.ts | 4 +- tests/cases/unittests/session.ts | 4 +- .../cases/unittests/tsserverProjectSystem.ts | 64 ++++++++++++++----- 6 files changed, 68 insertions(+), 26 deletions(-) diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 553d59428ab..3b5918c3286 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -666,6 +666,14 @@ namespace Harness.LanguageService { clearTimeout(timeoutId: any): void { clearTimeout(timeoutId); } + + setImmediate(callback: (...args: any[]) => void, ms: number, ...args: any[]): any { + return setImmediate(callback, args); + } + + clearImmediate(timeoutId: any): void { + clearImmediate(timeoutId); + } } export class ServerLanguageServiceAdapter implements LanguageServiceAdapter { diff --git a/src/server/session.ts b/src/server/session.ts index f3d439580f3..b741c421859 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -165,9 +165,11 @@ namespace ts.server { export const ProjectLanguageServiceDisabled = new Error("The project's language service is disabled."); } - export interface ServerHost extends ts.System { + export interface ServerHost extends System { setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): any; clearTimeout(timeoutId: any): void; + setImmediate(callback: (...args: any[]) => void, ...args: any[]): any; + clearImmediate(timeoutId: any): void; } export class Session { @@ -318,10 +320,10 @@ namespace ts.server { followMs = ms; } if (this.errorTimer) { - clearTimeout(this.errorTimer); + this.host.clearTimeout(this.errorTimer); } if (this.immediateId) { - clearImmediate(this.immediateId); + this.host.clearImmediate(this.immediateId); this.immediateId = undefined; } let index = 0; @@ -331,7 +333,7 @@ namespace ts.server { index++; if (checkSpec.project.containsFile(checkSpec.fileName, requireOpen)) { this.syntacticCheck(checkSpec.fileName, checkSpec.project); - this.immediateId = setImmediate(() => { + this.immediateId = this.host.setImmediate(() => { this.semanticCheck(checkSpec.fileName, checkSpec.project); this.immediateId = undefined; if (checkList.length > index) { diff --git a/src/server/utilities.ts b/src/server/utilities.ts index 03d608bfd3e..79a8edc0f8c 100644 --- a/src/server/utilities.ts +++ b/src/server/utilities.ts @@ -69,10 +69,6 @@ namespace ts.server { return fileName; } - export function asNormalizedPathArray(fileNames: string[]): NormalizedPath[] { - return fileNames; - } - export interface NormalizedPathMap { get(path: NormalizedPath): T; set(path: NormalizedPath, value: T): void; diff --git a/tests/cases/unittests/cachingInServerLSHost.ts b/tests/cases/unittests/cachingInServerLSHost.ts index 0d9590d5431..888618fcefb 100644 --- a/tests/cases/unittests/cachingInServerLSHost.ts +++ b/tests/cases/unittests/cachingInServerLSHost.ts @@ -63,7 +63,9 @@ namespace ts { }; }, setTimeout, - clearTimeout + clearTimeout, + setImmediate, + clearImmediate }; } diff --git a/tests/cases/unittests/session.ts b/tests/cases/unittests/session.ts index c8a952da02e..90343f4699d 100644 --- a/tests/cases/unittests/session.ts +++ b/tests/cases/unittests/session.ts @@ -21,7 +21,9 @@ namespace ts.server { readDirectory(): string[] { return []; }, exit(): void { }, setTimeout(callback, ms, ...args) { return 0; }, - clearTimeout(timeoutId) { } + clearTimeout(timeoutId) { }, + setImmediate: () => 0, + clearImmediate() {} }; const nullCancellationToken: HostCancellationToken = { isCancellationRequested: () => false }; const mockLogger: Logger = { diff --git a/tests/cases/unittests/tsserverProjectSystem.ts b/tests/cases/unittests/tsserverProjectSystem.ts index fc6ef16e398..a0ba0c37ce5 100644 --- a/tests/cases/unittests/tsserverProjectSystem.ts +++ b/tests/cases/unittests/tsserverProjectSystem.ts @@ -136,6 +136,36 @@ namespace ts { checkFileNames(`${server.ProjectKind[project.projectKind]} project, rootFileNames`, project.getRootFiles(), expectedFiles); } + class Callbacks { + private map: { [n: number]: TimeOutCallback } = {}; + private nextId = 1; + + register(cb: (...args: any[]) => void, args: any[]) { + const timeoutId = this.nextId; + this.nextId++; + this.map[timeoutId] = cb.bind(undefined, ...args); + return timeoutId; + } + unregister(id: any) { + if (typeof id === "number") { + delete this.map[id]; + } + } + + count() { + return sizeOfMap(this.map); + } + + invoke() { + for (const id in this.map) { + if (hasProperty(this.map, id)) { + this.map[id](); + } + } + this.map = {}; + } + } + type TimeOutCallback = () => any; class TestServerHost implements server.ServerHost { @@ -146,8 +176,8 @@ namespace ts { private getCanonicalFileName: (s: string) => string; private toPath: (f: string) => Path; - private nextTimeoutId = 0; - private callbacks: { [n: number]: TimeOutCallback } = {}; + private timeoutCallbacks = new Callbacks(); + private immediateCallbacks = new Callbacks(); readonly watchedDirectories: Map<{ cb: DirectoryWatcherCallback, recursive: boolean }[]> = {}; readonly watchedFiles: Map = {}; @@ -286,30 +316,32 @@ namespace ts { } // TOOD: record and invoke callbacks to simulate timer events - readonly setTimeout = (callback: TimeOutCallback, time: number, ...args: any[]) => { - const timeoutId = this.nextTimeoutId; - this.nextTimeoutId++; - this.callbacks[timeoutId] = callback.bind(undefined, ...args); - return timeoutId; + setTimeout (callback: TimeOutCallback, time: number, ...args: any[]) { + return this.timeoutCallbacks.register(callback, args); }; - readonly clearTimeout = (timeoutId: any): void => { - if (typeof timeoutId === "number") { - delete this.callbacks[timeoutId]; - } + + clearTimeout(timeoutId: any): void { + this.timeoutCallbacks.unregister(timeoutId); }; checkTimeoutQueueLength(expected: number) { - const callbacksCount = sizeOfMap(this.callbacks); + const callbacksCount = this.timeoutCallbacks.count(); assert.equal(callbacksCount, expected, `expected ${expected} timeout callbacks queued but found ${callbacksCount}.`); } runQueuedTimeoutCallbacks() { - for (const id in this.callbacks) { - this.callbacks[id](); - } - this.callbacks = []; + this.timeoutCallbacks.invoke(); } + setImmediate (callback: TimeOutCallback, time: number, ...args: any[]) { + return this.immediateCallbacks.register(callback, args); + }; + + clearImmediate(timeoutId: any): void { + this.immediateCallbacks.unregister(timeoutId); + }; + + readonly readFile = (s: string) => (this.fs.get(this.toPath(s))).content; readonly resolvePath = (s: string) => s; readonly getExecutingFilePath = () => this.executingFilePath;