Skip to content

Commit 5f68e6a

Browse files
authored
Fix issues with didOpen synchronization (#10442)
1 parent 93dc373 commit 5f68e6a

File tree

8 files changed

+69
-97
lines changed

8 files changed

+69
-97
lines changed

Extension/src/LanguageServer/Providers/documentSymbolProvider.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,7 @@ export class DocumentSymbolProvider implements vscode.DocumentSymbolProvider {
5757
const client: Client = clients.getClientFor(document.uri);
5858
if (client instanceof DefaultClient) {
5959
const defaultClient: DefaultClient = <DefaultClient>client;
60-
if (!defaultClient.TrackedDocuments.has(document)) {
61-
processDelayedDidOpen(document);
62-
}
63-
await defaultClient.awaitUntilLanguageClientReady();
60+
await client.requestWhenReady(() => processDelayedDidOpen(document));
6461
const params: GetDocumentSymbolRequestParams = {
6562
uri: document.uri.toString()
6663
};

Extension/src/LanguageServer/Providers/foldingRangeProvider.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* ------------------------------------------------------------------------------------------ */
55
import * as vscode from 'vscode';
66
import { DefaultClient, GetFoldingRangesParams, GetFoldingRangesRequest, FoldingRangeKind, GetFoldingRangesResult, CppFoldingRange } from '../client';
7+
import { processDelayedDidOpen } from '../extension';
78
import { CppSettings } from '../settings';
89

910
export class FoldingRangeProvider implements vscode.FoldingRangeProvider {
@@ -22,7 +23,7 @@ export class FoldingRangeProvider implements vscode.FoldingRangeProvider {
2223
const params: GetFoldingRangesParams = {
2324
uri: document.uri.toString()
2425
};
25-
await this.client.awaitUntilLanguageClientReady();
26+
await this.client.requestWhenReady(() => processDelayedDidOpen(document));
2627
const response: GetFoldingRangesResult = await this.client.languageClient.sendRequest(GetFoldingRangesRequest, params, token);
2728
if (token.isCancellationRequested || response.ranges === undefined) {
2829
throw new vscode.CancellationError();

Extension/src/LanguageServer/Providers/inlayHintProvider.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import * as vscode from 'vscode';
66
import { DefaultClient, openFileVersions } from '../client';
77
import { Position, RequestType } from 'vscode-languageclient';
88
import { CppSettings } from '../settings';
9+
import { processDelayedDidOpen } from '../extension';
910

1011
interface GetInlayHintsParams {
1112
uri: string;
@@ -54,7 +55,7 @@ export class InlayHintsProvider implements vscode.InlayHintsProvider {
5455

5556
public async provideInlayHints(document: vscode.TextDocument, range: vscode.Range,
5657
token: vscode.CancellationToken): Promise<vscode.InlayHint[] | undefined> {
57-
await this.client.awaitUntilLanguageClientReady();
58+
await this.client.requestWhenReady(() => processDelayedDidOpen(document));
5859
const uriString: string = document.uri.toString();
5960

6061
// Get results from cache if available.

Extension/src/LanguageServer/Providers/semanticTokensProvider.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* ------------------------------------------------------------------------------------------ */
55
import * as vscode from 'vscode';
66
import { DefaultClient, GetSemanticTokensParams, GetSemanticTokensRequest, openFileVersions, GetSemanticTokensResult, semanticTokensLegend } from '../client';
7+
import { processDelayedDidOpen } from '../extension';
78

89
export class SemanticTokensProvider implements vscode.DocumentSemanticTokensProvider {
910
private client: DefaultClient;
@@ -17,7 +18,7 @@ export class SemanticTokensProvider implements vscode.DocumentSemanticTokensProv
1718
}
1819

1920
public async provideDocumentSemanticTokens(document: vscode.TextDocument, token: vscode.CancellationToken): Promise<vscode.SemanticTokens> {
20-
await this.client.awaitUntilLanguageClientReady();
21+
await this.client.requestWhenReady(() => processDelayedDidOpen(document));
2122
const uriString: string = document.uri.toString();
2223
// First check the semantic token cache to see if we already have results for that file and version
2324
const cache: [number, vscode.SemanticTokens] | undefined = this.tokenCaches.get(uriString);

Extension/src/LanguageServer/client.ts

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -734,11 +734,12 @@ export interface Client {
734734
getVcpkgEnabled(): Thenable<boolean>;
735735
getCurrentCompilerPathAndArgs(): Thenable<util.CompilerPathAndArgs | undefined>;
736736
getKnownCompilers(): Thenable<configs.KnownCompiler[] | undefined>;
737-
takeOwnership(document: vscode.TextDocument): void;
737+
takeOwnership(document: vscode.TextDocument): Promise<void>;
738+
sendDidOpen(document: vscode.TextDocument): Promise<void>;
738739
queueTask<T>(task: () => Thenable<T>): Promise<T>;
739-
requestWhenReady<T>(request: () => Thenable<T>): Thenable<T>;
740-
notifyWhenLanguageClientReady(notify: () => void): void;
741-
awaitUntilLanguageClientReady(): Thenable<void>;
740+
requestWhenReady<T>(request: () => Thenable<T>): Promise<T>;
741+
notifyWhenLanguageClientReady<T>(notify: () => T): Promise<T>;
742+
awaitUntilLanguageClientReady(): Promise<void>;
742743
requestSwitchHeaderSource(rootUri: vscode.Uri, fileName: string): Thenable<string>;
743744
activeDocumentChanged(document: vscode.TextDocument): Promise<void>;
744745
restartIntelliSenseForFile(document: vscode.TextDocument): Promise<void>;
@@ -1934,7 +1935,13 @@ export class DefaultClient implements Client {
19341935
* that it knows about the file, as well as adding it to this client's set of
19351936
* tracked documents.
19361937
*/
1937-
public takeOwnership(document: vscode.TextDocument): void {
1938+
public async takeOwnership(document: vscode.TextDocument): Promise<void> {
1939+
this.trackedDocuments.add(document);
1940+
this.updateActiveDocumentTextOptions();
1941+
await this.requestWhenReady(() => this.sendDidOpen(document));
1942+
}
1943+
1944+
public async sendDidOpen(document: vscode.TextDocument): Promise<void> {
19381945
const params: DidOpenTextDocumentParams = {
19391946
textDocument: {
19401947
uri: document.uri.toString(),
@@ -1943,9 +1950,7 @@ export class DefaultClient implements Client {
19431950
text: document.getText()
19441951
}
19451952
};
1946-
this.updateActiveDocumentTextOptions();
1947-
this.notifyWhenLanguageClientReady(() => this.languageClient.sendNotification(DidOpenNotification, params));
1948-
this.trackedDocuments.add(document);
1953+
await this.languageClient.sendNotification(DidOpenNotification, params);
19491954
}
19501955

19511956
/**
@@ -2016,7 +2021,7 @@ export class DefaultClient implements Client {
20162021
});
20172022
}
20182023

2019-
public requestWhenReady<T>(request: () => Thenable<T>): Thenable<T> {
2024+
public requestWhenReady<T>(request: () => Thenable<T>): Promise<T> {
20202025
return this.queueTask(request);
20212026
}
20222027

@@ -2027,7 +2032,7 @@ export class DefaultClient implements Client {
20272032
return this.queueTask(task);
20282033
}
20292034

2030-
public awaitUntilLanguageClientReady(): Thenable<void> {
2035+
public awaitUntilLanguageClientReady(): Promise<void> {
20312036
const task: () => Thenable<void> = () => new Promise<void>(resolve => {
20322037
resolve();
20332038
});
@@ -2116,7 +2121,7 @@ export class DefaultClient implements Client {
21162121
if (fileName === ".editorconfig") {
21172122
cachedEditorConfigSettings.clear();
21182123
cachedEditorConfigLookups.clear();
2119-
await this.updateActiveDocumentTextOptions();
2124+
this.updateActiveDocumentTextOptions();
21202125
}
21212126
if (fileName === ".clang-format" || fileName === "_clang-format") {
21222127
cachedEditorConfigLookups.clear();
@@ -2144,7 +2149,7 @@ export class DefaultClient implements Client {
21442149
if (fileName === ".editorconfig") {
21452150
cachedEditorConfigSettings.clear();
21462151
cachedEditorConfigLookups.clear();
2147-
await this.updateActiveDocumentTextOptions();
2152+
this.updateActiveDocumentTextOptions();
21482153
}
21492154
if (dotIndex !== -1) {
21502155
const ext: string = uri.fsPath.substring(dotIndex + 1);
@@ -2456,7 +2461,7 @@ export class DefaultClient implements Client {
24562461
return this.languageClient.sendRequest(QueryCompilerDefaultsRequest, params);
24572462
}
24582463

2459-
private async updateActiveDocumentTextOptions(): Promise<void> {
2464+
private updateActiveDocumentTextOptions(): void {
24602465
const editor: vscode.TextEditor | undefined = vscode.window.activeTextEditor;
24612466
if (editor?.document?.uri.scheme === "file"
24622467
&& (editor.document.languageId === "c"
@@ -2493,7 +2498,7 @@ export class DefaultClient implements Client {
24932498
* notifications to the language server
24942499
*/
24952500
public async activeDocumentChanged(document: vscode.TextDocument): Promise<void> {
2496-
await this.updateActiveDocumentTextOptions();
2501+
this.updateActiveDocumentTextOptions();
24972502
await this.awaitUntilLanguageClientReady();
24982503
this.languageClient.sendNotification(ActiveDocumentChangeNotification, this.languageClient.code2ProtocolConverter.asTextDocumentIdentifier(document));
24992504
}
@@ -3417,11 +3422,12 @@ class NullClient implements Client {
34173422
getVcpkgEnabled(): Thenable<boolean> { return Promise.resolve(false); }
34183423
getCurrentCompilerPathAndArgs(): Thenable<util.CompilerPathAndArgs | undefined> { return Promise.resolve(undefined); }
34193424
getKnownCompilers(): Thenable<configs.KnownCompiler[] | undefined> { return Promise.resolve([]); }
3420-
takeOwnership(document: vscode.TextDocument): void { }
3425+
takeOwnership(document: vscode.TextDocument): Promise<void> { return Promise.resolve(); }
3426+
sendDidOpen(document: vscode.TextDocument): Promise<void> { return Promise.resolve(); }
34213427
queueTask<T>(task: () => Thenable<T>): Promise<T> { return Promise.resolve(task()); }
3422-
requestWhenReady<T>(request: () => Thenable<T>): Thenable<T> { return request(); }
3423-
notifyWhenLanguageClientReady(notify: () => void): void { }
3424-
awaitUntilLanguageClientReady(): Thenable<void> { return Promise.resolve(); }
3428+
requestWhenReady<T>(request: () => Thenable<T>): Promise<T> { return Promise.resolve(request()); }
3429+
notifyWhenLanguageClientReady<T>(notify: () => T): Promise<T> { return Promise.resolve(notify()); }
3430+
awaitUntilLanguageClientReady(): Promise<void> { return Promise.resolve(); }
34253431
requestSwitchHeaderSource(rootUri: vscode.Uri, fileName: string): Thenable<string> { return Promise.resolve(""); }
34263432
activeDocumentChanged(document: vscode.TextDocument): Promise<void> { return Promise.resolve(); }
34273433
restartIntelliSenseForFile(document: vscode.TextDocument): Promise<void> { return Promise.resolve(); }

Extension/src/LanguageServer/configurations.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,6 @@ export class CppProperties {
253253
this.isCppPropertiesJsonVisible = true;
254254
if (!wasVisible) {
255255
this.handleSquiggles();
256-
257256
}
258257
}
259258
});

Extension/src/LanguageServer/extension.ts

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ function onDidChangeTextEditorSelection(event: vscode.TextEditorSelectionChangeE
324324
clients.ActiveClient.selectionChanged(makeCpptoolsRange(event.selections[0]));
325325
}
326326

327-
export function processDelayedDidOpen(document: vscode.TextDocument): boolean {
327+
export async function processDelayedDidOpen(document: vscode.TextDocument): Promise<boolean> {
328328
const client: Client = clients.getClientFor(document.uri);
329329
if (client) {
330330
// Log warm start.
@@ -333,28 +333,17 @@ export function processDelayedDidOpen(document: vscode.TextDocument): boolean {
333333
// If not yet tracked, process as a newly opened file. (didOpen is sent to server in client.takeOwnership()).
334334
clients.timeTelemetryCollector.setDidOpenTime(document.uri);
335335
client.TrackedDocuments.add(document);
336-
const finishDidOpen = (doc: vscode.TextDocument) => {
337-
client.provideCustomConfiguration(doc.uri, undefined);
338-
client.notifyWhenLanguageClientReady(() => {
339-
client.takeOwnership(doc);
340-
client.onDidOpenTextDocument(doc);
341-
});
342-
};
343-
let languageChanged: boolean = false;
344336
// Work around vscode treating ".C" or ".H" as c, by adding this file name to file associations as cpp
345337
if (document.languageId === "c" && shouldChangeFromCToCpp(document)) {
346338
const baseFileName: string = path.basename(document.fileName);
347339
const mappingString: string = baseFileName + "@" + document.fileName;
348340
client.addFileAssociations(mappingString, "cpp");
349341
client.sendDidChangeSettings();
350-
vscode.languages.setTextDocumentLanguage(document, "cpp").then((newDoc: vscode.TextDocument) => {
351-
finishDidOpen(newDoc);
352-
});
353-
languageChanged = true;
354-
}
355-
if (!languageChanged) {
356-
finishDidOpen(document);
342+
document = await vscode.languages.setTextDocumentLanguage(document, "cpp");
357343
}
344+
await client.provideCustomConfiguration(document.uri, undefined);
345+
client.onDidOpenTextDocument(document);
346+
await client.sendDidOpen(document);
358347
return true;
359348
}
360349
}
@@ -364,12 +353,11 @@ export function processDelayedDidOpen(document: vscode.TextDocument): boolean {
364353

365354
function onDidChangeVisibleTextEditors(editors: readonly vscode.TextEditor[]): void {
366355
// Process delayed didOpen for any visible editors we haven't seen before
367-
editors.forEach(editor => {
356+
editors.forEach(async (editor) => {
368357
if ((editor.document.uri.scheme === "file") && (editor.document.languageId === "c" || editor.document.languageId === "cpp" || editor.document.languageId === "cuda-cpp")) {
369-
if (!processDelayedDidOpen(editor.document)) {
370-
const client: Client = clients.getClientFor(editor.document.uri);
371-
client.onDidChangeVisibleTextEditor(editor);
372-
}
358+
const client: Client = clients.getClientFor(editor.document.uri);
359+
await client.requestWhenReady(() => processDelayedDidOpen(editor.document));
360+
client.onDidChangeVisibleTextEditor(editor);
373361
}
374362
});
375363
}

0 commit comments

Comments
 (0)