Skip to content

Commit 2253f74

Browse files
committed
Updates to vscode debug launch configurations
* Create a launch configuration for each main for attaching to a running process * Make debug configurations have preLaunchTask fields pointing to build tasks
1 parent f077994 commit 2253f74

File tree

4 files changed

+67
-47
lines changed

4 files changed

+67
-47
lines changed

.vscode/extensions.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"dbaeumer.vscode-eslint",
88
"esbenp.prettier-vscode",
99
"gruntfuggly.triggertaskonsave",
10-
"davidanson.vscode-markdownlint"
10+
"davidanson.vscode-markdownlint",
11+
"adacore.ada"
1112
]
1213
}

integration/vscode/ada/src/commands.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,12 @@ export function registerCommands(context: vscode.ExtensionContext, clients: Exte
3939

4040
// This is a hidden command that gets called in the default debug
4141
// configuration snippet that gets offered in the launch.json file.
42+
// It is expected to return the relative path of the main program chosen for
43+
// debugging.
4244
context.subscriptions.push(
4345
vscode.commands.registerCommand('ada.getOrAskForProgram', async () => {
4446
const p = await getOrAskForProgram();
45-
return p;
47+
return p?.execRelPath();
4648
})
4749
);
4850

integration/vscode/ada/src/debugConfigProvider.ts

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,24 @@ import assert from 'assert';
22
import * as vscode from 'vscode';
33
import { adaExtState } from './extension';
44
import { AdaMain, getAdaMains, getProjectFile } from './helpers';
5+
import { BUILD_PROJECT_TASK_NAME, getBuildTaskName } from './taskProviders';
56

67
/**
78
* Ada Configuration for a debug session
89
*/
910
interface AdaConfig extends vscode.DebugConfiguration {
1011
MIMode: string;
1112
program: string;
12-
cwd: string;
13-
targetArchitecture: string;
14-
stopAtEntry: boolean;
15-
args: string[];
16-
setupCommands: {
13+
cwd?: string;
14+
targetArchitecture?: string;
15+
stopAtEntry?: boolean;
16+
args?: string[];
17+
setupCommands?: {
1718
description: string;
1819
text: string;
1920
ignoreFailures: boolean;
2021
}[];
22+
processId?: string;
2123
}
2224

2325
/**
@@ -53,9 +55,9 @@ export function initializeDebugging(ctx: vscode.ExtensionContext) {
5355
): Promise<vscode.DebugConfiguration[]> {
5456
const quickpick = await createQuickPickItems('Build & Debug');
5557

56-
const configs: vscode.DebugConfiguration[] = quickpick.map((i) => {
58+
const configs: AdaConfig[] = quickpick.flatMap((i) => {
5759
assert(i.adaMain);
58-
return initializeConfig(i.adaMain.execFullPath, i.adaMain.mainRelPath());
60+
return [initializeConfig(i.adaMain), createAttachConfig(i.adaMain)];
5961
});
6062

6163
return configs;
@@ -89,27 +91,23 @@ export function initializeDebugging(ctx: vscode.ExtensionContext) {
8991
* 'program' parameter.
9092
* @returns an AdaConfig
9193
*/
92-
function initializeConfig(program?: string, main?: string, name?: string): AdaConfig {
94+
function initializeConfig(main: AdaMain, name?: string): AdaConfig {
9395
// TODO it would be nice if this and the package.json configuration snippet
9496
// were the same.
9597
const config: AdaConfig = {
9698
type: 'cppdbg',
97-
name:
98-
name ??
99-
(main
100-
? `Ada: Debug main - ${main}`
101-
: program
102-
? `Ada: Debug executable - ${program.replace('${workspaceFolder}/', '')}`
103-
: 'Ada: Debugger Launch'),
99+
name: name ?? (main ? `Ada: Debug main - ${main.mainRelPath()}` : 'Ada: Debugger Launch'),
104100
request: 'launch',
105101
targetArchitecture: process.arch,
106102
cwd: '${workspaceFolder}',
107-
program: program ?? '${workspaceFolder}/${command:ada.getOrAskForProgram}',
103+
program: main
104+
? `\${workspaceFolder}/${main.execRelPath()}`
105+
: '${workspaceFolder}/${command:ada.getOrAskForProgram}',
108106
stopAtEntry: false,
109107
externalConsole: false,
110108
args: [],
111109
MIMode: 'gdb',
112-
preLaunchTask: 'ada: Build current project',
110+
preLaunchTask: main ? getBuildTaskName(main) : BUILD_PROJECT_TASK_NAME,
113111
setupCommands: setupCmd,
114112
};
115113

@@ -155,12 +153,7 @@ export class AdaDebugConfigProvider implements vscode.DebugConfigurationProvider
155153
const item = quickpick[i];
156154
if (item != generateAll) {
157155
assert(item.adaMain);
158-
configs.push(
159-
initializeConfig(
160-
`\${workspaceFolder}/${item.adaMain.execRelPath()}`,
161-
item.adaMain.mainRelPath()
162-
)
163-
);
156+
configs.push(initializeConfig(item.adaMain));
164157
}
165158
}
166159
} else if (selectedProgram) {
@@ -169,10 +162,7 @@ export class AdaDebugConfigProvider implements vscode.DebugConfigurationProvider
169162
// The cppdbg debug configuration exepects the executable to be
170163
// a full path rather than a path relative to the specified
171164
// cwd. That is why we include ${workspaceFolder}.
172-
const configuration = initializeConfig(
173-
`\${workspaceFolder}/${selectedProgram.adaMain.execRelPath()}`,
174-
selectedProgram.label
175-
);
165+
const configuration = initializeConfig(selectedProgram.adaMain);
176166
configs.push(configuration);
177167
} else {
178168
return Promise.reject('Cancelled');
@@ -212,10 +202,10 @@ export class AdaDebugConfigProvider implements vscode.DebugConfigurationProvider
212202
// configuration on the fly.
213203
return debugConfiguration;
214204
} else {
215-
const exec = await getOrAskForProgram();
205+
const main = await getOrAskForProgram();
216206

217-
if (exec) {
218-
return initializeConfig(`\${workspaceFolder}/${exec}`);
207+
if (main) {
208+
return initializeConfig(main);
219209
}
220210
}
221211

@@ -308,31 +298,29 @@ async function assertProjectHasMains(mains?: AdaMain[]) {
308298
* matches one of the mains, the corresponding executable is returned.
309299
*
310300
* Otherwise, the list of mains is offered to the user as a QuickPicker to
311-
* choose a main file. The executable corresponding to the selected main
312-
* file is returned.
313-
*
314-
* Note that paths are returned relative to the workspace.
301+
* choose a main file. The object corresponding to the selected main file is
302+
* returned.
315303
*
316304
* @param mains - a list of AdaMains if available at the caller site, otherwise
317305
* it is computed by the call.
318-
* @returns the path of the executable to debug *relative to the workspace*,
319-
* or *undefined* if no selection was made.
306+
* @returns the object representing the selected main, or *undefined* if no
307+
* selection was made.
320308
*/
321-
export async function getOrAskForProgram(mains?: AdaMain[]): Promise<string | undefined> {
309+
export async function getOrAskForProgram(mains?: AdaMain[]): Promise<AdaMain | undefined> {
322310
// Compute list of mains if not provided by the caller
323311
mains = mains ?? (await getAdaMains());
324312

325313
await assertProjectHasMains(mains);
326314

327-
if (mains.length == 1) return mains[0].execRelPath();
315+
if (mains.length == 1) return mains[0];
328316

329317
// Check if the current file matches one of the mains of the project. If
330318
// so, use it.
331319
const currentFile = vscode.window.activeTextEditor?.document.uri.path;
332320
if (currentFile != undefined) {
333321
const adaMain = await getAdaMainForSourceFile(currentFile, mains);
334322
if (adaMain) {
335-
return adaMain.execRelPath();
323+
return adaMain;
336324
}
337325
}
338326

@@ -343,7 +331,7 @@ export async function getOrAskForProgram(mains?: AdaMain[]): Promise<string | un
343331
placeHolder: 'Select a main file to debug',
344332
});
345333
if (selectedProgram) {
346-
return selectedProgram.adaMain?.execRelPath();
334+
return selectedProgram.adaMain;
347335
}
348336

349337
return undefined;
@@ -366,3 +354,15 @@ async function getAdaMainForSourceFile(
366354

367355
return mains.find((val) => srcPath == val.mainFullPath);
368356
}
357+
358+
function createAttachConfig(adaMain: AdaMain): AdaConfig {
359+
return {
360+
name: `Ada: Attach debugger to running process - ${adaMain.mainRelPath()}`,
361+
type: 'cppdbg',
362+
request: 'attach',
363+
program: `\${workspaceFolder}/${adaMain.execRelPath()}`,
364+
processId: '${command:pickProcess}',
365+
MIMode: 'gdb',
366+
preLaunchTask: adaMain ? getBuildTaskName(adaMain) : BUILD_PROJECT_TASK_NAME,
367+
};
368+
}

integration/vscode/ada/src/taskProviders.ts

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@ import { basename } from 'path';
2121
import * as vscode from 'vscode';
2222
import { SymbolKind } from 'vscode';
2323
import { adaExtState } from './extension';
24-
import { getAdaMains, getProjectFile } from './helpers';
25-
import { task } from 'fp-ts';
24+
import { AdaMain, getAdaMains, getProjectFile } from './helpers';
25+
26+
export const ADA_TASK_TYPE = 'ada';
2627

2728
/**
2829
* Callback to provide an extra argument for a tool
@@ -215,6 +216,9 @@ export const allTaskProperties: { [id in AllTaskKinds]: TaskProperties } = {
215216
},
216217
};
217218

219+
// eslint-disable-next-line max-len
220+
export const BUILD_PROJECT_TASK_NAME = `${ADA_TASK_TYPE}: ${allTaskProperties['buildProject'].title}`;
221+
218222
export const PROJECT_FROM_CONFIG = '${config:ada.projectFile}';
219223
async function getProjectFromConfigOrALS(): Promise<string> {
220224
return vscode.workspace.getConfiguration('ada').get('projectFile')
@@ -424,9 +428,7 @@ export class ConfigurableTaskProvider implements vscode.TaskProvider {
424428
main: main.mainRelPath(),
425429
},
426430
};
427-
const name = `${allTaskProperties['buildMain'].title}${basename(
428-
main.mainRelPath()
429-
)}`;
431+
const name = getBuildTaskPlainName(main);
430432
const cmdLine = await buildFullCommandLine(name, def);
431433
this.tasks?.push(
432434
new vscode.Task(
@@ -448,6 +450,7 @@ export class ConfigurableTaskProvider implements vscode.TaskProvider {
448450
projectFile: await computeProject(),
449451
main: main.mainRelPath(),
450452
},
453+
// dependsOn: getBuildTaskName(main),
451454
};
452455
const name = `${allTaskProperties['buildAndRunMain'].title}${basename(
453456
main.mainRelPath()
@@ -512,6 +515,20 @@ export class ConfigurableTaskProvider implements vscode.TaskProvider {
512515
}
513516
}
514517

518+
/**
519+
* The name of the build task of a main, without the task type.
520+
*/
521+
function getBuildTaskPlainName(main: AdaMain) {
522+
return `${allTaskProperties['buildMain'].title}${main.mainRelPath()}`;
523+
}
524+
525+
/**
526+
* The full name of the build task of a main, including the task type.
527+
*/
528+
export function getBuildTaskName(main: AdaMain) {
529+
return `ada: ${getBuildTaskPlainName(main)}`;
530+
}
531+
515532
export function createSparkTaskProvider(): ConfigurableTaskProvider {
516533
return new ConfigurableTaskProvider(
517534
'spark',

0 commit comments

Comments
 (0)