diff --git a/extensions/typescript-language-features/src/commands/goToProjectConfiguration.ts b/extensions/typescript-language-features/src/commands/goToProjectConfiguration.ts index ee819648000..9273683ba4c 100644 --- a/extensions/typescript-language-features/src/commands/goToProjectConfiguration.ts +++ b/extensions/typescript-language-features/src/commands/goToProjectConfiguration.ts @@ -69,7 +69,7 @@ async function goToProjectConfig( return; } - let res: ServerResponse | undefined; + let res: ServerResponse.Response | undefined; try { res = await client.execute('projectInfo', { file, needFileNameList: false }, nulToken); } catch { diff --git a/extensions/typescript-language-features/src/features/rename.ts b/extensions/typescript-language-features/src/features/rename.ts index 55e6c819a08..aff2c508c53 100644 --- a/extensions/typescript-language-features/src/features/rename.ts +++ b/extensions/typescript-language-features/src/features/rename.ts @@ -79,7 +79,7 @@ class TypeScriptRenameProvider implements vscode.RenameProvider { document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken - ): Promise | undefined> { + ): Promise | undefined> { const file = this.client.toOpenedFilePath(document); if (!file) { return undefined; diff --git a/extensions/typescript-language-features/src/test/cachedResponse.test.ts b/extensions/typescript-language-features/src/test/cachedResponse.test.ts index de1003f284f..919d5d4d03c 100644 --- a/extensions/typescript-language-features/src/test/cachedResponse.test.ts +++ b/extensions/typescript-language-features/src/test/cachedResponse.test.ts @@ -8,7 +8,7 @@ import 'mocha'; import * as vscode from 'vscode'; import * as Proto from '../protocol'; import { CachedResponse } from '../tsServer/cachedResponse'; -import { ServerResponse, CancelledResponse } from '../typescriptService'; +import { ServerResponse } from '../typescriptService'; suite('CachedResponse', () => { test('should cache simple response for same document', async () => { @@ -36,12 +36,12 @@ suite('CachedResponse', () => { const doc = await createTextDocument(); const response = new CachedResponse(); - const cancelledResponder = createEventualResponder(); + const cancelledResponder = createEventualResponder(); const result1 = response.execute(doc, () => cancelledResponder.promise); const result2 = response.execute(doc, respondWith('test-0')); const result3 = response.execute(doc, respondWith('test-1')); - cancelledResponder.resolve(new CancelledResponse('cancelled')); + cancelledResponder.resolve(new ServerResponse.Cancelled('cancelled')); assert.strictEqual((await result1).type, 'cancelled'); assertResult(await result2, 'test-0'); @@ -52,12 +52,12 @@ suite('CachedResponse', () => { const doc = await createTextDocument(); const response = new CachedResponse(); - const cancelledResponder = createEventualResponder(); + const cancelledResponder = createEventualResponder(); const result1 = response.execute(doc, respondWith('test-0')); const result2 = response.execute(doc, () => cancelledResponder.promise); const result3 = response.execute(doc, respondWith('test-1')); - cancelledResponder.resolve(new CancelledResponse('cancelled')); + cancelledResponder.resolve(new ServerResponse.Cancelled('cancelled')); assertResult(await result1, 'test-0'); assertResult(await result2, 'test-0'); @@ -69,8 +69,8 @@ suite('CachedResponse', () => { const doc2 = await createTextDocument(); const response = new CachedResponse(); - const cancelledResponder = createEventualResponder(); - const cancelledResponder2 = createEventualResponder(); + const cancelledResponder = createEventualResponder(); + const cancelledResponder2 = createEventualResponder(); const result1 = response.execute(doc1, () => cancelledResponder.promise); const result2 = response.execute(doc1, respondWith('test-0')); @@ -79,8 +79,8 @@ suite('CachedResponse', () => { const result5 = response.execute(doc2, respondWith('test-2')); const result6 = response.execute(doc1, respondWith('test-3')); - cancelledResponder.resolve(new CancelledResponse('cancelled')); - cancelledResponder2.resolve(new CancelledResponse('cancelled')); + cancelledResponder.resolve(new ServerResponse.Cancelled('cancelled')); + cancelledResponder2.resolve(new ServerResponse.Cancelled('cancelled')); assert.strictEqual((await result1).type, 'cancelled'); assertResult(await result2, 'test-0'); @@ -99,7 +99,7 @@ function createTextDocument() { return vscode.workspace.openTextDocument({ language: 'javascript', content: '' }); } -function assertResult(result: ServerResponse, command: string) { +function assertResult(result: ServerResponse.Response, command: string) { if (result.type === 'response') { assert.strictEqual(result.command, command); } else { diff --git a/extensions/typescript-language-features/src/tsServer/cachedResponse.ts b/extensions/typescript-language-features/src/tsServer/cachedResponse.ts index ea8414cf8a5..2fb9b542281 100644 --- a/extensions/typescript-language-features/src/tsServer/cachedResponse.ts +++ b/extensions/typescript-language-features/src/tsServer/cachedResponse.ts @@ -7,13 +7,13 @@ import * as vscode from 'vscode'; import * as Proto from '../protocol'; import { ServerResponse } from '../typescriptService'; -type Resolve = () => Promise>; +type Resolve = () => Promise>; /** * Caches a class of TS Server request based on document. */ export class CachedResponse { - private response?: Promise>; + private response?: Promise>; private version: number = -1; private document: string = ''; @@ -25,7 +25,7 @@ export class CachedResponse { public execute( document: vscode.TextDocument, resolve: Resolve - ): Promise> { + ): Promise> { if (this.response && this.matches(document)) { // Chain so that on cancellation we fall back to the next resolve return this.response = this.response.then(result => result.type === 'cancelled' ? resolve() : result); @@ -40,7 +40,7 @@ export class CachedResponse { private async reset( document: vscode.TextDocument, resolve: Resolve - ): Promise> { + ): Promise> { this.version = document.version; this.document = document.uri.toString(); return this.response = resolve(); diff --git a/extensions/typescript-language-features/src/tsServer/callbackMap.ts b/extensions/typescript-language-features/src/tsServer/callbackMap.ts index 897a587b924..7f96de57159 100644 --- a/extensions/typescript-language-features/src/tsServer/callbackMap.ts +++ b/extensions/typescript-language-features/src/tsServer/callbackMap.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as Proto from '../protocol'; -import { CancelledResponse, ServerResponse } from '../typescriptService'; +import { ServerResponse } from '../typescriptService'; export interface CallbackItem { readonly onSuccess: (value: R) => void; @@ -14,11 +14,11 @@ export interface CallbackItem { } export class CallbackMap { - private readonly _callbacks = new Map | undefined>>(); - private readonly _asyncCallbacks = new Map | undefined>>(); + private readonly _callbacks = new Map | undefined>>(); + private readonly _asyncCallbacks = new Map | undefined>>(); public destroy(cause: string): void { - const cancellation = new CancelledResponse(cause); + const cancellation = new ServerResponse.Cancelled(cause); for (const callback of this._callbacks.values()) { callback.onSuccess(cancellation); } @@ -29,7 +29,7 @@ export class CallbackMap { this._asyncCallbacks.clear(); } - public add(seq: number, callback: CallbackItem | undefined>, isAsync: boolean) { + public add(seq: number, callback: CallbackItem | undefined>, isAsync: boolean) { if (isAsync) { this._asyncCallbacks.set(seq, callback); } else { @@ -37,7 +37,7 @@ export class CallbackMap { } } - public fetch(seq: number): CallbackItem | undefined> | undefined { + public fetch(seq: number): CallbackItem | undefined> | undefined { const callback = this._callbacks.get(seq) || this._asyncCallbacks.get(seq); this.delete(seq); return callback; diff --git a/extensions/typescript-language-features/src/tsServer/server.ts b/extensions/typescript-language-features/src/tsServer/server.ts index b657449ee32..6c237aa538d 100644 --- a/extensions/typescript-language-features/src/tsServer/server.ts +++ b/extensions/typescript-language-features/src/tsServer/server.ts @@ -8,7 +8,7 @@ import * as fs from 'fs'; import * as path from 'path'; import * as vscode from 'vscode'; import * as Proto from '../protocol'; -import { CancelledResponse, NoContentResponse, ServerResponse } from '../typescriptService'; +import { ServerResponse } from '../typescriptService'; import API from '../utils/api'; import { TsServerLogLevel, TypeScriptServiceConfiguration } from '../utils/configuration'; import { Disposable } from '../utils/dispose'; @@ -299,7 +299,7 @@ export class TypeScriptServer extends Disposable { } finally { const callback = this.fetchCallback(seq); if (callback) { - callback.onSuccess(new CancelledResponse(`Cancelled request ${seq} - ${command}`)); + callback.onSuccess(new ServerResponse.Cancelled(`Cancelled request ${seq} - ${command}`)); } } } @@ -315,15 +315,15 @@ export class TypeScriptServer extends Disposable { callback.onSuccess(response); } else if (response.message === 'No content available.') { // Special case where response itself is successful but there is not any data to return. - callback.onSuccess(NoContentResponse); + callback.onSuccess(ServerResponse.NoContent); } else { callback.onError(new TypeScriptServerError(this._version, response)); } } public executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: false, lowPriority?: boolean }): undefined; - public executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise>; - public executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise> | undefined { + public executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise>; + public executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise> | undefined { const request = this._requestQueue.createRequest(command, args); const requestInfo: RequestItem = { request, @@ -331,9 +331,9 @@ export class TypeScriptServer extends Disposable { isAsync: executeInfo.isAsync, queueingType: getQueueingType(command, executeInfo.lowPriority) }; - let result: Promise> | undefined; + let result: Promise> | undefined; if (executeInfo.expectsResult) { - result = new Promise>((resolve, reject) => { + result = new Promise>((resolve, reject) => { this._callbacks.add(request.seq, { onSuccess: resolve, onError: reject, startTime: Date.now(), isAsync: executeInfo.isAsync }, executeInfo.isAsync); if (executeInfo.token) { diff --git a/extensions/typescript-language-features/src/typescriptService.ts b/extensions/typescript-language-features/src/typescriptService.ts index 8f004c0e5eb..90ba448e9ed 100644 --- a/extensions/typescript-language-features/src/typescriptService.ts +++ b/extensions/typescript-language-features/src/typescriptService.ts @@ -11,19 +11,22 @@ import { TypeScriptServiceConfiguration } from './utils/configuration'; import Logger from './utils/logger'; import { PluginManager } from './utils/plugins'; -export class CancelledResponse { - public readonly type: 'cancelled' = 'cancelled'; +export namespace ServerResponse { - constructor( - public readonly reason: string - ) { } + export class Cancelled { + public readonly type = 'cancelled'; + + constructor( + public readonly reason: string + ) { } + } + + export const NoContent = new class { readonly type = 'noContent'; }; + export const LanguageServiceDisabled = new class { readonly type = 'languageServiceDisabled'; }; + + export type Response = T | Cancelled | typeof NoContent | typeof LanguageServiceDisabled; } -export const NoContentResponse = new class { readonly type = 'noContent'; }; -export const LanguageServiceDisabledContentResponse = new class { readonly type = 'languageServiceDisabled'; }; - -export type ServerResponse = T | CancelledResponse | typeof NoContentResponse | typeof LanguageServiceDisabledContentResponse; - export interface TypeScriptRequestTypes { 'applyCodeActionCommand': [Proto.ApplyCodeActionCommandRequestArgs, Proto.ApplyCodeActionCommandResponse]; 'completionEntryDetails': [Proto.CompletionDetailsRequestArgs, Proto.CompletionDetailsResponse]; @@ -103,7 +106,7 @@ export interface ITypeScriptServiceClient { args: TypeScriptRequestTypes[K][0], token: vscode.CancellationToken, lowPriority?: boolean - ): Promise>; + ): Promise>; executeWithoutWaitingForResponse(command: 'open', args: Proto.OpenRequestArgs): void; executeWithoutWaitingForResponse(command: 'close', args: Proto.FileRequestArgs): void; @@ -111,7 +114,7 @@ export interface ITypeScriptServiceClient { executeWithoutWaitingForResponse(command: 'compilerOptionsForInferredProjects', args: Proto.SetCompilerOptionsForInferredProjectsArgs): void; executeWithoutWaitingForResponse(command: 'reloadProjects', args: null): void; - executeAsync(command: 'geterr', args: Proto.GeterrRequestArgs, token: vscode.CancellationToken): Promise>; + executeAsync(command: 'geterr', args: Proto.GeterrRequestArgs, token: vscode.CancellationToken): Promise>; /** * Cancel on going geterr requests and re-queue them after `f` has been evaluated. diff --git a/extensions/typescript-language-features/src/typescriptServiceClient.ts b/extensions/typescript-language-features/src/typescriptServiceClient.ts index 799f24864c1..91353cd1055 100644 --- a/extensions/typescript-language-features/src/typescriptServiceClient.ts +++ b/extensions/typescript-language-features/src/typescriptServiceClient.ts @@ -11,7 +11,7 @@ import BufferSyncSupport from './features/bufferSyncSupport'; import { DiagnosticKind, DiagnosticsManager } from './features/diagnostics'; import * as Proto from './protocol'; import { TypeScriptServer, TypeScriptServerSpawner } from './tsServer/server'; -import { ITypeScriptServiceClient, ServerResponse, LanguageServiceDisabledContentResponse } from './typescriptService'; +import { ITypeScriptServiceClient, ServerResponse } from './typescriptService'; import API from './utils/api'; import { TsServerLogLevel, TypeScriptServiceConfiguration } from './utils/configuration'; import { Disposable } from './utils/dispose'; @@ -590,7 +590,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType return undefined; } - public execute(command: string, args: any, token: vscode.CancellationToken, lowPriority?: boolean): Promise> { + public execute(command: string, args: any, token: vscode.CancellationToken, lowPriority?: boolean): Promise> { return this.executeImpl(command, args, { isAsync: false, token, @@ -607,7 +607,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType }); } - public executeAsync(command: string, args: Proto.GeterrRequestArgs, token: vscode.CancellationToken): Promise> { + public executeAsync(command: string, args: Proto.GeterrRequestArgs, token: vscode.CancellationToken): Promise> { return this.executeImpl(command, args, { isAsync: true, token, @@ -616,8 +616,8 @@ export default class TypeScriptServiceClient extends Disposable implements IType } private executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: false, lowPriority?: boolean }): undefined; - private executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise>; - private executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise> | undefined { + private executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise>; + private executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise> | undefined { const runningServerState = this.service(); if (!runningServerState.langaugeServiceEnabled) { @@ -634,7 +634,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType 'reloadProjects', ]; if (nonSemanticCommands.indexOf(command) === -1) { - return Promise.resolve(LanguageServiceDisabledContentResponse); + return Promise.resolve(ServerResponse.LanguageServiceDisabled); } }