Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 47 additions & 12 deletions Extension/src/LanguageServer/configurations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ interface ConfigurationJson {

export class CppProperties {
private propertiesFile: vscode.Uri = null;
private workspaceRoot: string;
private readonly configFolder: string;
private configurationJson: ConfigurationJson = null;
private currentConfigurationIndex: PersistentFolderState<number>;
Expand All @@ -141,6 +142,7 @@ export class CppProperties {
console.assert(rootPath !== undefined);
this.currentConfigurationIndex = new PersistentFolderState<number>("CppProperties.currentConfigurationIndex", -1, rootPath);
this.configFolder = path.join(rootPath, ".vscode");
this.workspaceRoot = rootPath;
this.resetToDefaultSettings(this.currentConfigurationIndex.Value === -1);

let configFilePath: string = path.join(this.configFolder, "c_cpp_properties.json");
Expand Down Expand Up @@ -295,31 +297,64 @@ export class CppProperties {
this.onSelectionChanged();
}

private resolveAndSplit(paths: string[] | undefined): string[] {
private expandPath(path1: string): Promise<string[]> {
return new Promise<string[]>((resolve, reject) => {
let index: number = path1.indexOf("/*/");
if (index >= 0) {
let paths: string[] = [];
let basePath: string = path1.substr(0, index).replace("${workspaceRoot}", this.workspaceRoot);
let remainingPath: string = path1.substr(index + 3);
try {
let items: string[] = fs.readdirSync(basePath);
items.forEach(directory => {
let potentialPath: string = path.join(basePath, directory, remainingPath);
try {
let stats: fs.Stats = fs.statSync(potentialPath.endsWith("*") ? potentialPath.substr(0, potentialPath.length - 1) : potentialPath);
if (stats && stats.isDirectory()) {
paths.push(potentialPath.replace(this.workspaceRoot, "${workspaceRoot}"));
}
} catch {
// potentialPath is not a valid path. Ignore it.
}
});
} catch {
// basePath is not a valid path. Ignore it.
}
resolve(paths);
} else {
resolve([path1]);
}
});
}

private resolveAndSplit(paths: string[]): Promise<string[]> {
let promises: Promise<void>[] = [];
let result: string[] = [];
if (paths) {
paths.forEach(entry => {
let entries: string[] = util.resolveVariables(entry).split(";").filter(e => e);
result = result.concat(entries);
paths.forEach(entry => {
let entries: string[] = util.resolveVariables(entry).split(";").filter(e => e);
entries.forEach(path => {
promises.push(this.expandPath(path).then(paths => {
result = result.concat(paths);
}));
});
}
return result;
});
return Promise.all(promises).then(() => result);
}

private updateServerOnFolderSettingsChange(): void {
private async updateServerOnFolderSettingsChange(): Promise<void> {
for (let i: number = 0; i < this.configurationJson.configurations.length; i++) {
let configuration: Configuration = this.configurationJson.configurations[i];
if (configuration.includePath) {
configuration.includePath = this.resolveAndSplit(configuration.includePath);
configuration.includePath = await this.resolveAndSplit(configuration.includePath);
}
if (configuration.browse && configuration.browse.path) {
configuration.browse.path = this.resolveAndSplit(configuration.browse.path);
configuration.browse.path = await this.resolveAndSplit(configuration.browse.path);
}
if (configuration.macFrameworkPath) {
configuration.macFrameworkPath = this.resolveAndSplit(configuration.macFrameworkPath);
configuration.macFrameworkPath = await this.resolveAndSplit(configuration.macFrameworkPath);
}
if (configuration.forcedInclude) {
configuration.forcedInclude = this.resolveAndSplit(configuration.forcedInclude);
configuration.forcedInclude = await this.resolveAndSplit(configuration.forcedInclude);
}
if (configuration.compileCommands) {
configuration.compileCommands = util.resolveVariables(configuration.compileCommands);
Expand Down