Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added system to store and query properties from the active C/C++ configuration #5453

Merged
merged 8 commits into from
Jun 15, 2020
10 changes: 10 additions & 0 deletions Extension/c_cpp_properties.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,16 @@
}
},
"additionalProperties": false
},
"properties": {
bugengine marked this conversation as resolved.
Show resolved Hide resolved
"type": "object",
"description": "Custom properties that can be queried through the command ${cpptools:activeConfigProperty}.",
"patternProperties": {
"(^.+$)": {
"type": "string"
}
},
"additionalProperties": false
}
},
"additionalProperties": false
Expand Down
14 changes: 14 additions & 0 deletions Extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,20 @@
"description": "%c_cpp.configuration.default.systemIncludePath.description%",
"scope": "machine-overridable"
},
"C_Cpp.default.properties": {
"type": [
"object",
"null"
],
"default": null,
"patternProperties": {
"(^.+$)": {
"type": "string"
}
},
"description": "%c_cpp.configuration.default.properties.description%",
"scope": "machine-overridable"
},
"C_Cpp.default.enableConfigurationSquiggles": {
"type": "boolean",
"default": true,
Expand Down
1 change: 1 addition & 0 deletions Extension/package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"c_cpp.configuration.default.browse.limitSymbolsToIncludedHeaders.description": "The value to use in a configuration if \"browse.limitSymbolsToIncludedHeaders\" is either not specified or set to \"${default}\".",
"c_cpp.configuration.default.systemIncludePath.description": "The value to use for the system include path. If set, it overrides the system include path acquired via \"compilerPath\" and \"compileCommands\" settings.",
"c_cpp.configuration.default.enableConfigurationSquiggles.description": "Controls whether the extension will report errors detected in c_cpp_properties.json.",
"c_cpp.configuration.default.properties.description": "The value to use in a configuration if \"property\" is not set, or the values to insert if \"${default}\" is present as a key in \"property\".",
"c_cpp.configuration.updateChannel.description": "Set to \"Insiders\" to automatically download and install the latest Insiders builds of the extension, which include upcoming features and bug fixes.",
"c_cpp.configuration.experimentalFeatures.description": "Controls whether \"experimental\" features are usable.",
"c_cpp.configuration.suggestSnippets.description": "If true, snippets are provided by the language server.",
Expand Down
6 changes: 6 additions & 0 deletions Extension/src/LanguageServer/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,7 @@ export interface Client {
toggleReferenceResultsView(): void;
setCurrentConfigName(configurationName: string): Thenable<void>;
getCurrentConfigName(): Thenable<string | undefined>;
getCurrentConfigProperty(propertyName: string): Thenable<string>;
getVcpkgInstalled(): Thenable<boolean>;
getVcpkgEnabled(): Thenable<boolean>;
getCurrentCompilerPathAndArgs(): Thenable<util.CompilerPathAndArgs | undefined>;
Expand Down Expand Up @@ -1778,6 +1779,10 @@ export class DefaultClient implements Client {
return this.queueTask(() => Promise.resolve(this.configuration.CurrentConfiguration?.name));
}

public getCurrentConfigProperty(propertyName: string): Thenable<string> {
return this.queueTask(() => Promise.resolve(this.configuration.CurrentConfiguration?.properties?.[propertyName] || ''));
}

public setCurrentConfigName(configurationName: string): Thenable<void> {
return this.queueTask(() => new Promise((resolve, reject) => {
let configurations: configs.Configuration[] = this.configuration.Configurations || [];
Expand Down Expand Up @@ -2658,6 +2663,7 @@ class NullClient implements Client {
toggleReferenceResultsView(): void {}
setCurrentConfigName(configurationName: string): Thenable<void> { return Promise.resolve(); }
getCurrentConfigName(): Thenable<string> { return Promise.resolve(""); }
getCurrentConfigProperty(propertyName: string): Thenable<string> { return Promise.resolve(""); }
getVcpkgInstalled(): Thenable<boolean> { return Promise.resolve(false); }
getVcpkgEnabled(): Thenable<boolean> { return Promise.resolve(false); }
getCurrentCompilerPathAndArgs(): Thenable<util.CompilerPathAndArgs | undefined> { return Promise.resolve(undefined); }
Expand Down
35 changes: 35 additions & 0 deletions Extension/src/LanguageServer/configurations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export interface Configuration {
forcedInclude?: string[];
configurationProvider?: string;
browse?: Browse;
properties?: {[key: string]: string};
}

export interface ConfigurationErrors {
Expand Down Expand Up @@ -123,6 +124,7 @@ export class CppProperties {
private vcpkgIncludes: string[] = [];
private vcpkgPathReady: boolean = false;
private defaultIntelliSenseMode?: string;
private defaultProperties?: { [key: string]: string };
private readonly configurationGlobPattern: string = "c_cpp_properties.json";
private disposables: vscode.Disposable[] = [];
private configurationsChanged = new vscode.EventEmitter<Configuration[]>();
Expand Down Expand Up @@ -328,6 +330,9 @@ export class CppProperties {
if (isUnset(settings.defaultIntelliSenseMode) || settings.defaultIntelliSenseMode === "") {
configuration.intelliSenseMode = this.defaultIntelliSenseMode;
}
if (isUnset(settings.defaultProperties) || settings.defaultProperties === {}) {
configuration.properties = this.defaultProperties;
}
}

private get ExtendedEnvironment(): Environment {
Expand Down Expand Up @@ -527,6 +532,25 @@ export class CppProperties {
return result;
}

private resolveDefaultsDictionary(entries: { [key: string] : string }, defaultValue: { [key: string] : string } | undefined, env: Environment): { [key: string] : string } {
let result: { [key: string] : string } = {};
for (const property in entries) {
if (property === "${default}") {
if (defaultValue) {
for (const defaultProperty in defaultValue) {
if (!(defaultProperty in entries))
{
result[defaultProperty] = util.resolveVariables(defaultValue[defaultProperty], env);
}
}
}
} else {
result[property] = util.resolveVariables(entries[property], env);
}
}
return result;
}

private resolveAndSplit(paths: string[] | undefined, defaultValue: string[] | undefined, env: Environment): string[] {
let result: string[] = [];
if (paths) {
Expand Down Expand Up @@ -572,6 +596,16 @@ export class CppProperties {
return util.resolveVariables(property, env);
}

private updateConfigurationStringDictionary(property: { [key: string]: string } | undefined, defaultValue: { [key: string]: string } | undefined, env: Environment): { [key: string]: string } | undefined {
if (!property || property === {}) {
property = defaultValue;
}
if (!property || property === {}) {
return undefined;
}
return this.resolveDefaultsDictionary(property, defaultValue, env);
}

private updateServerOnFolderSettingsChange(): void {
if (!this.configurationJson) {
return;
Expand All @@ -592,6 +626,7 @@ export class CppProperties {
configuration.cStandard = this.updateConfigurationString(configuration.cStandard, settings.defaultCStandard, env);
configuration.cppStandard = this.updateConfigurationString(configuration.cppStandard, settings.defaultCppStandard, env);
configuration.intelliSenseMode = this.updateConfigurationString(configuration.intelliSenseMode, settings.defaultIntelliSenseMode, env);
configuration.properties = this.updateConfigurationStringDictionary(configuration.properties, settings.defaultProperties, env);
configuration.configurationProvider = this.updateConfigurationString(configuration.configurationProvider, settings.defaultConfigurationProvider, env);

if (!configuration.browse) {
Expand Down
5 changes: 5 additions & 0 deletions Extension/src/LanguageServer/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -905,6 +905,7 @@ export function registerCommands(): void {
disposables.push(vscode.commands.registerCommand('C_Cpp.VcpkgClipboardInstallSuggested', onVcpkgClipboardInstallSuggested));
disposables.push(vscode.commands.registerCommand('C_Cpp.VcpkgOnlineHelpSuggested', onVcpkgOnlineHelpSuggested));
disposables.push(vscode.commands.registerCommand('cpptools.activeConfigName', onGetActiveConfigName));
disposables.push(vscode.commands.registerCommand('cpptools.activeConfigProperty', onGetActiveConfigProperty));
disposables.push(vscode.commands.registerCommand('cpptools.setActiveConfigName', onSetActiveConfigName));
getTemporaryCommandRegistrarInstance().executeDelayedCommands();
}
Expand Down Expand Up @@ -1167,6 +1168,10 @@ function onGetActiveConfigName(): Thenable<string | undefined> {
return clients.ActiveClient.getCurrentConfigName();
}

function onGetActiveConfigProperty(propertyName: string): Thenable<string> {
return clients.ActiveClient.getCurrentConfigProperty(propertyName);
}

function onLogDiagnostics(): void {
onActivationEvent();
clients.ActiveClient.logDiagnostics();
Expand Down
1 change: 1 addition & 0 deletions Extension/src/LanguageServer/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ export class CppSettings extends Settings {
public get defaultLimitSymbolsToIncludedHeaders(): boolean | undefined { return super.Section.get<boolean>("default.browse.limitSymbolsToIncludedHeaders"); }
public get defaultSystemIncludePath(): string[] | undefined { return super.Section.get<string[]>("default.systemIncludePath"); }
public get defaultEnableConfigurationSquiggles(): boolean | undefined { return super.Section.get<boolean>("default.enableConfigurationSquiggles"); }
public get defaultProperties(): { [key: string]: string } | undefined { return super.Section.get< { [key: string]: string } >("default.properties"); }
public get useBacktickCommandSubstitution(): boolean | undefined { return super.Section.get<boolean>("debugger.useBacktickCommandSubstitution"); }
public get codeFolding(): boolean { return super.Section.get<string>("codeFolding") === "Enabled"; }

Expand Down