Skip to content

Commit b96737a

Browse files
authored
Add support for selecting a default compiler (#10165)
1 parent c4d68fd commit b96737a

File tree

8 files changed

+234
-38
lines changed

8 files changed

+234
-38
lines changed

Extension/package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
"onCommand:C_Cpp.RestartIntelliSenseForFile",
5757
"onCommand:C_Cpp.ConfigurationEditJSON",
5858
"onCommand:C_Cpp.ConfigurationEditUI",
59+
"onCommand:C_Cpp.selectDefaultCompiler",
5960
"onCommand:C_Cpp.ConfigurationSelect",
6061
"onCommand:C_Cpp.ConfigurationProviderSelect",
6162
"onCommand:C_Cpp.CreateDeclarationOrDefinition",
@@ -2941,6 +2942,11 @@
29412942
"title": "%c_cpp.command.configurationEditUI.title%",
29422943
"category": "C/C++"
29432944
},
2945+
{
2946+
"command": "C_Cpp.selectDefaultCompiler",
2947+
"title": "%c_cpp.command.selectDefaultCompiler.title%",
2948+
"category": "C/C++"
2949+
},
29442950
{
29452951
"command": "C_Cpp.SwitchHeaderSource",
29462952
"title": "%c_cpp.command.switchHeaderSource.title%",

Extension/package.nls.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"c_cpp.command.configurationProviderSelect.title": "Change Configuration Provider...",
1212
"c_cpp.command.configurationEditJSON.title": "Edit Configurations (JSON)",
1313
"c_cpp.command.configurationEditUI.title": "Edit Configurations (UI)",
14+
"c_cpp.command.selectDefaultCompiler.title": "Select Default Compiler",
1415
"c_cpp.command.switchHeaderSource.title": "Switch Header/Source",
1516
"c_cpp.command.enableErrorSquiggles.title": "Enable Error Squiggles",
1617
"c_cpp.command.disableErrorSquiggles.title": "Disable Error Squiggles",

Extension/src/LanguageServer/client.ts

Lines changed: 175 additions & 16 deletions
Large diffs are not rendered by default.

Extension/src/LanguageServer/configurations.ts

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { setTimeout } from 'timers';
2121
import * as which from 'which';
2222
import { Version, WorkspaceBrowseConfiguration } from 'vscode-cpptools';
2323
import { getOutputChannelLogger } from '../logger';
24-
24+
import { compilerPaths } from './client';
2525
nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })();
2626
const localize: nls.LocalizeFunc = nls.loadMessageBundle();
2727

