Skip to content

Commit 0fc52ed

Browse files
committed
Merge branch 'main' of https://github.com/Microsoft/vscode-cpptools into dev/spebl/otfdocs
2 parents 76000c7 + 05fbc0e commit 0fc52ed

File tree

12 files changed

+193
-89
lines changed

12 files changed

+193
-89
lines changed

Extension/CHANGELOG.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,24 @@
11
# C/C++ for Visual Studio Code Changelog
22

3-
## Version 1.23.0: October 24, 2024
3+
### Version 1.23.1: November 6, 2024
4+
### Bug Fixes
5+
* A potential fix for a crash during process shutdown (in `uv_run`). [#12668](https://github.com/microsoft/vscode-cpptools/issues/12668)
6+
* Fix a performance issue where some LSP requests would delay other LSP requests. [#12905](https://github.com/microsoft/vscode-cpptools/issues/12905)
7+
* A potential fix for a crash in cpptools (in `report_intellisense_results`).
8+
* Fix a random deadlock with `compiler_info::find_or_create`.
9+
* Fix a random deadlock with `handle_edits`.
10+
* Other internal fixes.
11+
12+
## Version 1.22.11: November 5, 2024
13+
### Bug Fixes
14+
* Fix system includes incorrectly being treated as non-system includes when specified with `-I`. [#12842](https://github.com/microsoft/vscode-cpptools/issues/12842)
15+
* Fix inactive region ranges when multi-byte UTF-8 characters are used. [#12879](https://github.com/microsoft/vscode-cpptools/issues/12879)
16+
* Fix formatting with `.editorconfig` files. [#12921](https://github.com/microsoft/vscode-cpptools/issues/12921)
17+
18+
## Version 1.23.0: October 29, 2024
419
### Enhancements
520
* Update to clang-format and clang-tidy 19.1.2. [#12824](https://github.com/microsoft/vscode-cpptools/issues/12824)
21+
* Enable `#cpp` with GitHub Copilot chat without `C_Cpp.experimentalFeatures` enabled. [PR #12898](https://github.com/microsoft/vscode-cpptools/pull/12898)
622

723
### Bug Fixes
824
* Fix some translation issues. [#7824](https://github.com/microsoft/vscode-cpptools/issues/7824), [#12439](https://github.com/microsoft/vscode-cpptools/issues/12439), [#12440](https://github.com/microsoft/vscode-cpptools/issues/12440), [#12441](https://github.com/microsoft/vscode-cpptools/issues/12441)

Extension/ThirdPartyNotices.txt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2429,6 +2429,7 @@ The notices below are from non-npm sources.
24292429
- ANTLR (http://www.antlr2.org/)
24302430
- C++11 Sublime Text Snippets (https://github.com/Rapptz/cpp-sublime-snippet)
24312431
- Clang (https://clang.llvm.org/)
2432+
- editorconfig-core-js (https://github.com/editorconfig/editorconfig-core-js)
24322433
- gcc-11/libgcc (https://packages.ubuntu.com/jammy/gcc-11-base)
24332434
- Guidelines Support Library (https://github.com/Microsoft/GSL)
24342435
- libc++ (https://libcxx.llvm.org/index.html)
@@ -2677,6 +2678,31 @@ mechanisms:
26772678
=========================================
26782679
END OF Clang NOTICES AND INFORMATION
26792680

2681+
%% editorconfig-core-js NOTICES AND INFORMATION BEGIN HERE
2682+
=========================================
2683+
Copyright © 2012 EditorConfig Team
2684+
2685+
Permission is hereby granted, free of charge, to any person obtaining a copy
2686+
of this software and associated documentation files (the “Software”), to deal
2687+
in the Software without restriction, including without limitation the rights
2688+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2689+
copies of the Software, and to permit persons to whom the Software is
2690+
furnished to do so, subject to the following conditions:
2691+
2692+
The above copyright notice and this permission notice shall be included in
2693+
all copies or substantial portions of the Software.
2694+
2695+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2696+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2697+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2698+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2699+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2700+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2701+
THE SOFTWARE.
2702+
2703+
=========================================
2704+
END OF editorconfig-core-js NOTICES AND INFORMATION
2705+
26802706
%% gcc-9/libgcc NOTICES AND INFORMATION BEGIN HERE
26812707
=========================================
26822708
The following runtime libraries are licensed under the terms of the

Extension/package.json

Lines changed: 3 additions & 4 deletions
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.23.0-main",
5+
"version": "1.23.1-main",
66
"publisher": "ms-vscode",
77
"icon": "LanguageCCPP_color_128x.png",
88
"readme": "README.md",
@@ -6522,13 +6522,12 @@
65226522
"translations-generate": "set NODE_OPTIONS=--no-experimental-fetch && gulp translations-generate",
65236523
"translations-import": "gulp translations-import",
65246524
"import-edge-strings": "ts-node -T ./.scripts/import_edge_strings.ts",
6525-
"prep:dts": "yarn verify dts --quiet || (npx vscode-dts dev && npx vscode-dts main)",
6525+
"prep:dts": "yarn verify dts --quiet || (npx @vscode/dts dev && npx @vscode/dts main)",
65266526
"build": "yarn prep:dts && echo [Building TypeScript code] && tsc --build tsconfig.json"
65276527
},
65286528
"devDependencies": {
65296529
"@octokit/rest": "^20.1.1",
65306530
"@types/glob": "^7.2.0",
6531-
"@types/minimatch": "^3.0.5",
65326531
"@types/mocha": "^10.0.6",
65336532
"@types/node": "^20.14.2",
65346533
"@types/node-fetch": "^2.6.11",
@@ -6580,7 +6579,7 @@
65806579
"comment-json": "^4.2.3",
65816580
"escape-string-regexp": "^2.0.0",
65826581
"glob": "^7.2.3",
6583-
"minimatch": "^3.0.5",
6582+
"minimatch": "^4.2.0",
65846583
"mkdirp": "^3.0.1",
65856584
"node-fetch": "^2.7.0",
65866585
"node-loader": "^2.0.0",

Extension/src/Debugger/configurationProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ export class DebugConfigurationProvider implements vscode.DebugConfigurationProv
331331

332332
// Run deploy steps
333333
if (config.deploySteps && config.deploySteps.length !== 0) {
334-
const codeVersion: number[] = vscode.version.split('.').map(num => parseInt(num, undefined));
334+
const codeVersion: number[] = util.getVsCodeVersion();
335335
if ((util.isNumber(codeVersion[0]) && codeVersion[0] < 1) || (util.isNumber(codeVersion[0]) && codeVersion[0] === 1 && util.isNumber(codeVersion[1]) && codeVersion[1] < 69)) {
336336
void logger.getOutputChannelLogger().showErrorMessage(localize("vs.code.1.69+.required", "'deploySteps' require VS Code 1.69+."));
337337
return undefined;

Extension/src/LanguageServer/client.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1307,6 +1307,12 @@ export class DefaultClient implements Client {
13071307

13081308
// Listen for messages from the language server.
13091309
this.registerNotifications();
1310+
1311+
// If a file is already open when we activate, sometimes we don't get any notifications about visible
1312+
// or active text editors, visible ranges, or text selection. As a workaround, we trigger
1313+
// onDidChangeVisibleTextEditors here.
1314+
const cppEditors: vscode.TextEditor[] = vscode.window.visibleTextEditors.filter(e => util.isCpp(e.document));
1315+
await this.onDidChangeVisibleTextEditors(cppEditors);
13101316
}
13111317

13121318
// update all client configurations
@@ -2603,7 +2609,8 @@ export class DefaultClient implements Client {
26032609
}
26042610
let foundGlobMatch: boolean = false;
26052611
for (const assoc in assocs) {
2606-
if (minimatch(filePath, assoc)) {
2612+
const matcher = new minimatch.Minimatch(assoc);
2613+
if (matcher.match(filePath)) {
26072614
foundGlobMatch = true;
26082615
break; // Assoc matched a glob pattern.
26092616
}

Extension/src/LanguageServer/configurations.ts

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ export class CppProperties {
138138
private configFileWatcherFallbackTime: Date = new Date(); // Used when file watching fails.
139139
private compileCommandsFile: vscode.Uri | undefined | null = undefined;
140140
private compileCommandsFileWatchers: fs.FSWatcher[] = [];
141-
private compileCommandsFileWatcherFallbackTime: Date = new Date(); // Used when file watching fails.
141+
private compileCommandsFileWatcherFallbackTime: Map<string, Date> = new Map<string, Date>(); // Used when file watching fails.
142142
private defaultCompilerPath: string | null = null;
143143
private knownCompilers?: KnownCompiler[];
144144
private defaultCStandard: string | null = null;
@@ -1093,6 +1093,10 @@ export class CppProperties {
10931093

10941094
if (configuration.compileCommands) {
10951095
configuration.compileCommands = this.resolvePath(configuration.compileCommands);
1096+
if (!this.compileCommandsFileWatcherFallbackTime.has(configuration.compileCommands)) {
1097+
// Start tracking the fallback time for a new path.
1098+
this.compileCommandsFileWatcherFallbackTime.set(configuration.compileCommands, new Date());
1099+
}
10961100
}
10971101

10981102
if (configuration.forcedInclude) {
@@ -1104,12 +1108,31 @@ export class CppProperties {
11041108
}
11051109
}
11061110

1111+
this.clearStaleCompileCommandsFileWatcherFallbackTimes();
11071112
this.updateCompileCommandsFileWatchers();
11081113
if (!this.configurationIncomplete) {
11091114
this.onConfigurationsChanged();
11101115
}
11111116
}
11121117

1118+
private clearStaleCompileCommandsFileWatcherFallbackTimes(): void {
1119+
// We need to keep track of relevant timestamps, so we cannot simply clear all entries.
1120+
// Instead, we clear entries that are no longer relevant.
1121+
const trackedCompileCommandsPaths: Set<string> = new Set();
1122+
this.configurationJson?.configurations.forEach((config: Configuration) => {
1123+
const path = this.resolvePath(config.compileCommands);
1124+
if (path.length > 0) {
1125+
trackedCompileCommandsPaths.add(path);
1126+
}
1127+
});
1128+
1129+
for (const path of this.compileCommandsFileWatcherFallbackTime.keys()) {
1130+
if (!trackedCompileCommandsPaths.has(path)) {
1131+
this.compileCommandsFileWatcherFallbackTime.delete(path);
1132+
}
1133+
}
1134+
}
1135+
11131136
private compileCommandsFileWatcherTimer?: NodeJS.Timeout;
11141137
private compileCommandsFileWatcherFiles: Set<string> = new Set<string>();
11151138

@@ -1948,7 +1971,7 @@ export class CppProperties {
19481971
compilerPath = checkPathExists.path;
19491972
}
19501973
if (!compilerPathExists) {
1951-
compilerMessage = localize('cannot.find2', "Cannot find \"{0}\".", compilerPath);
1974+
compilerMessage = localize('cannot.find', "Cannot find: {0}", compilerPath);
19521975
newSquiggleMetrics.PathNonExistent++;
19531976
}
19541977
if (compilerMessage) {
@@ -1975,7 +1998,7 @@ export class CppProperties {
19751998
dotConfigPath = checkPathExists.path;
19761999
}
19772000
if (!dotConfigPathExists) {
1978-
dotConfigMessage = localize('cannot.find2', "Cannot find \"{0}\".", dotConfigPath);
2001+
dotConfigMessage = localize('cannot.find', "Cannot find: {0}", dotConfigPath);
19792002
newSquiggleMetrics.PathNonExistent++;
19802003
} else if (dotConfigPath && !util.checkFileExistsSync(dotConfigPath)) {
19812004
dotConfigMessage = localize("path.is.not.a.file", "Path is not a file: {0}", dotConfigPath);
@@ -2083,7 +2106,7 @@ export class CppProperties {
20832106
} else {
20842107
badPath = `"${expandedPaths[0]}"`;
20852108
}
2086-
message = localize('cannot.find2', "Cannot find {0}", badPath);
2109+
message = localize('cannot.find', "Cannot find: {0}", badPath);
20872110
newSquiggleMetrics.PathNonExistent++;
20882111
} else {
20892112
// Check for file versus path mismatches.
@@ -2141,7 +2164,7 @@ export class CppProperties {
21412164
endOffset = curOffset + curMatch.length;
21422165
let message: string;
21432166
if (!pathExists) {
2144-
message = localize('cannot.find2', "Cannot find \"{0}\".", expandedPaths[0]);
2167+
message = localize('cannot.find', "Cannot find: {0}", expandedPaths[0]);
21452168
newSquiggleMetrics.PathNonExistent++;
21462169
const diagnostic: vscode.Diagnostic = new vscode.Diagnostic(
21472170
new vscode.Range(document.positionAt(envTextStartOffSet + curOffset),
@@ -2310,14 +2333,18 @@ export class CppProperties {
23102333
fs.stat(compileCommandsFile, (err, stats) => {
23112334
if (err) {
23122335
if (err.code === "ENOENT" && this.compileCommandsFile) {
2336+
this.compileCommandsFileWatchers.forEach((watcher: fs.FSWatcher) => watcher.close());
23132337
this.compileCommandsFileWatchers = []; // reset file watchers
23142338
this.onCompileCommandsChanged(compileCommandsFile);
23152339
this.compileCommandsFile = null; // File deleted
23162340
}
2317-
} else if (stats.mtime > this.compileCommandsFileWatcherFallbackTime) {
2318-
this.compileCommandsFileWatcherFallbackTime = new Date();
2319-
this.onCompileCommandsChanged(compileCommandsFile);
2320-
this.compileCommandsFile = vscode.Uri.file(compileCommandsFile); // File created.
2341+
} else {
2342+
const compileCommandsLastChanged: Date | undefined = this.compileCommandsFileWatcherFallbackTime.get(compileCommandsFile);
2343+
if (compileCommandsLastChanged !== undefined && stats.mtime > compileCommandsLastChanged) {
2344+
this.compileCommandsFileWatcherFallbackTime.set(compileCommandsFile, new Date());
2345+
this.onCompileCommandsChanged(compileCommandsFile);
2346+
this.compileCommandsFile = vscode.Uri.file(compileCommandsFile); // File created.
2347+
}
23212348
}
23222349
});
23232350
}

Extension/src/LanguageServer/editorConfig.ts

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
'use strict';
66

77
import * as fs from 'fs';
8+
import { Minimatch } from 'minimatch';
89
import * as path from 'path';
10+
import { isWindows } from '../constants';
911

1012
export const cachedEditorConfigSettings: Map<string, any> = new Map<string, any>();
1113

@@ -61,13 +63,25 @@ export function mapWrapToEditorConfig(value: string | undefined): string {
6163
return "never";
6264
}
6365

64-
function matchesSection(filePath: string, section: string): boolean {
65-
const fileName: string = path.basename(filePath);
66-
// Escape all regex special characters except '*' and '?'.
67-
// Convert wildcards '*' to '.*' and '?' to '.'.
68-
const sectionPattern = section.replace(/[.+^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*').replace(/\?/g, '.');
69-
const regex: RegExp = new RegExp(`^${sectionPattern}$`);
70-
return regex.test(fileName);
66+
export function matchesSection(pathPrefix: string, filePath: string, section: string): boolean {
67+
// The following code is copied from: https://github.com/editorconfig/editorconfig-core-js
68+
const matchOptions = { matchBase: true, dot: true };
69+
pathPrefix = pathPrefix.replace(/[?*+@!()|[\]{}]/g, '\\$&');
70+
pathPrefix = pathPrefix.replace(/^#/, '\\#');
71+
switch (section.indexOf('/')) {
72+
case -1:
73+
section = `**/${section}`;
74+
break;
75+
case 0:
76+
section = section.substring(1);
77+
break;
78+
default:
79+
break;
80+
}
81+
section = section.replace(/\\\\/g, '\\\\\\\\');
82+
section = section.replace(/\*\*/g, '{*,**/**/**}');
83+
const matcher = new Minimatch(`${pathPrefix}/${section}`, matchOptions);
84+
return matcher.match(filePath);
7185
}
7286

7387
function parseEditorConfigContent(content: string): Record<string, any> {
@@ -92,7 +106,17 @@ function parseEditorConfigContent(content: string): Record<string, any> {
92106
const [key, ...values] = line.split('=');
93107
if (key && values.length > 0) {
94108
const trimmedKey = key.trim();
95-
const value = values.join('=').trim();
109+
let value: any = values.join('=').trim();
110+
111+
// Convert boolean-like and numeric values.
112+
if (value === 'true') {
113+
value = true;
114+
} else if (value === 'false') {
115+
value = false;
116+
} else if (!isNaN(Number(value))) {
117+
value = Number(value);
118+
}
119+
96120
if (currentSection) {
97121
// Ensure the current section is initialized.
98122
if (!config[currentSection]) {
@@ -113,8 +137,12 @@ function getEditorConfig(filePath: string): any {
113137
let currentDir: string = path.dirname(filePath);
114138
const rootDir: string = path.parse(currentDir).root;
115139

140+
if (isWindows) {
141+
filePath = filePath.replace(/\\/g, '/');
142+
}
143+
116144
// Traverse from the file's directory to the root directory.
117-
for (;;) {
145+
for (; ;) {
118146
const editorConfigPath: string = path.join(currentDir, '.editorconfig');
119147
if (fs.existsSync(editorConfigPath)) {
120148
const configFileContent: string = fs.readFileSync(editorConfigPath, 'utf-8');
@@ -128,9 +156,14 @@ function getEditorConfig(filePath: string): any {
128156
};
129157
}
130158

159+
let currentDirForwardSlashes: string = currentDir;
160+
if (isWindows) {
161+
currentDirForwardSlashes = currentDir.replace(/\\/g, '/');
162+
}
163+
131164
// Match sections and combine configurations.
132165
Object.keys(configData).forEach((section: string) => {
133-
if (section !== '*' && matchesSection(filePath, section)) {
166+
if (section !== '*' && matchesSection(currentDirForwardSlashes, filePath, section)) {
134167
combinedConfig = {
135168
...combinedConfig,
136169
...configData[section]
@@ -139,7 +172,7 @@ function getEditorConfig(filePath: string): any {
139172
});
140173

141174
// Check if the current .editorconfig is the root.
142-
if (configData['*']?.root?.toLowerCase() === 'true') {
175+
if (configData['*']?.root) {
143176
break; // Stop searching after processing the root = true file.
144177
}
145178
}

Extension/src/LanguageServer/extension.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,15 @@ export async function activate(): Promise<void> {
255255
activeDocument = activeEditor.document;
256256
}
257257

258-
if (util.extensionContext && new CppSettings().experimentalFeatures) {
259-
const tool = vscode.lm.registerTool('cpptools-lmtool-configuration', new CppConfigurationLanguageModelTool());
260-
disposables.push(tool);
258+
if (util.extensionContext) {
259+
// lmTools wasn't stabilized until 1.95, but (as of October 2024)
260+
// cpptools can be installed on older versions of VS Code. See
261+
// https://github.com/microsoft/vscode-cpptools/blob/main/Extension/package.json#L14
262+
const version = util.getVsCodeVersion();
263+
if (version[0] > 1 || (version[0] === 1 && version[1] >= 95)) {
264+
const tool = vscode.lm.registerTool('cpptools-lmtool-configuration', new CppConfigurationLanguageModelTool());
265+
disposables.push(tool);
266+
}
261267
}
262268

263269
await registerRelatedFilesProvider();

0 commit comments

Comments
 (0)