diff --git a/Extension/src/LanguageServer/client.ts b/Extension/src/LanguageServer/client.ts index 8be7dc006..b09c4c408 100644 --- a/Extension/src/LanguageServer/client.ts +++ b/Extension/src/LanguageServer/client.ts @@ -89,7 +89,7 @@ export function hasTrustedCompilerPaths(): boolean { // Data shared by all clients. let languageClient: LanguageClient; -let firstClientStarted: Promise; +let firstClientStarted: Promise<{ wasShutdown: boolean }>; let languageClientCrashedNeedsRestart: boolean = false; const languageClientCrashTimes: number[] = []; let compilerDefaults: configs.CompilerDefaults | undefined; @@ -508,6 +508,10 @@ interface CppInitializationParams { settings: SettingsParams; } +interface CppInitializationResult { + shouldShutdown: boolean; +} + interface TagParseStatus { localizeStringParams: LocalizeStringParams; isPaused: boolean; @@ -585,7 +589,7 @@ export interface CopilotCompletionContextParams { // Requests const PreInitializationRequest: RequestType = new RequestType('cpptools/preinitialize'); -const InitializationRequest: RequestType = new RequestType('cpptools/initialize'); +const InitializationRequest: RequestType = new RequestType('cpptools/initialize'); const QueryCompilerDefaultsRequest: RequestType = new RequestType('cpptools/queryCompilerDefaults'); const SwitchHeaderSourceRequest: RequestType = new RequestType('cpptools/didSwitchHeaderSource'); const GetDiagnosticsRequest: RequestType = new RequestType('cpptools/getDiagnostics'); @@ -1310,7 +1314,12 @@ export class DefaultClient implements Client { private async init(rootUri: vscode.Uri | undefined, isFirstClient: boolean) { ui = getUI(); ui.bind(this); - await firstClientStarted; + if ((await firstClientStarted).wasShutdown) { + this.isSupported = false; + DefaultClient.isStarted.resolve(); + return; + } + try { const workspaceFolder: vscode.WorkspaceFolder | undefined = this.rootFolder; this.innerConfiguration = new configs.CppProperties(this, rootUri, workspaceFolder); @@ -1574,7 +1583,7 @@ export class DefaultClient implements Client { }; } - private async createLanguageClient(): Promise { + private async createLanguageClient(): Promise<{ wasShutdown: boolean }> { this.currentCaseSensitiveFileSupport = new PersistentWorkspaceState("CPP.currentCaseSensitiveFileSupport", false); let resetDatabase: boolean = false; const serverModule: string = getLanguageServerFileName(); @@ -1707,7 +1716,15 @@ export class DefaultClient implements Client { // Move initialization to a separate message, so we can see log output from it. // A request is used in order to wait for completion and ensure that no subsequent // higher priority message may be processed before the Initialization request. - await languageClient.sendRequest(InitializationRequest, cppInitializationParams); + const initializeResult = await languageClient.sendRequest(InitializationRequest, cppInitializationParams); + + // If the server requested shutdown, then reload with the failsafe (null) client. + if (initializeResult.shouldShutdown) { + await languageClient.stop(); + await clients.recreateClients(true); + } + + return { wasShutdown: initializeResult.shouldShutdown }; } public async sendDidChangeSettings(): Promise {