From d1510288f0c3f0dd1f1301b20c3f2bc4f5d61fd1 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 18 Sep 2020 15:53:58 -0700 Subject: [PATCH] Add timeout for `vscode.workspace.findFiles` For #87494 --- .../src/task/taskProvider.ts | 4 +++- .../src/task/tsconfigProvider.ts | 24 +++++++++++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/extensions/typescript-language-features/src/task/taskProvider.ts b/extensions/typescript-language-features/src/task/taskProvider.ts index 85d3b574ae3..f324e0ff60a 100644 --- a/extensions/typescript-language-features/src/task/taskProvider.ts +++ b/extensions/typescript-language-features/src/task/taskProvider.ts @@ -38,6 +38,8 @@ interface TypeScriptTaskDefinition extends vscode.TaskDefinition { class TscTaskProvider implements vscode.TaskProvider { private readonly projectInfoRequestTimeout = 2000; + private readonly findConfigFilesTimeout = 5000; + private autoDetect: AutoDetect = 'on'; private readonly tsconfigProvider: TsConfigProvider; private readonly disposables: vscode.Disposable[] = []; @@ -160,7 +162,7 @@ class TscTaskProvider implements vscode.TaskProvider { } private async getTsConfigsInWorkspace(): Promise { - return Array.from(await this.tsconfigProvider.getConfigsForWorkspace()); + return Array.from(await this.tsconfigProvider.getConfigsForWorkspace({ timeout: this.findConfigFilesTimeout })); } private static async getCommand(project: TSConfig): Promise { diff --git a/extensions/typescript-language-features/src/task/tsconfigProvider.ts b/extensions/typescript-language-features/src/task/tsconfigProvider.ts index d44b828e384..247b6bb321a 100644 --- a/extensions/typescript-language-features/src/task/tsconfigProvider.ts +++ b/extensions/typescript-language-features/src/task/tsconfigProvider.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; +import { wait } from '../test/testUtils'; export interface TSConfig { readonly uri: vscode.Uri; @@ -13,12 +14,13 @@ export interface TSConfig { } export class TsConfigProvider { - public async getConfigsForWorkspace(): Promise> { + public async getConfigsForWorkspace(options?: { timeout: number }): Promise> { if (!vscode.workspace.workspaceFolders) { return []; } + const configs = new Map(); - for (const config of await vscode.workspace.findFiles('**/tsconfig*.json', '**/{node_modules,.*}/**')) { + for (const config of await this.findConfigFiles(options)) { const root = vscode.workspace.getWorkspaceFolder(config); if (root) { configs.set(config.fsPath, { @@ -31,4 +33,22 @@ export class TsConfigProvider { } return configs.values(); } + + private async findConfigFiles(options?: { timeout: number }): Promise { + const timeout = options?.timeout; + const task = (token?: vscode.CancellationToken) => vscode.workspace.findFiles('**/tsconfig*.json', '**/{node_modules,.*}/**', undefined, token); + + if (typeof timeout === 'number') { + const cancel = new vscode.CancellationTokenSource(); + return Promise.race([ + task(cancel.token), + wait(timeout).then(() => { + cancel.cancel(); + return []; + }), + ]); + } else { + return task(); + } + } }