aboutsummaryrefslogtreecommitdiff
path: root/editors/code/src/debug.ts
diff options
context:
space:
mode:
Diffstat (limited to 'editors/code/src/debug.ts')
-rw-r--r--editors/code/src/debug.ts124
1 files changed, 124 insertions, 0 deletions
diff --git a/editors/code/src/debug.ts b/editors/code/src/debug.ts
new file mode 100644
index 000000000..d3fe588e8
--- /dev/null
+++ b/editors/code/src/debug.ts
@@ -0,0 +1,124 @@
1import * as os from "os";
2import * as vscode from 'vscode';
3import * as path from 'path';
4import * as ra from './rust-analyzer-api';
5
6import { Cargo } from './cargo';
7import { Ctx } from "./ctx";
8
9const debugOutput = vscode.window.createOutputChannel("Debug");
10type DebugConfigProvider = (config: ra.Runnable, executable: string, sourceFileMap?: Record<string, string>) => vscode.DebugConfiguration;
11
12function getLldbDebugConfig(config: ra.Runnable, executable: string, sourceFileMap?: Record<string, string>): vscode.DebugConfiguration {
13 return {
14 type: "lldb",
15 request: "launch",
16 name: config.label,
17 program: executable,
18 args: config.extraArgs,
19 cwd: config.cwd,
20 sourceMap: sourceFileMap,
21 sourceLanguages: ["rust"]
22 };
23}
24
25function getCppvsDebugConfig(config: ra.Runnable, executable: string, sourceFileMap?: Record<string, string>): vscode.DebugConfiguration {
26 return {
27 type: (os.platform() === "win32") ? "cppvsdbg" : "cppdbg",
28 request: "launch",
29 name: config.label,
30 program: executable,
31 args: config.extraArgs,
32 cwd: config.cwd,
33 sourceFileMap: sourceFileMap,
34 };
35}
36
37async function getDebugExecutable(config: ra.Runnable): Promise<string> {
38 const cargo = new Cargo(config.cwd || '.', debugOutput);
39 const executable = await cargo.executableFromArgs(config.args);
40
41 // if we are here, there were no compilation errors.
42 return executable;
43}
44
45export async function getDebugConfiguration(ctx: Ctx, config: ra.Runnable): Promise<vscode.DebugConfiguration | undefined> {
46 const editor = ctx.activeRustEditor;
47 if (!editor) return;
48
49 const knownEngines: Record<string, DebugConfigProvider> = {
50 "vadimcn.vscode-lldb": getLldbDebugConfig,
51 "ms-vscode.cpptools": getCppvsDebugConfig
52 };
53 const debugOptions = ctx.config.debug;
54
55 let debugEngine = null;
56 if (debugOptions.engine === "auto") {
57 for (var engineId in knownEngines) {
58 debugEngine = vscode.extensions.getExtension(engineId);
59 if (debugEngine) break;
60 }
61 } else {
62 debugEngine = vscode.extensions.getExtension(debugOptions.engine);
63 }
64
65 if (!debugEngine) {
66 vscode.window.showErrorMessage(`Install [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb)`
67 + ` or [MS C++ tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) extension for debugging.`);
68 return;
69 }
70
71 debugOutput.clear();
72 if (ctx.config.debug.openUpDebugPane) {
73 debugOutput.show(true);
74 }
75
76 const wsFolder = path.normalize(vscode.workspace.workspaceFolders![0].uri.fsPath); // folder exists or RA is not active.
77 function simplifyPath(p: string): string {
78 return path.normalize(p).replace(wsFolder, '${workspaceRoot}');
79 }
80
81 const executable = await getDebugExecutable(config);
82 const debugConfig = knownEngines[debugEngine.id](config, simplifyPath(executable), debugOptions.sourceFileMap);
83 if (debugConfig.type in debugOptions.engineSettings) {
84 const settingsMap = (debugOptions.engineSettings as any)[debugConfig.type];
85 for (var key in settingsMap) {
86 debugConfig[key] = settingsMap[key];
87 }
88 }
89
90 if (debugConfig.name === "run binary") {
91 // The LSP side: crates\rust-analyzer\src\main_loop\handlers.rs,
92 // fn to_lsp_runnable(...) with RunnableKind::Bin
93 debugConfig.name = `run ${path.basename(executable)}`;
94 }
95
96 if (debugConfig.cwd) {
97 debugConfig.cwd = simplifyPath(debugConfig.cwd);
98 }
99
100 return debugConfig;
101}
102
103export async function startDebugSession(ctx: Ctx, config: ra.Runnable): Promise<boolean> {
104 let debugConfig: vscode.DebugConfiguration | undefined = undefined;
105 let message = "";
106
107 const wsLaunchSection = vscode.workspace.getConfiguration("launch");
108 const configurations = wsLaunchSection.get<any[]>("configurations") || [];
109
110 const index = configurations.findIndex(c => c.name === config.label);
111 if (-1 !== index) {
112 debugConfig = configurations[index];
113 message = " (from launch.json)";
114 debugOutput.clear();
115 } else {
116 debugConfig = await getDebugConfiguration(ctx, config);
117 }
118
119 if (!debugConfig) return false;
120
121 debugOutput.appendLine(`Launching debug configuration${message}:`);
122 debugOutput.appendLine(JSON.stringify(debugConfig, null, 2));
123 return vscode.debug.startDebugging(undefined, debugConfig);
124}