Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'editors/code/src/debug.ts')
-rw-r--r--editors/code/src/debug.ts55
1 files changed, 54 insertions, 1 deletions
diff --git a/editors/code/src/debug.ts b/editors/code/src/debug.ts
index 3aae0f9ce6..fb7e340e51 100644
--- a/editors/code/src/debug.ts
+++ b/editors/code/src/debug.ts
@@ -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;
@@ -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];
@@ -168,6 +173,8 @@ async function getDebugConfiguration(
if (debugConfig.name === "run binary") {
// The LSP side: crates\rust-analyzer\src\main_loop\handlers.rs,
// fn to_lsp_runnable(...) with RunnableKind::Bin
+ // FIXME: Neither crates\rust-analyzer\src\main_loop\handlers.rs
+ // nor to_lsp_runnable exist anymore
debugConfig.name = `run ${path.basename(executable)}`;
}
@@ -359,3 +366,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);
+ }
+}