Skip to content

Commit

Permalink
Changes for debug restarting
Browse files Browse the repository at this point in the history
  • Loading branch information
basvandriel committed Sep 25, 2024
1 parent a594a2d commit b204f48
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/tools/rust-analyzer/editors/code/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,11 @@
"type": "boolean",
"default": false
},
"rust-analyzer.debug.buildBeforeRestart": {
"markdownDescription": "Whether to rebuild the project modules before debugging the same test again",
"type": "boolean",
"default": false
},
"rust-analyzer.debug.engineSettings": {
"type": "object",
"default": {},
Expand Down
1 change: 1 addition & 0 deletions src/tools/rust-analyzer/editors/code/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ export class Config {
engine: this.get<string>("debug.engine"),
engineSettings: this.get<object>("debug.engineSettings") ?? {},
openDebugPane: this.get<boolean>("debug.openDebugPane"),
buildBeforeRestart: this.get<boolean>("debug.buildBeforeRestart"),
sourceFileMap: sourceFileMap,
};
}
Expand Down
53 changes: 52 additions & 1 deletion src/tools/rust-analyzer/editors/code/src/debug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ import type * as ra from "./lsp_ext";

import { Cargo } from "./toolchain";
import type { Ctx } from "./ctx";
import { prepareEnv } from "./run";
import { createTaskFromRunnable, prepareEnv } from "./run";
import { execute, isCargoRunnableArgs, unwrapUndefinable } from "./util";
import type { Config } from "./config";

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

// Here we want to keep track on everything that's currently running
const activeDebugSessionIds: string[] = [];

export async function makeDebugConfig(ctx: Ctx, runnable: ra.Runnable): Promise<void> {
const scope = ctx.activeRustEditor?.document.uri;
if (!scope) return;
Expand Down Expand Up @@ -45,6 +48,8 @@ export async function startDebugSession(ctx: Ctx, runnable: ra.Runnable): Promis
const wsLaunchSection = vscode.workspace.getConfiguration("launch");
const configurations = wsLaunchSection.get<any[]>("configurations") || [];

// The runnable label is the name of the test with the "test prefix"
// e.g. test test_feature_x
const index = configurations.findIndex((c) => c.name === runnable.label);
if (-1 !== index) {
debugConfig = configurations[index];
Expand Down Expand Up @@ -359,3 +364,49 @@ function quote(xs: string[]) {
})
.join(" ");
}

async function recompileTestFromDebuggingSession(session: vscode.DebugSession, ctx: Ctx) {
const { cwd, args: sessionArgs }: vscode.DebugConfiguration = session.configuration;

const args: ra.CargoRunnableArgs = {
cwd: cwd,
cargoArgs: ["test", "--no-run", "--test", "lib"],

// The first element of the debug configuration args is the test path e.g. "test_bar::foo::test_a::test_b"
executableArgs: sessionArgs,
};
const runnable: ra.Runnable = {
kind: "cargo",
label: "compile-test",
args,
};
const task: vscode.Task = await createTaskFromRunnable(runnable, ctx.config);

// It is not needed to call the language server, since the test path is already resolved in the
// configuration option. We can simply call a debug configuration with the --no-run option to compile
await vscode.tasks.executeTask(task);
}

export function initializeDebugSessionTrackingAndRebuild(ctx: Ctx) {
vscode.debug.onDidStartDebugSession((session: vscode.DebugSession) => {
if (!activeDebugSessionIds.includes(session.id)) {
activeDebugSessionIds.push(session.id);
}
});

vscode.debug.onDidTerminateDebugSession(async (session: vscode.DebugSession) => {
// The id of the session will be the same when pressing restart the restart button
if (activeDebugSessionIds.find((s) => s === session.id)) {
await recompileTestFromDebuggingSession(session, ctx);
}
removeActiveSession(session);
});
}

function removeActiveSession(session: vscode.DebugSession) {
const activeSessionId = activeDebugSessionIds.findIndex((id) => id === session.id);

if (activeSessionId !== -1) {
activeDebugSessionIds.splice(activeSessionId, 1);
}
}
5 changes: 5 additions & 0 deletions src/tools/rust-analyzer/editors/code/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { type CommandFactory, Ctx, fetchWorkspace } from "./ctx";
import * as diagnostics from "./diagnostics";
import { activateTaskProvider } from "./tasks";
import { setContextValue } from "./util";
import { initializeDebugSessionTrackingAndRebuild } from "./debug";

const RUST_PROJECT_CONTEXT_NAME = "inRustProject";

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

if (ctx.config.debug.buildBeforeRestart) {
initializeDebugSessionTrackingAndRebuild(ctx);
}

await ctx.start();
return ctx;
}
Expand Down

0 comments on commit b204f48

Please sign in to comment.