Skip to content

Commit f809a81

Browse files
Dynamic debug config + Telemetry (#8876)
1 parent 9ea7328 commit f809a81

File tree

9 files changed

+353
-329
lines changed

9 files changed

+353
-329
lines changed

Extension/package.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@
7575
"onCommand:C_Cpp.RunCodeAnalysisOnOpenFiles",
7676
"onCommand:C_Cpp.RunCodeAnalysisOnAllFiles",
7777
"onCommand:C_Cpp.ClearCodeAnalysisSquiggles",
78-
"onDebugInitialConfigurations",
7978
"onDebugResolve:cppdbg",
8079
"onDebugResolve:cppvsdbg",
8180
"workspaceContains:/.vscode/c_cpp_properties.json",
@@ -259,7 +258,7 @@
259258
"owner": "cpptools",
260259
"fileLocation": [
261260
"autoDetect",
262-
"${workspaceFolder}"
261+
"{$cwd}"
263262
],
264263
"pattern": {
265264
"regexp": "^(.*?):(\\d+):(\\d*):?\\s+(?:fatal\\s+)?(warning|error):\\s+(.*)$",
@@ -2763,7 +2762,6 @@
27632762
"configurationAttributes": {
27642763
"launch": {
27652764
"type": "object",
2766-
"default": {},
27672765
"required": [
27682766
"program"
27692767
],
@@ -3438,7 +3436,6 @@
34383436
"configurationAttributes": {
34393437
"launch": {
34403438
"type": "object",
3441-
"default": {},
34423439
"required": [
34433440
"program",
34443441
"cwd"

Extension/package.nls.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@
211211
"c_cpp.configuration.debugger.useBacktickCommandSubstitution.markdownDescription": { "message": "If `true`, debugger shell command substitution will use obsolete backtick ``(`)``.", "comment": [ "Markdown text between `` should not be translated or localized (they represent literal text) and the capitalization, spacing, and punctuation (including the ``) should not be altered." ] },
212212
"c_cpp.contributes.views.cppReferencesView.title": "C/C++: Other references results.",
213213
"c_cpp.contributes.viewsWelcome.contents": { "message": "To learn more about launch.json, see [Configuring C/C++ debugging](https://code.visualstudio.com/docs/cpp/launch-json-reference).", "comment": [ "Markdown text between () should not be altered: https://en.wikipedia.org/wiki/Markdown" ] },
214-
"c_cpp.configuration.debugShortcut.description": "Show icon for 'Debug and Run' in shortcut menu bar",
214+
"c_cpp.configuration.debugShortcut.description": "Show the Run and Debug play button in the editor title bar for C++ files",
215215
"c_cpp.debuggers.pipeTransport.description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the MI-enabled debugger backend executable (such as gdb).",
216216
"c_cpp.debuggers.pipeTransport.default.pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'.",
217217
"c_cpp.debuggers.pipeTransport.default.debuggerPath": "The full path to the debugger on the target machine, for example /usr/bin/gdb.",

Extension/src/Debugger/configurationProvider.ts

Lines changed: 306 additions & 284 deletions
Large diffs are not rendered by default.

Extension/src/Debugger/configurations.ts

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,26 @@
55

66
import * as os from 'os';
77
import * as nls from 'vscode-nls';
8+
import { configPrefix } from '../LanguageServer/extension';
89

910
nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })();
1011
const localize: nls.LocalizeFunc = nls.loadMessageBundle();
1112

1213
export enum DebuggerType {
13-
cppvsdbg,
14-
cppdbg
14+
cppvsdbg = "cppvsdbg",
15+
cppdbg = "cppdbg",
16+
all = "all"
17+
}
18+
19+
export enum DebuggerEvent {
20+
debugPanel = "debugPanel",
21+
launchPlayButton = "launchPlayButton"
1522
}
1623

1724
export enum TaskConfigStatus {
1825
recentlyUsed = "Recently Used Task",
19-
configured = "Configured Task",
20-
detected = "Detected Task"
26+
configured = "Configured Task", // The tasks that are configured in tasks.json file.
27+
detected = "Detected Task" // The tasks that are available based on detected compilers.
2128
}
2229

2330
export interface IConfigurationSnippet {
@@ -89,7 +96,6 @@ export interface IConfiguration {
8996
}
9097

9198
abstract class Configuration implements IConfiguration {
92-
public snippetPrefix = "C/C++: ";
9399

94100
public executable: string;
95101
public pipeProgram: string;
@@ -122,7 +128,7 @@ export class MIConfigurations extends Configuration {
122128
this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalProperties)}` : ""]);
123129

124130
return {
125-
"label": this.snippetPrefix + name,
131+
"label": configPrefix + name,
126132
"description": localize("launch.with", "Launch with {0}.", this.MIMode).replace(/\"/g, "\\\""),
127133
"bodyText": body.trim(),
128134
"isInitialConfiguration": true,
@@ -140,7 +146,7 @@ export class MIConfigurations extends Configuration {
140146
this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalProperties)}` : ""]);
141147

142148
return {
143-
"label": this.snippetPrefix + name,
149+
"label": configPrefix + name,
144150
"description": localize("attach.with", "Attach with {0}.", this.MIMode).replace(/\"/g, "\\\""),
145151
"bodyText": body.trim(),
146152
"debuggerType": DebuggerType.cppdbg
@@ -162,7 +168,7 @@ export class PipeTransportConfigurations extends Configuration {
162168
}`, [this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalProperties)}` : ""]);
163169

164170
return {
165-
"label": this.snippetPrefix + name,
171+
"label": configPrefix + name,
166172
"description": localize("pipe.launch.with", "Pipe Launch with {0}.", this.MIMode).replace(/\"/g, "\\\""),
167173
"bodyText": body.trim(),
168174
"debuggerType": DebuggerType.cppdbg
@@ -180,7 +186,7 @@ export class PipeTransportConfigurations extends Configuration {
180186
\t"MIMode": "${this.MIMode}"{0}
181187
}`, [this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalProperties)}` : ""]);
182188
return {
183-
"label": this.snippetPrefix + name,
189+
"label": configPrefix + name,
184190
"description": localize("pipe.attach.with", "Pipe Attach with {0}.", this.MIMode).replace(/\"/g, "\\\""),
185191
"bodyText": body.trim(),
186192
"debuggerType": DebuggerType.cppdbg
@@ -200,7 +206,7 @@ export class WindowsConfigurations extends Configuration {
200206
}`;
201207

202208
return {
203-
"label": this.snippetPrefix + name,
209+
"label": configPrefix + name,
204210
"description": localize("launch.with.vs.debugger", "Launch with the Visual Studio C/C++ debugger.").replace(/\"/g, "\\\""),
205211
"bodyText": body.trim(),
206212
"isInitialConfiguration": true,
@@ -218,7 +224,7 @@ export class WindowsConfigurations extends Configuration {
218224
}`;
219225

220226
return {
221-
"label": this.snippetPrefix + name,
227+
"label": configPrefix + name,
222228
"description": localize("attach.with.vs.debugger", "Attach to a process with the Visual Studio C/C++ debugger.").replace(/\"/g, "\\\""),
223229
"bodyText": body.trim(),
224230
"debuggerType": DebuggerType.cppvsdbg
@@ -241,7 +247,7 @@ export class WSLConfigurations extends Configuration {
241247
}`, [this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalProperties)}` : ""]);
242248

243249
return {
244-
"label": this.snippetPrefix + name,
250+
"label": configPrefix + name,
245251
"description": localize("launch.bash.windows", "Launch in Bash on Windows using {0}.", this.MIMode).replace(/\"/g, "\\\""),
246252
"bodyText": body.trim(),
247253
"debuggerType": DebuggerType.cppdbg
@@ -258,7 +264,7 @@ export class WSLConfigurations extends Configuration {
258264
}`, [this.additionalProperties ? `,${os.EOL}\t${indentJsonString(this.additionalProperties)}` : ""]);
259265

260266
return {
261-
"label": this.snippetPrefix + name,
267+
"label": configPrefix + name,
262268
"description": localize("remote.attach.bash.windows", "Attach to a remote process running in Bash on Windows using {0}.", this.MIMode).replace(/\"/g, "\\\""),
263269
"bodyText": body.trim(),
264270
"debuggerType": DebuggerType.cppdbg

Extension/src/Debugger/debugAdapterDescriptorFactory.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ abstract class AbstractDebugAdapterDescriptorFactory implements vscode.DebugAdap
2626
}
2727

2828
export class CppdbgDebugAdapterDescriptorFactory extends AbstractDebugAdapterDescriptorFactory {
29-
public static DEBUG_TYPE: string = "cppdbg";
30-
3129
constructor(context: vscode.ExtensionContext) {
3230
super(context);
3331
}
@@ -42,8 +40,6 @@ export class CppdbgDebugAdapterDescriptorFactory extends AbstractDebugAdapterDes
4240
}
4341

4442
export class CppvsdbgDebugAdapterDescriptorFactory extends AbstractDebugAdapterDescriptorFactory {
45-
public static DEBUG_TYPE: string = "cppvsdbg";
46-
4743
constructor(context: vscode.ExtensionContext) {
4844
super(context);
4945
}

Extension/src/Debugger/extension.ts

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ import * as vscode from 'vscode';
77
import * as os from 'os';
88
import { AttachPicker, RemoteAttachPicker, AttachItemsProvider } from './attachToProcess';
99
import { NativeAttachItemsProviderFactory } from './nativeAttach';
10-
import { QuickPickConfigurationProvider, ConfigurationAssetProviderFactory, CppVsDbgConfigurationProvider, CppDbgConfigurationProvider, ConfigurationSnippetProvider, IConfigurationAssetProvider, buildAndDebug } from './configurationProvider';
10+
import { DebugConfigurationProvider, ConfigurationAssetProviderFactory, ConfigurationSnippetProvider, IConfigurationAssetProvider } from './configurationProvider';
1111
import { CppdbgDebugAdapterDescriptorFactory, CppvsdbgDebugAdapterDescriptorFactory } from './debugAdapterDescriptorFactory';
12+
import { DebuggerType } from './configurations';
1213

1314
// The extension deactivate method is asynchronous, so we handle the disposables ourselves instead of using extensonContext.subscriptions.
1415
const disposables: vscode.Disposable[] = [];
@@ -22,22 +23,24 @@ export async function initialize(context: vscode.ExtensionContext): Promise<void
2223
disposables.push(vscode.commands.registerCommand('extension.pickRemoteNativeProcess', (any) => remoteAttacher.ShowAttachEntries(any)));
2324

2425
// Activate ConfigurationProvider
25-
const configurationProvider: IConfigurationAssetProvider = ConfigurationAssetProviderFactory.getConfigurationProvider();
26-
// On non-windows platforms, the cppvsdbg debugger will not be registered for initial configurations.
27-
// This will cause it to not show up on the dropdown list.
28-
let cppVsDbgProvider: CppVsDbgConfigurationProvider | null = null;
26+
const assetProvider: IConfigurationAssetProvider = ConfigurationAssetProviderFactory.getConfigurationProvider();
27+
28+
// Register DebugConfigurationProviders for "Run and Debug" in Debug Panel.
29+
// On windows platforms, the cppvsdbg debugger will also be registered for initial configurations.
30+
let cppVsDebugProvider: DebugConfigurationProvider | null = null;
2931
if (os.platform() === 'win32') {
30-
cppVsDbgProvider = new CppVsDbgConfigurationProvider(configurationProvider);
31-
disposables.push(vscode.debug.registerDebugConfigurationProvider('cppvsdbg', new QuickPickConfigurationProvider(cppVsDbgProvider)));
32+
cppVsDebugProvider = new DebugConfigurationProvider(assetProvider, DebuggerType.cppvsdbg);
33+
disposables.push(vscode.debug.registerDebugConfigurationProvider(DebuggerType.cppvsdbg, cppVsDebugProvider, vscode.DebugConfigurationProviderTriggerKind.Dynamic));
3234
}
33-
const cppDbgProvider: CppDbgConfigurationProvider = new CppDbgConfigurationProvider(configurationProvider);
34-
disposables.push(vscode.debug.registerDebugConfigurationProvider('cppdbg', new QuickPickConfigurationProvider(cppDbgProvider)));
35-
36-
disposables.push(vscode.commands.registerTextEditorCommand("C_Cpp.BuildAndDebugFile", async (textEditor: vscode.TextEditor, edit: vscode.TextEditorEdit, ...args: any[]) => { await buildAndDebug(textEditor, cppVsDbgProvider, cppDbgProvider); }));
35+
const cppDebugProvider: DebugConfigurationProvider = new DebugConfigurationProvider(assetProvider, DebuggerType.cppdbg);
36+
disposables.push(vscode.debug.registerDebugConfigurationProvider(DebuggerType.cppdbg, cppDebugProvider, vscode.DebugConfigurationProviderTriggerKind.Dynamic));
3737

38-
disposables.push(vscode.commands.registerTextEditorCommand("C_Cpp.BuildAndRunFile", async (textEditor: vscode.TextEditor, edit: vscode.TextEditorEdit, ...args: any[]) => { await buildAndDebug(textEditor, cppVsDbgProvider, cppDbgProvider, false); }));
38+
// Register DebugConfigurationProviders for "Run and Debug" play button.
39+
const debugProvider: DebugConfigurationProvider = new DebugConfigurationProvider(assetProvider, DebuggerType.all);
40+
disposables.push(vscode.commands.registerTextEditorCommand("C_Cpp.BuildAndDebugFile", async (textEditor: vscode.TextEditor, edit: vscode.TextEditorEdit, ...args: any[]) => { await debugProvider.buildAndDebug(textEditor); }));
41+
disposables.push(vscode.commands.registerTextEditorCommand("C_Cpp.BuildAndRunFile", async (textEditor: vscode.TextEditor, edit: vscode.TextEditorEdit, ...args: any[]) => { await debugProvider.buildAndRun(textEditor); }));
3942

40-
configurationProvider.getConfigurationSnippets();
43+
assetProvider.getConfigurationSnippets();
4144

4245
const launchJsonDocumentSelector: vscode.DocumentSelector = [{
4346
scheme: 'file',
@@ -46,11 +49,11 @@ export async function initialize(context: vscode.ExtensionContext): Promise<void
4649
}];
4750

4851
// ConfigurationSnippetProvider needs to be initiallized after configurationProvider calls getConfigurationSnippets.
49-
disposables.push(vscode.languages.registerCompletionItemProvider(launchJsonDocumentSelector, new ConfigurationSnippetProvider(configurationProvider)));
52+
disposables.push(vscode.languages.registerCompletionItemProvider(launchJsonDocumentSelector, new ConfigurationSnippetProvider(assetProvider)));
5053

5154
// Register Debug Adapters
52-
disposables.push(vscode.debug.registerDebugAdapterDescriptorFactory(CppvsdbgDebugAdapterDescriptorFactory.DEBUG_TYPE, new CppvsdbgDebugAdapterDescriptorFactory(context)));
53-
disposables.push(vscode.debug.registerDebugAdapterDescriptorFactory(CppdbgDebugAdapterDescriptorFactory.DEBUG_TYPE, new CppdbgDebugAdapterDescriptorFactory(context)));
55+
disposables.push(vscode.debug.registerDebugAdapterDescriptorFactory(DebuggerType.cppvsdbg , new CppvsdbgDebugAdapterDescriptorFactory(context)));
56+
disposables.push(vscode.debug.registerDebugAdapterDescriptorFactory(DebuggerType.cppdbg, new CppdbgDebugAdapterDescriptorFactory(context)));
5457

5558
vscode.Disposable.from(...disposables);
5659
}

Extension/src/LanguageServer/cppBuildTaskProvider.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,13 @@ export class CppBuildTaskProvider implements TaskProvider {
5757

5858
public resolveInsiderTask(_task: CppBuildTask): CppBuildTask | undefined {
5959
const definition: CppBuildTaskDefinition = <any>_task.definition;
60+
definition.label = definition.label.replace(ext.configPrefix, "");
6061
_task = this.getTask(definition.command, false, definition.args ? definition.args : [], definition, _task.detail);
6162
return _task;
6263
}
6364

6465
// Generate tasks to build the current file based on the user's detected compilers, the user's compilerPath setting, and the current file's extension.
65-
public async getTasks(appendSourceToName: boolean): Promise<CppBuildTask[]> {
66+
public async getTasks(appendSourceToName: boolean = false): Promise<CppBuildTask[]> {
6667
const editor: TextEditor | undefined = window.activeTextEditor;
6768
const emptyTasks: CppBuildTask[] = [];
6869
if (!editor) {
@@ -170,8 +171,8 @@ export class CppBuildTaskProvider implements TaskProvider {
170171
if (!definition) {
171172
const isWindows: boolean = os.platform() === 'win32';
172173
const isMacARM64: boolean = (os.platform() === 'darwin' && os.arch() === 'arm64');
173-
const taskLabel: string = ((appendSourceToName && !compilerPathBase.startsWith(ext.CppSourceStr)) ?
174-
ext.CppSourceStr + ": " : "") + compilerPathBase + " " + localize("build_active_file", "build active file");
174+
const taskLabel: string = ((appendSourceToName && !compilerPathBase.startsWith(ext.configPrefix)) ?
175+
ext.configPrefix : "") + compilerPathBase + " " + localize("build_active_file", "build active file");
175176
const filePath: string = path.join('${fileDirname}', '${fileBasenameNoExtension}');
176177
const programName: string = isWindows ? filePath + '.exe' : filePath;
177178
let args: string[] = isCl ? ['/Zi', '/EHsc', '/nologo', '/Fe:', programName, '${file}'] : ['-fdiagnostics-color=always', '-g', '${file}', '-o', programName];

Extension/src/LanguageServer/extension.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFo
3030
const localize: nls.LocalizeFunc = nls.loadMessageBundle();
3131
export const cppBuildTaskProvider: CppBuildTaskProvider = new CppBuildTaskProvider();
3232
export const CppSourceStr: string = "C/C++";
33+
export const configPrefix: string = "C/C++: ";
3334

3435
let prevCrashFile: string;
3536
let clients: ClientCollection;
@@ -218,15 +219,15 @@ export async function activate(): Promise<void> {
218219
vscode.tasks.onDidStartTask(event => {
219220
getActiveClient().PauseCodeAnalysis();
220221
if (event.execution.task.definition.type === CppBuildTaskProvider.CppBuildScriptType
221-
|| event.execution.task.name.startsWith(CppSourceStr)) {
222+
|| event.execution.task.name.startsWith(configPrefix)) {
222223
telemetry.logLanguageServerEvent('buildTaskStarted');
223224
}
224225
});
225226

226227
vscode.tasks.onDidEndTask(event => {
227228
getActiveClient().ResumeCodeAnalysis();
228229
if (event.execution.task.definition.type === CppBuildTaskProvider.CppBuildScriptType
229-
|| event.execution.task.name.startsWith(CppSourceStr)) {
230+
|| event.execution.task.name.startsWith(configPrefix)) {
230231
telemetry.logLanguageServerEvent('buildTaskFinished');
231232
if (event.execution.task.scope !== vscode.TaskScope.Global && event.execution.task.scope !== vscode.TaskScope.Workspace) {
232233
const folder: vscode.WorkspaceFolder | undefined = event.execution.task.scope;

Extension/tools/OptionsSchema.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,6 @@
195195
},
196196
"CppdbgLaunchOptions": {
197197
"type": "object",
198-
"default": {},
199198
"required": [
200199
"program"
201200
],
@@ -519,7 +518,6 @@
519518
},
520519
"CppvsdbgLaunchOptions": {
521520
"type": "object",
522-
"default": {},
523521
"required": [
524522
"program",
525523
"cwd"

0 commit comments

Comments
 (0)