Skip to content

Commit 1ed7c86

Browse files
authored
Merge pull request #13895 from microsoft/main
Merge for 1.27.3
2 parents b1ed550 + 854fecf commit 1ed7c86

File tree

10 files changed

+345
-136
lines changed

10 files changed

+345
-136
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
The documentation for c_cpp_properties.json has moved to https://code.visualstudio.com/docs/cpp/c-cpp-properties-schema-reference.
1+
The documentation for c_cpp_properties.json has moved to https://code.visualstudio.com/docs/cpp/customize-cpp-settings.

Extension/CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# C/C++ for Visual Studio Code Changelog
22

3+
## Version 1.27.3: September 3, 2025
4+
### Enhancements
5+
* Show a warning when too many files are processed in a workspace. [#10828](https://github.com/microsoft/vscode-cpptools/issues/10828)
6+
* Update GitHub Copilot APIs. [PR #13877](https://github.com/microsoft/vscode-cpptools/pull/13877)
7+
* Thank you for the contribution. [@dbaeumer (Dirk Bäumer)](https://github.com/dbaeumer)
8+
9+
### Bug Fixes
10+
* Fix input delays when editing `c_cpp_properties.json`. [#13591](https://github.com/microsoft/vscode-cpptools/issues/13591)
11+
* Fix non-recursive browse paths from configuration providers. [#13886](https://github.com/microsoft/vscode-cpptools/issues/13886)
12+
* Fix an IntelliSense process crash involving `requires` expressions and templates.
13+
* Fix an IntelliSense process crash with `class_has_mutable_member`.
14+
315
## Version 1.27.2: August 21, 2025
416
### Bug Fix
517
* Fix a crash regression with `__BASE_FILE__`. [#13866](https://github.com/microsoft/vscode-cpptools/issues/13866)

Extension/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "cpptools",
33
"displayName": "C/C++",
44
"description": "C/C++ IntelliSense, debugging, and code browsing.",
5-
"version": "1.27.2-main",
5+
"version": "1.27.3-main",
66
"publisher": "ms-vscode",
77
"icon": "LanguageCCPP_color_128x.png",
88
"readme": "README.md",

Extension/src/LanguageServer/client.ts

Lines changed: 106 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ import { CopilotCompletionContextFeatures, CopilotCompletionContextProvider } fr
5959
import { CustomConfigurationProvider1, getCustomConfigProviders, isSameProviderExtensionId } from './customProviders';
6060
import { DataBinding } from './dataBinding';
6161
import { cachedEditorConfigSettings, getEditorConfigSettings } from './editorConfig';
62-
import { CppSourceStr, clients, configPrefix, initializeIntervalTimer, updateLanguageConfigurations, usesCrashHandler, watchForCrashes } from './extension';
62+
import { CppSourceStr, clients, configPrefix, initializeIntervalTimer, isWritingCrashCallStack, updateLanguageConfigurations, usesCrashHandler, watchForCrashes } from './extension';
6363
import { LocalizeStringParams, getLocaleId, getLocalizedString } from './localization';
6464
import { PersistentFolderState, PersistentState, PersistentWorkspaceState } from './persistentState';
6565
import { RequestCancelled, ServerCancelled, createProtocolFilter } from './protocolFilter';
@@ -953,6 +953,8 @@ export class DefaultClient implements Client {
953953
public getShowConfigureIntelliSenseButton(): boolean { return this.showConfigureIntelliSenseButton; }
954954
public setShowConfigureIntelliSenseButton(show: boolean): void { this.showConfigureIntelliSenseButton = show; }
955955

956+
private lastInvokedLspMessage: string = ""; // e.g. cpptools/hover
957+
956958
/**
957959
* don't use this.rootFolder directly since it can be undefined
958960
*/
@@ -1688,7 +1690,6 @@ export class DefaultClient implements Client {
16881690
closed: () => {
16891691
languageClientCrashTimes.push(Date.now());
16901692
languageClientCrashedNeedsRestart = true;
1691-
telemetry.logLanguageServerEvent("languageClientCrash");
16921693
let restart: boolean = true;
16931694
if (languageClientCrashTimes.length < 5) {
16941695
void clients.recreateClients();
@@ -1702,6 +1703,26 @@ export class DefaultClient implements Client {
17021703
void clients.recreateClients();
17031704
}
17041705
}
1706+
1707+
// Wait 1 second to allow time for the file watcher to signal a crash call stack write has occurred.
1708+
setTimeout(() => {
1709+
telemetry.logLanguageServerEvent("languageClientCrash",
1710+
{
1711+
lastInvokedLspMessage: this.lastInvokedLspMessage
1712+
},
1713+
{
1714+
restarting: Number(restart),
1715+
writingCrashCallStack: Number(isWritingCrashCallStack),
1716+
initializingWorkspace: Number(this.model.isInitializingWorkspace.Value),
1717+
indexingWorkspace: Number(this.model.isIndexingWorkspace.Value),
1718+
parsingWorkspace: Number(this.model.isParsingWorkspace.Value),
1719+
parsingFiles: Number(this.model.isParsingFiles.Value),
1720+
updatingIntelliSense: Number(this.model.isUpdatingIntelliSense.Value),
1721+
runningCodeAnalysis: Number(this.model.isRunningCodeAnalysis.Value)
1722+
}
1723+
);
1724+
}, 1000);
1725+
17051726
const message: string = restart ? localize('server.crashed.restart', 'The language server crashed. Restarting...')
17061727
: localize('server.crashed2', 'The language server crashed 5 times in the last 3 minutes. It will not be restarted.');
17071728

@@ -1723,7 +1744,7 @@ export class DefaultClient implements Client {
17231744
languageClient = new LanguageClient(`cpptools`, serverOptions, clientOptions);
17241745
languageClient.onNotification(DebugProtocolNotification, logDebugProtocol);
17251746
languageClient.onNotification(DebugLogNotification, logLocalized);
1726-
languageClient.onNotification(LogTelemetryNotification, (e) => this.logTelemetry(e));
1747+
languageClient.onNotification(LogTelemetryNotification, (e) => void this.logTelemetry(e));
17271748
languageClient.onNotification(ShowMessageWindowNotification, showMessageWindow);
17281749
languageClient.registerProposedFeatures();
17291750
await languageClient.start();
@@ -2757,66 +2778,98 @@ export class DefaultClient implements Client {
27572778
}
27582779
}
27592780

2760-
private logTelemetry(notificationBody: TelemetryPayload): void {
2781+
private excessiveFilesWarningShown: boolean = false;
2782+
private async logTelemetry(notificationBody: TelemetryPayload): Promise<void> {
27612783
if (notificationBody.event === "includeSquiggles" && this.configurationProvider && notificationBody.properties) {
27622784
notificationBody.properties["providerId"] = this.configurationProvider;
27632785
}
2786+
2787+
const showExcessiveFilesWarning = new PersistentWorkspaceState<boolean>('CPP.showExcessiveFilesWarning', true);
2788+
if (!this.excessiveFilesWarningShown && showExcessiveFilesWarning.Value && notificationBody.event === 'ParsingStats') {
2789+
const filesDiscovered = notificationBody.metrics?.filesDiscovered ?? 0;
2790+
const parsableFiles = notificationBody.metrics?.parsableFiles ?? 0;
2791+
if (filesDiscovered > 250000 || parsableFiles > 100000) {
2792+
// According to telemetry, less than 3% of workspaces have this many files so it seems like a reasonable threshold.
2793+
2794+
const message = localize(
2795+
"parsing.stats.large.project",
2796+
'Enumerated {0} files with {1} C/C++ source files detected. You may want to consider excluding some files for better performance.',
2797+
filesDiscovered,
2798+
parsableFiles);
2799+
const learnMore = localize('learn.more', 'Learn More');
2800+
const dontShowAgain = localize('dont.show.again', 'Don\'t Show Again');
2801+
2802+
// We only want to show this once per session.
2803+
this.excessiveFilesWarningShown = true;
2804+
const response = await vscode.window.showInformationMessage(message, learnMore, dontShowAgain);
2805+
2806+
if (response === dontShowAgain) {
2807+
showExcessiveFilesWarning.Value = false;
2808+
} else if (response === learnMore) {
2809+
void vscode.commands.executeCommand('vscode.open', vscode.Uri.parse('https://go.microsoft.com/fwlink/?linkid=2333292'));
2810+
}
2811+
}
2812+
}
27642813
telemetry.logLanguageServerEvent(notificationBody.event, notificationBody.properties, notificationBody.metrics);
27652814
}
27662815

27672816
private async updateStatus(notificationBody: ReportStatusNotificationBody): Promise<void> {
27682817
const message: string = notificationBody.status;
27692818
util.setProgress(util.getProgressExecutableSuccess());
27702819
const testHook: TestHook = getTestHook();
2771-
if (message.endsWith("Idle")) {
2772-
const status: IntelliSenseStatus = { status: Status.Idle };
2773-
testHook.updateStatus(status);
2774-
} else if (message.endsWith("Parsing")) {
2775-
this.model.isParsingWorkspace.Value = true;
2776-
this.model.isInitializingWorkspace.Value = false;
2777-
this.model.isIndexingWorkspace.Value = false;
2778-
const status: IntelliSenseStatus = { status: Status.TagParsingBegun };
2779-
testHook.updateStatus(status);
2780-
} else if (message.endsWith("Initializing")) {
2781-
this.model.isInitializingWorkspace.Value = true;
2782-
this.model.isIndexingWorkspace.Value = false;
2783-
this.model.isParsingWorkspace.Value = false;
2784-
} else if (message.endsWith("Indexing")) {
2785-
this.model.isIndexingWorkspace.Value = true;
2786-
this.model.isInitializingWorkspace.Value = false;
2787-
this.model.isParsingWorkspace.Value = false;
2788-
} else if (message.endsWith("files")) {
2789-
this.model.isParsingFiles.Value = true;
2790-
} else if (message.endsWith("IntelliSense")) {
2791-
timeStamp = Date.now();
2792-
this.model.isUpdatingIntelliSense.Value = true;
2793-
const status: IntelliSenseStatus = { status: Status.IntelliSenseCompiling };
2794-
testHook.updateStatus(status);
2795-
} else if (message.endsWith("IntelliSense done")) {
2796-
getOutputChannelLogger().appendLineAtLevel(6, localize("update.intellisense.time", "Update IntelliSense time (sec): {0}", (Date.now() - timeStamp) / 1000));
2797-
this.model.isUpdatingIntelliSense.Value = false;
2798-
const status: IntelliSenseStatus = { status: Status.IntelliSenseReady };
2799-
testHook.updateStatus(status);
2800-
} else if (message.endsWith("Parsing done")) { // Tag Parser Ready
2801-
this.model.isParsingWorkspace.Value = false;
2802-
const status: IntelliSenseStatus = { status: Status.TagParsingDone };
2803-
testHook.updateStatus(status);
2804-
util.setProgress(util.getProgressParseRootSuccess());
2805-
} else if (message.endsWith("files done")) {
2806-
this.model.isParsingFiles.Value = false;
2807-
} else if (message.endsWith("Analysis")) {
2808-
this.model.isRunningCodeAnalysis.Value = true;
2809-
this.model.codeAnalysisTotal.Value = 1;
2810-
this.model.codeAnalysisProcessed.Value = 0;
2811-
} else if (message.endsWith("Analysis done")) {
2812-
this.model.isRunningCodeAnalysis.Value = false;
2813-
} else if (message.includes("Squiggles Finished - File name:")) {
2814-
const index: number = message.lastIndexOf(":");
2815-
const name: string = message.substring(index + 2);
2816-
const status: IntelliSenseStatus = { status: Status.IntelliSenseReady, filename: name };
2817-
testHook.updateStatus(status);
2818-
} else if (message.endsWith("No Squiggles")) {
2819-
util.setIntelliSenseProgress(util.getProgressIntelliSenseNoSquiggles());
2820+
if (message.startsWith("C_Cpp: ")) {
2821+
if (message.endsWith("Idle")) {
2822+
const status: IntelliSenseStatus = { status: Status.Idle };
2823+
testHook.updateStatus(status);
2824+
} else if (message.endsWith("Parsing")) {
2825+
this.model.isParsingWorkspace.Value = true;
2826+
this.model.isInitializingWorkspace.Value = false;
2827+
this.model.isIndexingWorkspace.Value = false;
2828+
const status: IntelliSenseStatus = { status: Status.TagParsingBegun };
2829+
testHook.updateStatus(status);
2830+
} else if (message.endsWith("Initializing")) {
2831+
this.model.isInitializingWorkspace.Value = true;
2832+
this.model.isIndexingWorkspace.Value = false;
2833+
this.model.isParsingWorkspace.Value = false;
2834+
} else if (message.endsWith("Indexing")) {
2835+
this.model.isIndexingWorkspace.Value = true;
2836+
this.model.isInitializingWorkspace.Value = false;
2837+
this.model.isParsingWorkspace.Value = false;
2838+
} else if (message.endsWith("files")) {
2839+
this.model.isParsingFiles.Value = true;
2840+
} else if (message.endsWith("IntelliSense")) {
2841+
timeStamp = Date.now();
2842+
this.model.isUpdatingIntelliSense.Value = true;
2843+
const status: IntelliSenseStatus = { status: Status.IntelliSenseCompiling };
2844+
testHook.updateStatus(status);
2845+
} else if (message.endsWith("IntelliSense done")) {
2846+
getOutputChannelLogger().appendLineAtLevel(6, localize("update.intellisense.time", "Update IntelliSense time (sec): {0}", (Date.now() - timeStamp) / 1000));
2847+
this.model.isUpdatingIntelliSense.Value = false;
2848+
const status: IntelliSenseStatus = { status: Status.IntelliSenseReady };
2849+
testHook.updateStatus(status);
2850+
} else if (message.endsWith("Parsing done")) { // Tag Parser Ready
2851+
this.model.isParsingWorkspace.Value = false;
2852+
const status: IntelliSenseStatus = { status: Status.TagParsingDone };
2853+
testHook.updateStatus(status);
2854+
util.setProgress(util.getProgressParseRootSuccess());
2855+
} else if (message.endsWith("files done")) {
2856+
this.model.isParsingFiles.Value = false;
2857+
} else if (message.endsWith("Analysis")) {
2858+
this.model.isRunningCodeAnalysis.Value = true;
2859+
this.model.codeAnalysisTotal.Value = 1;
2860+
this.model.codeAnalysisProcessed.Value = 0;
2861+
} else if (message.endsWith("Analysis done")) {
2862+
this.model.isRunningCodeAnalysis.Value = false;
2863+
} else if (message.includes("Squiggles Finished - File name:")) {
2864+
const index: number = message.lastIndexOf(":");
2865+
const name: string = message.substring(index + 2);
2866+
const status: IntelliSenseStatus = { status: Status.IntelliSenseReady, filename: name };
2867+
testHook.updateStatus(status);
2868+
} else if (message.endsWith("No Squiggles")) {
2869+
util.setIntelliSenseProgress(util.getProgressIntelliSenseNoSquiggles());
2870+
}
2871+
} else if (message.includes("/")) {
2872+
this.lastInvokedLspMessage = message;
28202873
}
28212874
}
28222875

0 commit comments

Comments
 (0)