Skip to content

Commit 8809e69

Browse files
browntariksean-mcmanus
authored andcommitted
Remove redundant variable resolution in handleSquiggles and fix error messaging for env and delimited paths under include paths in c_cpp_properties.json (#12188)
* remove redundant variable resolution * fix lint * remove resolveVariable redundancies * change when resolve and split happens * fix lint * Resolve error checking for environment vars and delimited paths * remove "path" from error messaging * Adjust error messaging * remove stray comment * refactor error messaging + minor fix * resolve lint * Fix multi path squiggle regression * Remove resolvedPath redundancies * Refactor error messaging and squiggling * Revert and improve error squiggling behavior * fix linting * properly proccess glob patterns + minor fixes * fix comment positions * Refactor error message + minor fix * Fix telemetry metric + minor fix
1 parent 7af5c40 commit 8809e69

File tree

1 file changed

+85
-40
lines changed

1 file changed

+85
-40
lines changed

Extension/src/LanguageServer/configurations.ts

Lines changed: 85 additions & 40 deletions
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
}

0 commit comments

Comments
 (0)