@@ -103,6 +103,8 @@ export interface Browse {
103103
export interface KnownCompiler {
104104
path: string;
105105
isC: boolean;
106+
isTrusted: boolean; // May be used in the future for build tasks.
107+
isCL: boolean;
106108
}
107109

108110
export interface CompilerDefaults {
@@ -115,6 +117,7 @@ export interface CompilerDefaults {
115117
frameworks: string[];
116118
windowsSdkVersion: string;
117119
intelliSenseMode: string;
120+
trustedCompilerFound: boolean;
118121
}
119122

120123
export class CppProperties {
@@ -157,6 +160,7 @@ export class CppProperties {
157160
// Any time the default settings are parsed and assigned to `this.configurationJson`,
158161
// we want to track when the default includes have been added to it.
159162
private configurationIncomplete: boolean = true;
163+
trustedCompilerFound: boolean = false;
160164

161165
constructor(rootUri?: vscode.Uri, workspaceFolder?: vscode.WorkspaceFolder) {
162166
this.rootUri = rootUri;
@@ -206,18 +210,11 @@ export class CppProperties {
206210
return result;
207211
}
208212

209-
public set CompilerDefaults(compilerDefaults: CompilerDefaults) {
210-
this.defaultCompilerPath = compilerDefaults.compilerPath;
211-
this.knownCompilers = compilerDefaults.knownCompilers;
212-
this.defaultCStandard = compilerDefaults.cStandard;
213-
this.defaultCppStandard = compilerDefaults.cppStandard;
214-
this.defaultIncludes = compilerDefaults.includes;
215-
this.defaultFrameworks = compilerDefaults.frameworks;
216-
this.defaultWindowsSdkVersion = compilerDefaults.windowsSdkVersion;
217-
this.defaultIntelliSenseMode = compilerDefaults.intelliSenseMode;
213+
public setupConfigurations(): void {
218214

219215
// defaultPaths is only used when there isn't a c_cpp_properties.json, but we don't send the configuration changed event
220216
// to the language server until the default include paths and frameworks have been sent.
217+
221218
const configFilePath: string = path.join(this.configFolder, "c_cpp_properties.json");
222219
if (this.rootUri !== null && fs.existsSync(configFilePath)) {
223220
this.propertiesFile = vscode.Uri.file(configFilePath);
@@ -273,7 +270,7 @@ export class CppProperties {
273270
const savedDocWorkspaceFolder: vscode.WorkspaceFolder | undefined = vscode.workspace.getWorkspaceFolder(doc.uri);
274271
const notifyingWorkspaceFolder: vscode.WorkspaceFolder | undefined = vscode.workspace.getWorkspaceFolder(vscode.Uri.file(settingsPath));
275272
if ((!savedDocWorkspaceFolder && vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 0 && notifyingWorkspaceFolder === vscode.workspace.workspaceFolders[0])
276-
|| savedDocWorkspaceFolder === notifyingWorkspaceFolder) {
273+
|| savedDocWorkspaceFolder === notifyingWorkspaceFolder) {
277274
let fileType: string | undefined;
278275
const documentPath: string = doc.uri.fsPath.toLowerCase();
279276
if (documentPath.endsWith("cmakelists.txt")) {
@@ -298,6 +295,17 @@ export class CppProperties {
298295

299296
this.handleConfigurationChange();
300297
}
298+
public set CompilerDefaults(compilerDefaults: CompilerDefaults) {
299+
this.defaultCompilerPath = compilerDefaults.compilerPath;
300+
this.knownCompilers = compilerDefaults.knownCompilers;
301+
this.defaultCStandard = compilerDefaults.cStandard;
302+
this.defaultCppStandard = compilerDefaults.cppStandard;
303+
this.defaultIncludes = compilerDefaults.includes;
304+
this.defaultFrameworks = compilerDefaults.frameworks;
305+
this.defaultWindowsSdkVersion = compilerDefaults.windowsSdkVersion;
306+
this.defaultIntelliSenseMode = compilerDefaults.intelliSenseMode;
307+
this.trustedCompilerFound = compilerDefaults.trustedCompilerFound;
308+
}
301309

302310
public get VcpkgInstalled(): boolean {
303311
return this.vcpkgIncludes.length > 0;
@@ -857,7 +865,7 @@ export class CppProperties {
857865
configuration.compilerPath = this.updateConfigurationString(configuration.compilerPath, settings.defaultCompilerPath, env, true);
858866
configuration.compilerPathIsExplicit = configuration.compilerPathIsExplicit || settings.defaultCompilerPath !== undefined;
859867
if (configuration.compilerPath === undefined) {
860-
if (!!this.defaultCompilerPath) {
868+
if (!!this.defaultCompilerPath && this.trustedCompilerFound) {
861869
// If no config value yet set for these, pick up values from the defaults, but don't consider them explicit.
862870
configuration.compilerPath = this.defaultCompilerPath;
863871
if (!configuration.cStandard && !!this.defaultCStandard) {
@@ -883,6 +891,9 @@ export class CppProperties {
883891
configuration.macFrameworkPath = this.defaultFrameworks;
884892
}
885893
}
894+
} else {
895+
// add compiler to list of trusted compilers
896+
util.addTrustedCompiler(compilerPaths, configuration.compilerPath);
886897
}
887898
} else {
888899
// However, if compileCommands are used and compilerPath is explicitly set, it's still necessary to resolve variables in it.

Extension/src/LanguageServer/extension.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,7 @@ export function registerCommands(enabled: boolean): void {
387387
commandDisposables.length = 0;
388388
commandDisposables.push(vscode.commands.registerCommand('C_Cpp.SwitchHeaderSource', enabled ? onSwitchHeaderSource : onDisabledCommand));
389389
commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ResetDatabase', enabled ? onResetDatabase : onDisabledCommand));
390+
commandDisposables.push(vscode.commands.registerCommand('C_Cpp.selectDefaultCompiler', enabled ? selectDefaultCompiler : onDisabledCommand));
390391
commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ConfigurationSelect', enabled ? onSelectConfiguration : onDisabledCommand));
391392
commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ConfigurationProviderSelect', enabled ? onSelectConfigurationProvider : onDisabledCommand));
392393
commandDisposables.push(vscode.commands.registerCommand('C_Cpp.ConfigurationEditJSON', enabled ? onEditConfigurationJSON : onDisabledCommand));
@@ -595,9 +596,13 @@ function onResetDatabase(): void {
595596
clients.ActiveClient.resetDatabase();
596597
}
597598

599+
function selectDefaultCompiler(): void {
600+
clients.ActiveClient.promptSelectCompiler(true);
601+
}
602+
598603
function onSelectConfiguration(): void {
599604
if (!isFolderOpen()) {
600-
vscode.window.showInformationMessage(localize("configuration.select.first", 'Open a folder first to select a configuration'));
605+
vscode.window.showInformationMessage(localize("configuration.select.first", 'Open a folder first to select a configuration.'));
601606
} else {
602607
// This only applies to the active client. You cannot change the configuration for
603608
// a client that is not active since that client's UI will not be visible.
@@ -607,7 +612,7 @@ function onSelectConfiguration(): void {
607612

608613
function onSelectConfigurationProvider(): void {
609614
if (!isFolderOpen()) {
610-
vscode.window.showInformationMessage(localize("configuration.provider.select.first", 'Open a folder first to select a configuration provider'));
615+
vscode.window.showInformationMessage(localize("configuration.provider.select.first", 'Open a folder first to select a configuration provider.'));
611616
} else {
612617
selectClient().then(client => client.handleConfigurationProviderSelectCommand(), rejected => {});
613618
}

Extension/src/LanguageServer/settings.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -964,6 +964,9 @@ export class OtherSettings {
964964
public set filesAssociations(value: any) {
965965
vscode.workspace.getConfiguration("files").update("associations", value, vscode.ConfigurationTarget.Workspace);
966966
}
967+
public set defaultCompiler(value: string) {
968+
vscode.workspace.getConfiguration("C_Cpp.default").update("compilerPath", value, vscode.ConfigurationTarget.Global);
969+
}
967970
public get filesExclude(): vscode.WorkspaceConfiguration | undefined { return vscode.workspace.getConfiguration("files", this.resource).get("exclude"); }
968971
public get filesAutoSaveAfterDelay(): boolean { return vscode.workspace.getConfiguration("files").get("autoSave") === "afterDelay"; }
969972
public get editorInlayHintsEnabled(): boolean { return vscode.workspace.getConfiguration("editor.inlayHints").get<string>("enabled") !== "off"; }

Extension/src/common.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -874,17 +874,25 @@ export async function renameAsync(oldName: string, newName: string): Promise<voi
874874
});
875875
}
876876

877-
export function promptForReloadWindowDueToSettingsChange(): void {
878-
promptReloadWindow(localize("reload.workspace.for.changes", "Reload the workspace for the settings change to take effect."));
877+
export async function promptForReloadWindowDueToSettingsChange(): Promise<void> {
878+
await promptReloadWindow(localize("reload.workspace.for.changes", "Reload the workspace for the settings change to take effect."));
879879
}
880880

881-
export function promptReloadWindow(message: string): void {
881+
export async function promptReloadWindow(message: string): Promise<void> {
882882
const reload: string = localize("reload.string", "Reload");
883-
vscode.window.showInformationMessage(message, reload).then((value?: string) => {
884-
if (value === reload) {
885-
vscode.commands.executeCommand("workbench.action.reloadWindow");
886-
}
887-
});
883+
const value: string | undefined = await vscode.window.showInformationMessage(message, reload);
884+
if (value === reload) {
885+
vscode.commands.executeCommand("workbench.action.reloadWindow");
886+
}
887+
}
888+
889+
export async function addTrustedCompiler(compilers: string[], path: string): Promise<string[]> {
890+
// Detect duplicate paths or invalid paths.
891+
if (compilers.includes(path) || path === null || path === undefined) {
892+
return compilers;
893+
}
894+
compilers.push(path);
895+
return compilers;
888896
}
889897

890898
export function createTempFileWithPostfix(postfix: string): Promise<tmp.FileResult> {

Extension/src/nativeStrings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,9 @@
177177
"text": "+%d specializations",
178178
"hint": "Refers to C++ template specializations. This is part of a description indicating there are N additional specializations of a function. %d is replaced with that number."
179179
},
180+
"compiler": {
181+
"text": "Note: IntelliSense is not fully configured. Use the 'Select Default Compiler' command to finish configuration."
182+
},
180183
"expands_to": "Expands to:",
181184
"attention_label": "Attention:",
182185
"author_label": "Author:",

0 commit comments

Comments
 (0)