Skip to content

Commit efdc8e9

Browse files
authored
Merge pull request #12235 from microsoft/seanmcm/1_20_2_cherryPicks2
Cherry-picks for 1.20.2
2 parents 1d2bd10 + 9f020e9 commit efdc8e9

File tree

4 files changed

+101
-52
lines changed

4 files changed

+101
-52
lines changed

Extension/CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# C/C++ for Visual Studio Code Changelog
22

3-
## Version 1.20.2: April 17, 2024
3+
## Version 1.20.2: April 22, 2024
44
### Bug Fixes
5+
* Fix non-existent relative path variables not showing a warning in `c_cpp_properties.json` (and other related issues). [#12089](https://github.com/microsoft/vscode-cpptools/issues/12089)
56
* Fix duplicate URIs in calls to provideConfigurations. [#12177](https://github.com/microsoft/vscode-cpptools/issues/12177)
67
* Fix a crash and deadlock with a high `C_Cpp.loggingLevel`. [#12194](https://github.com/microsoft/vscode-cpptools/issues/12194)
78
* Fix handling of `-iquote` for code analysis and `#include` completions. [#12198](https://github.com/microsoft/vscode-cpptools/issues/12198)

Extension/src/LanguageServer/client.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -2001,8 +2001,8 @@ export class DefaultClient implements Client {
20012001
}
20022002
try {
20032003
DefaultClient.isStarted.reset();
2004-
const status = await this.provideCustomConfigurationAsync(docUri, requestFile, replaceExisting, provider);
2005-
telemetry.logLanguageServerEvent('provideCustomConfiguration', { providerId, status });
2004+
const resultCode = await this.provideCustomConfigurationAsync(docUri, requestFile, replaceExisting, provider);
2005+
telemetry.logLanguageServerEvent('provideCustomConfiguration', { providerId, resultCode });
20062006
} finally {
20072007
onFinished();
20082008
DefaultClient.isStarted.resolve();

Extension/src/LanguageServer/configurations.ts

+85-40
Original file line numberDiff line numberDiff line change
@@ -1838,9 +1838,9 @@ export class CppProperties {
18381838
curText = curText.substring(0, nextNameStart2);
18391839
}
18401840
if (this.prevSquiggleMetrics.get(currentConfiguration.name) === undefined) {
1841-
this.prevSquiggleMetrics.set(currentConfiguration.name, { PathNonExistent: 0, PathNotAFile: 0, PathNotADirectory: 0, CompilerPathMissingQuotes: 0, CompilerModeMismatch: 0 });
1841+
this.prevSquiggleMetrics.set(currentConfiguration.name, { PathNonExistent: 0, PathNotAFile: 0, PathNotADirectory: 0, CompilerPathMissingQuotes: 0, CompilerModeMismatch: 0, MultiplePathsNotAllowed: 0 });
18421842
}
1843-
const newSquiggleMetrics: { [key: string]: number } = { PathNonExistent: 0, PathNotAFile: 0, PathNotADirectory: 0, CompilerPathMissingQuotes: 0, CompilerModeMismatch: 0 };
1843+
const newSquiggleMetrics: { [key: string]: number } = { PathNonExistent: 0, PathNotAFile: 0, PathNotADirectory: 0, CompilerPathMissingQuotes: 0, CompilerModeMismatch: 0, MultiplePathsNotAllowed: 0 };
18441844
const isWindows: boolean = os.platform() === 'win32';
18451845

18461846
// TODO: Add other squiggles.
@@ -1867,7 +1867,7 @@ export class CppProperties {
18671867
}
18681868

18691869
// Check for path-related squiggles.
1870-
let paths: string[] = [];
1870+
const paths: string[] = [];
18711871
let compilerPath: string | undefined;
18721872
for (const pathArray of [ currentConfiguration.browse ? currentConfiguration.browse.path : undefined,
18731873
currentConfiguration.includePath, currentConfiguration.macFrameworkPath ]) {
@@ -1895,10 +1895,7 @@ export class CppProperties {
18951895
compilerPath = currentConfiguration.compilerPath;
18961896
}
18971897

1898-
// Resolve and split any environment variables
1899-
paths = this.resolveAndSplit(paths, undefined, this.ExtendedEnvironment);
1900-
compilerPath = util.resolveVariables(compilerPath, this.ExtendedEnvironment).trim();
1901-
compilerPath = this.resolvePath(compilerPath);
1898+
compilerPath = this.resolvePath(compilerPath).trim();
19021899

19031900
// Get the start/end for properties that are file-only.
19041901
const forcedIncludeStart: number = curText.search(/\s*\"forcedInclude\"\s*:\s*\[/);
@@ -1961,8 +1958,7 @@ export class CppProperties {
19611958
let dotConfigMessage: string | undefined;
19621959

19631960
dotConfigPath = currentConfiguration.dotConfig;
1964-
dotConfigPath = util.resolveVariables(dotConfigPath, this.ExtendedEnvironment).trim();
1965-
dotConfigPath = this.resolvePath(dotConfigPath);
1961+
dotConfigPath = this.resolvePath(dotConfigPath).trim();
19661962
// does not try resolve if the dotConfig property is empty
19671963
dotConfigPath = dotConfigPath !== '' ? dotConfigPath : undefined;
19681964

@@ -2001,25 +1997,6 @@ export class CppProperties {
20011997
continue;
20021998
}
20031999

2004-
let resolvedPath: string = this.resolvePath(curPath);
2005-
if (!resolvedPath) {
2006-
continue;
2007-
}
2008-
let pathExists: boolean = true;
2009-
if (this.rootUri) {
2010-
const checkPathExists: any = util.checkPathExistsSync(resolvedPath, this.rootUri.fsPath + path.sep, isWindows, false);
2011-
pathExists = checkPathExists.pathExists;
2012-
resolvedPath = checkPathExists.path;
2013-
}
2014-
// Normalize path separators.
2015-
if (path.sep === "/") {
2016-
resolvedPath = resolvedPath.replace(/\\/g, path.sep);
2017-
} else {
2018-
resolvedPath = resolvedPath.replace(/\//g, path.sep);
2019-
}
2020-
2021-
// Iterate through the text and apply squiggles.
2022-
20232000
// Escape the path string for literal use in a regular expression
20242001
// Need to escape any quotes to match the original text
20252002
let escapedPath: string = curPath.replace(/"/g, '\\"');
@@ -2030,6 +2007,42 @@ export class CppProperties {
20302007
const pattern: RegExp = new RegExp(`"[^"]*?(?<="|;)${escapedPath}(?="|;).*?"`, "g");
20312008
const configMatches: string[] | null = curText.match(pattern);
20322009

2010+
const expandedPaths: string[] = this.resolveAndSplit([curPath], undefined, this.ExtendedEnvironment, true, true);
2011+
const incorrectExpandedPaths: string[] = [];
2012+
2013+
if (expandedPaths.length <= 0) {
2014+
continue;
2015+
}
2016+
2017+
if (this.rootUri) {
2018+
for (const [index, expandedPath] of expandedPaths.entries()) {
2019+
if (expandedPath.includes("${workspaceFolder}")) {
2020+
expandedPaths[index] = this.resolvePath(expandedPath, false);
2021+
} else {
2022+
expandedPaths[index] = this.resolvePath(expandedPath);
2023+
}
2024+
2025+
const checkPathExists: any = util.checkPathExistsSync(expandedPaths[index], this.rootUri.fsPath + path.sep, isWindows, false);
2026+
if (!checkPathExists.pathExists) {
2027+
// If there are multiple paths, store any non-existing paths to squiggle later on.
2028+
incorrectExpandedPaths.push(expandedPaths[index]);
2029+
}
2030+
}
2031+
}
2032+
2033+
const pathExists: boolean = incorrectExpandedPaths.length === 0;
2034+
2035+
for (const [index, expandedPath] of expandedPaths.entries()) {
2036+
// Normalize path separators.
2037+
if (path.sep === "/") {
2038+
expandedPaths[index] = expandedPath.replace(/\\/g, path.sep);
2039+
} else {
2040+
expandedPaths[index] = expandedPath.replace(/\//g, path.sep);
2041+
}
2042+
}
2043+
2044+
// Iterate through the text and apply squiggles.
2045+
20332046
let globPath: boolean = false;
20342047
const asteriskPosition = curPath.indexOf("*");
20352048
if (asteriskPosition !== -1) {
@@ -2041,6 +2054,7 @@ export class CppProperties {
20412054
}
20422055
}
20432056
}
2057+
20442058
if (configMatches && !globPath) {
20452059
let curOffset: number = 0;
20462060
let endOffset: number = 0;
@@ -2050,29 +2064,57 @@ export class CppProperties {
20502064
if (curOffset >= compilerPathStart && curOffset <= compilerPathEnd) {
20512065
continue;
20522066
}
2053-
let message: string;
2067+
let message: string = "";
20542068
if (!pathExists) {
20552069
if (curOffset >= forcedIncludeStart && curOffset <= forcedeIncludeEnd
2056-
&& !path.isAbsolute(resolvedPath)) {
2070+
&& !path.isAbsolute(expandedPaths[0])) {
20572071
continue; // Skip the error, because it could be resolved recursively.
20582072
}
2059-
message = localize('cannot.find2', "Cannot find \"{0}\".", resolvedPath);
2073+
let badPath = "";
2074+
if (incorrectExpandedPaths.length > 0) {
2075+
badPath = incorrectExpandedPaths.map(s => `"${s}"`).join(', ');
2076+
} else {
2077+
badPath = `"${expandedPaths[0]}"`;
2078+
}
2079+
message = localize('cannot.find2', "Cannot find {0}", badPath);
20602080
newSquiggleMetrics.PathNonExistent++;
20612081
} else {
20622082
// Check for file versus path mismatches.
20632083
if ((curOffset >= forcedIncludeStart && curOffset <= forcedeIncludeEnd) ||
2064-
(curOffset >= compileCommandsStart && curOffset <= compileCommandsEnd)) {
2065-
if (util.checkFileExistsSync(resolvedPath)) {
2066-
continue;
2084+
(curOffset >= compileCommandsStart && curOffset <= compileCommandsEnd)) {
2085+
if (expandedPaths.length > 1) {
2086+
message = localize("multiple.paths.not.allowed", "Multiple paths are not allowed.");
2087+
newSquiggleMetrics.MultiplePathsNotAllowed++;
2088+
} else {
2089+
const resolvedPath = this.resolvePath(expandedPaths[0]);
2090+
if (util.checkFileExistsSync(resolvedPath)) {
2091+
continue;
2092+
}
2093+
2094+
message = localize("path.is.not.a.file", "Path is not a file: {0}", expandedPaths[0]);
2095+
newSquiggleMetrics.PathNotAFile++;
20672096
}
2068-
message = localize("path.is.not.a.file", "Path is not a file: {0}", resolvedPath);
2069-
newSquiggleMetrics.PathNotAFile++;
20702097
} else {
2071-
if (util.checkDirectoryExistsSync(resolvedPath)) {
2098+
const mismatchedPaths: string[] = [];
2099+
for (const expandedPath of expandedPaths) {
2100+
const resolvedPath = this.resolvePath(expandedPath);
2101+
if (!util.checkDirectoryExistsSync(resolvedPath)) {
2102+
mismatchedPaths.push(expandedPath);
2103+
}
2104+
}
2105+
2106+
let badPath = "";
2107+
if (mismatchedPaths.length > 1) {
2108+
badPath = mismatchedPaths.map(s => `"${s}"`).join(', ');
2109+
message = localize('paths.are.not.directories', "Paths are not directories: {0}", badPath);
2110+
newSquiggleMetrics.PathNotADirectory++;
2111+
} else if (mismatchedPaths.length === 1) {
2112+
badPath = `"${mismatchedPaths[0]}"`;
2113+
message = localize('path.is.not.a.directory', "Path is not a directory: {0}", badPath);
2114+
newSquiggleMetrics.PathNotADirectory++;
2115+
} else {
20722116
continue;
20732117
}
2074-
message = localize("path.is.not.a.directory", "Path is not a directory: {0}", resolvedPath);
2075-
newSquiggleMetrics.PathNotADirectory++;
20762118
}
20772119
}
20782120
const diagnostic: vscode.Diagnostic = new vscode.Diagnostic(
@@ -2092,7 +2134,7 @@ export class CppProperties {
20922134
endOffset = curOffset + curMatch.length;
20932135
let message: string;
20942136
if (!pathExists) {
2095-
message = localize('cannot.find2', "Cannot find \"{0}\".", resolvedPath);
2137+
message = localize('cannot.find2', "Cannot find \"{0}\".", expandedPaths[0]);
20962138
newSquiggleMetrics.PathNonExistent++;
20972139
const diagnostic: vscode.Diagnostic = new vscode.Diagnostic(
20982140
new vscode.Range(document.positionAt(envTextStartOffSet + curOffset),
@@ -2128,6 +2170,9 @@ export class CppProperties {
21282170
if (newSquiggleMetrics.CompilerModeMismatch !== this.prevSquiggleMetrics.get(currentConfiguration.name)?.CompilerModeMismatch) {
21292171
changedSquiggleMetrics.CompilerModeMismatch = newSquiggleMetrics.CompilerModeMismatch;
21302172
}
2173+
if (newSquiggleMetrics.MultiplePathsNotAllowed !== this.prevSquiggleMetrics.get(currentConfiguration.name)?.MultiplePathsNotAllowed) {
2174+
changedSquiggleMetrics.MultiplePathsNotAllowed = newSquiggleMetrics.MultiplePathsNotAllowed;
2175+
}
21312176
if (Object.keys(changedSquiggleMetrics).length > 0) {
21322177
telemetry.logLanguageServerEvent("ConfigSquiggles", undefined, changedSquiggleMetrics);
21332178
}

Extension/src/LanguageServer/extension.ts

+12-9
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ const localize: nls.LocalizeFunc = nls.loadMessageBundle();
3636
export const CppSourceStr: string = "C/C++";
3737
export const configPrefix: string = "C/C++: ";
3838

39-
let prevCrashFile: string;
39+
let prevMacCrashFile: string;
40+
let prevCppCrashFile: string;
4041
export let clients: ClientCollection;
4142
let activeDocument: vscode.TextDocument | undefined;
4243
let ui: LanguageStatusUI;
@@ -914,7 +915,7 @@ function onShowRefCommand(arg?: TreeNode): void {
914915

915916
function reportMacCrashes(): void {
916917
if (process.platform === "darwin") {
917-
prevCrashFile = "";
918+
prevMacCrashFile = "";
918919
const home: string = os.homedir();
919920
const crashFolder: string = path.resolve(home, "Library/Logs/DiagnosticReports");
920921
fs.stat(crashFolder, (err) => {
@@ -932,10 +933,10 @@ function reportMacCrashes(): void {
932933
if (event !== "rename") {
933934
return;
934935
}
935-
if (!filename || filename === prevCrashFile) {
936+
if (!filename || filename === prevMacCrashFile) {
936937
return;
937938
}
938-
prevCrashFile = filename;
939+
prevMacCrashFile = filename;
939940
if (!filename.startsWith("cpptools")) {
940941
return;
941942
}
@@ -964,7 +965,7 @@ export function usesCrashHandler(): boolean {
964965

965966
export function watchForCrashes(crashDirectory: string): void {
966967
if (crashDirectory !== "") {
967-
prevCrashFile = "";
968+
prevCppCrashFile = "";
968969
fs.stat(crashDirectory, (err) => {
969970
const crashObject: Record<string, string> = {};
970971
if (err?.code) {
@@ -980,10 +981,10 @@ export function watchForCrashes(crashDirectory: string): void {
980981
if (event !== "rename") {
981982
return;
982983
}
983-
if (!filename || filename === prevCrashFile) {
984+
if (!filename || filename === prevCppCrashFile) {
984985
return;
985986
}
986-
prevCrashFile = filename;
987+
prevCppCrashFile = filename;
987988
if (!filename.startsWith("cpptools")) {
988989
return;
989990
}
@@ -1125,7 +1126,7 @@ async function handleCrashFileRead(crashDirectory: string, crashFile: string, er
11251126

11261127
const lines: string[] = data.split("\n");
11271128
let addressData: string = ".\n.";
1128-
data = crashFile + "\n";
1129+
data = (crashFile.startsWith("cpptools-srv") ? "cpptools-srv.txt" : crashFile) + "\n";
11291130
const filtPath: string | null = which.sync("c++filt", { nothrow: true });
11301131
const isMac: boolean = process.platform === "darwin";
11311132
const startStr: string = isMac ? " _" : "<";
@@ -1202,7 +1203,9 @@ async function handleCrashFileRead(crashDirectory: string, crashFile: string, er
12021203
logCppCrashTelemetry(data, addressData);
12031204

12041205
await util.deleteFile(path.resolve(crashDirectory, crashFile)).catch(logAndReturn.undefined);
1205-
void util.deleteDirectory(crashDirectory).catch(logAndReturn.undefined);
1206+
if (crashFile === "cpptools.txt") {
1207+
void util.deleteDirectory(crashDirectory).catch(logAndReturn.undefined);
1208+
}
12061209
}
12071210

12081211
export function deactivate(): Thenable<void> {

0 commit comments

Comments
 (0)