Skip to content

Commit b4f278b

Browse files
committed
Changes for debug restarting
1 parent 91aa3f4 commit b4f278b

File tree

4 files changed

+63
-1
lines changed

4 files changed

+63
-1
lines changed

editors/code/package.json

+5
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,11 @@
520520
"type": "boolean",
521521
"default": false
522522
},
523+
"rust-analyzer.debug.buildBeforeRestart": {
524+
"markdownDescription": "Whether to rebuild the project modules before debugging the same test again",
525+
"type": "boolean",
526+
"default": false
527+
},
523528
"rust-analyzer.debug.engineSettings": {
524529
"type": "object",
525530
"default": {},

editors/code/src/config.ts

+1
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ export class Config {
303303
engine: this.get<string>("debug.engine"),
304304
engineSettings: this.get<object>("debug.engineSettings") ?? {},
305305
openDebugPane: this.get<boolean>("debug.openDebugPane"),
306+
buildBeforeRestart: this.get<boolean>("debug.buildBeforeRestart"),
306307
sourceFileMap: sourceFileMap,
307308
};
308309
}

editors/code/src/debug.ts

+52-1
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@ import type * as ra from "./lsp_ext";
55

66
import { Cargo } from "./toolchain";
77
import type { Ctx } from "./ctx";
8-
import { prepareEnv } from "./run";
8+
import { createTaskFromRunnable, prepareEnv } from "./run";
99
import { execute, isCargoRunnableArgs, unwrapUndefinable } from "./util";
1010
import type { Config } from "./config";
1111

1212
const debugOutput = vscode.window.createOutputChannel("Debug");
1313

14+
// Here we want to keep track on everything that's currently running
15+
const activeDebugSessionIds: string[] = [];
16+
1417
export async function makeDebugConfig(ctx: Ctx, runnable: ra.Runnable): Promise<void> {
1518
const scope = ctx.activeRustEditor?.document.uri;
1619
if (!scope) return;
@@ -45,6 +48,8 @@ export async function startDebugSession(ctx: Ctx, runnable: ra.Runnable): Promis
4548
const wsLaunchSection = vscode.workspace.getConfiguration("launch");
4649
const configurations = wsLaunchSection.get<any[]>("configurations") || [];
4750

51+
// The runnable label is the name of the test with the "test prefix"
52+
// e.g. test test_feature_x
4853
const index = configurations.findIndex((c) => c.name === runnable.label);
4954
if (-1 !== index) {
5055
debugConfig = configurations[index];
@@ -359,3 +364,49 @@ function quote(xs: string[]) {
359364
})
360365
.join(" ");
361366
}
367+
368+
async function recompileTestFromDebuggingSession(session: vscode.DebugSession, ctx: Ctx) {
369+
const { cwd, args: sessionArgs }: vscode.DebugConfiguration = session.configuration;
370+
371+
const args: ra.CargoRunnableArgs = {
372+
cwd: cwd,
373+
cargoArgs: ["test", "--no-run", "--test", "lib"],
374+
375+
// The first element of the debug configuration args is the test path e.g. "test_bar::foo::test_a::test_b"
376+
executableArgs: sessionArgs,
377+
};
378+
const runnable: ra.Runnable = {
379+
kind: "cargo",
380+
label: "compile-test",
381+
args,
382+
};
383+
const task: vscode.Task = await createTaskFromRunnable(runnable, ctx.config);
384+
385+
// It is not needed to call the language server, since the test path is already resolved in the
386+
// configuration option. We can simply call a debug configuration with the --no-run option to compile
387+
await vscode.tasks.executeTask(task);
388+
}
389+
390+
export function initializeDebugSessionTrackingAndRebuild(ctx: Ctx) {
391+
vscode.debug.onDidStartDebugSession((session: vscode.DebugSession) => {
392+
if (!activeDebugSessionIds.includes(session.id)) {
393+
activeDebugSessionIds.push(session.id);
394+
}
395+
});
396+
397+
vscode.debug.onDidTerminateDebugSession(async (session: vscode.DebugSession) => {
398+
// The id of the session will be the same when pressing restart the restart button
399+
if (activeDebugSessionIds.find((s) => s === session.id)) {
400+
await recompileTestFromDebuggingSession(session, ctx);
401+
}
402+
removeActiveSession(session);
403+
});
404+
}
405+
406+
function removeActiveSession(session: vscode.DebugSession) {
407+
const activeSessionId = activeDebugSessionIds.findIndex((id) => id === session.id);
408+
409+
if (activeSessionId !== -1) {
410+
activeDebugSessionIds.splice(activeSessionId, 1);
411+
}
412+
}

editors/code/src/main.ts

+5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { type CommandFactory, Ctx, fetchWorkspace } from "./ctx";
66
import * as diagnostics from "./diagnostics";
77
import { activateTaskProvider } from "./tasks";
88
import { setContextValue } from "./util";
9+
import { initializeDebugSessionTrackingAndRebuild } from "./debug";
910

1011
const RUST_PROJECT_CONTEXT_NAME = "inRustProject";
1112

@@ -102,6 +103,10 @@ async function activateServer(ctx: Ctx): Promise<RustAnalyzerExtensionApi> {
102103
ctx.subscriptions,
103104
);
104105

106+
if (ctx.config.debug.buildBeforeRestart) {
107+
initializeDebugSessionTrackingAndRebuild(ctx);
108+
}
109+
105110
await ctx.start();
106111
return ctx;
107112
}

0 commit comments

Comments
 (0)