aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHannes De Valkeneer <[email protected]>2020-03-09 21:06:45 +0000
committerHannes De Valkeneer <[email protected]>2020-03-11 21:26:47 +0000
commite903fd0d9726dc6343a26ddeb919099fb8e4979e (patch)
tree23c2de00603542c434cc8e413c7d7cc425869cd2
parent05b4fc6d79060fc3120f92b01119e3a851c37829 (diff)
feat: add debug code lens
Refs #3539
-rw-r--r--crates/rust-analyzer/src/cargo_target_spec.rs42
-rw-r--r--crates/rust-analyzer/src/main_loop/handlers.rs21
-rw-r--r--crates/rust-analyzer/src/req.rs1
-rw-r--r--crates/rust-analyzer/tests/heavy_tests/main.rs8
-rw-r--r--editors/code/package.json3
-rw-r--r--editors/code/src/commands/runnables.ts28
-rw-r--r--editors/code/src/main.ts1
-rw-r--r--editors/code/src/rust-analyzer-api.ts3
8 files changed, 77 insertions, 30 deletions
diff --git a/crates/rust-analyzer/src/cargo_target_spec.rs b/crates/rust-analyzer/src/cargo_target_spec.rs
index 53751aafb..321861b16 100644
--- a/crates/rust-analyzer/src/cargo_target_spec.rs
+++ b/crates/rust-analyzer/src/cargo_target_spec.rs
@@ -19,50 +19,48 @@ impl CargoTargetSpec {
19 pub(crate) fn runnable_args( 19 pub(crate) fn runnable_args(
20 spec: Option<CargoTargetSpec>, 20 spec: Option<CargoTargetSpec>,
21 kind: &RunnableKind, 21 kind: &RunnableKind,
22 ) -> Result<Vec<String>> { 22 ) -> Result<(Vec<String>, Vec<String>)> {
23 let mut res = Vec::new(); 23 let mut args = Vec::new();
24 let mut extra_args = Vec::new();
24 match kind { 25 match kind {
25 RunnableKind::Test { test_id } => { 26 RunnableKind::Test { test_id } => {
26 res.push("test".to_string()); 27 args.push("test".to_string());
27 if let Some(spec) = spec { 28 if let Some(spec) = spec {
28 spec.push_to(&mut res); 29 spec.push_to(&mut args);
29 } 30 }
30 res.push("--".to_string()); 31 extra_args.push(test_id.to_string());
31 res.push(test_id.to_string());
32 if let TestId::Path(_) = test_id { 32 if let TestId::Path(_) = test_id {
33 res.push("--exact".to_string()); 33 extra_args.push("--exact".to_string());
34 } 34 }
35 res.push("--nocapture".to_string()); 35 extra_args.push("--nocapture".to_string());
36 } 36 }
37 RunnableKind::TestMod { path } => { 37 RunnableKind::TestMod { path } => {
38 res.push("test".to_string()); 38 args.push("test".to_string());
39 if let Some(spec) = spec { 39 if let Some(spec) = spec {
40 spec.push_to(&mut res); 40 spec.push_to(&mut args);
41 } 41 }
42 res.push("--".to_string()); 42 extra_args.push(path.to_string());
43 res.push(path.to_string()); 43 extra_args.push("--nocapture".to_string());
44 res.push("--nocapture".to_string());
45 } 44 }
46 RunnableKind::Bench { test_id } => { 45 RunnableKind::Bench { test_id } => {
47 res.push("bench".to_string()); 46 args.push("bench".to_string());
48 if let Some(spec) = spec { 47 if let Some(spec) = spec {
49 spec.push_to(&mut res); 48 spec.push_to(&mut args);
50 } 49 }
51 res.push("--".to_string()); 50 extra_args.push(test_id.to_string());
52 res.push(test_id.to_string());
53 if let TestId::Path(_) = test_id { 51 if let TestId::Path(_) = test_id {
54 res.push("--exact".to_string()); 52 extra_args.push("--exact".to_string());
55 } 53 }
56 res.push("--nocapture".to_string()); 54 extra_args.push("--nocapture".to_string());
57 } 55 }
58 RunnableKind::Bin => { 56 RunnableKind::Bin => {
59 res.push("run".to_string()); 57 args.push("run".to_string());
60 if let Some(spec) = spec { 58 if let Some(spec) = spec {
61 spec.push_to(&mut res); 59 spec.push_to(&mut args);
62 } 60 }
63 } 61 }
64 } 62 }
65 Ok(res) 63 Ok((args, extra_args))
66 } 64 }
67 65
68 pub(crate) fn for_file( 66 pub(crate) fn for_file(
diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs
index fcb40432d..044273333 100644
--- a/crates/rust-analyzer/src/main_loop/handlers.rs
+++ b/crates/rust-analyzer/src/main_loop/handlers.rs
@@ -381,6 +381,7 @@ pub fn handle_runnables(
381 label, 381 label,
382 bin: "cargo".to_string(), 382 bin: "cargo".to_string(),
383 args: check_args, 383 args: check_args,
384 extra_args: Vec::with_capacity(0),
384 env: FxHashMap::default(), 385 env: FxHashMap::default(),
385 cwd: workspace_root.map(|root| root.to_string_lossy().to_string()), 386 cwd: workspace_root.map(|root| root.to_string_lossy().to_string()),
386 }); 387 });
@@ -795,17 +796,29 @@ pub fn handle_code_lens(
795 } 796 }
796 .to_string(); 797 .to_string();
797 let r = to_lsp_runnable(&world, file_id, runnable)?; 798 let r = to_lsp_runnable(&world, file_id, runnable)?;
799 let range = r.range;
800 let arguments = vec![to_value(r).unwrap()];
798 let lens = CodeLens { 801 let lens = CodeLens {
799 range: r.range, 802 range: range.clone(),
800 command: Some(Command { 803 command: Some(Command {
801 title, 804 title,
802 command: "rust-analyzer.runSingle".into(), 805 command: "rust-analyzer.runSingle".into(),
803 arguments: Some(vec![to_value(r).unwrap()]), 806 arguments: Some(arguments.clone()),
807 }),
808 data: None,
809 };
810 let debug_lens = CodeLens {
811 range,
812 command: Some(Command {
813 title: "Debug".into(),
814 command: "rust-analyzer.debugSingle".into(),
815 arguments: Some(arguments.clone()),
804 }), 816 }),
805 data: None, 817 data: None,
806 }; 818 };
807 819
808 lenses.push(lens); 820 lenses.push(lens);
821 lenses.push(debug_lens);
809 } 822 }
810 823
811 // Handle impls 824 // Handle impls
@@ -952,7 +965,7 @@ fn to_lsp_runnable(
952 runnable: Runnable, 965 runnable: Runnable,
953) -> Result<req::Runnable> { 966) -> Result<req::Runnable> {
954 let spec = CargoTargetSpec::for_file(world, file_id)?; 967 let spec = CargoTargetSpec::for_file(world, file_id)?;
955 let args = CargoTargetSpec::runnable_args(spec, &runnable.kind)?; 968 let (args, extra_args) = CargoTargetSpec::runnable_args(spec, &runnable.kind)?;
956 let line_index = world.analysis().file_line_index(file_id)?; 969 let line_index = world.analysis().file_line_index(file_id)?;
957 let label = match &runnable.kind { 970 let label = match &runnable.kind {
958 RunnableKind::Test { test_id } => format!("test {}", test_id), 971 RunnableKind::Test { test_id } => format!("test {}", test_id),
@@ -965,6 +978,7 @@ fn to_lsp_runnable(
965 label, 978 label,
966 bin: "cargo".to_string(), 979 bin: "cargo".to_string(),
967 args, 980 args,
981 extra_args,
968 env: { 982 env: {
969 let mut m = FxHashMap::default(); 983 let mut m = FxHashMap::default();
970 m.insert("RUST_BACKTRACE".to_string(), "short".to_string()); 984 m.insert("RUST_BACKTRACE".to_string(), "short".to_string());
@@ -973,6 +987,7 @@ fn to_lsp_runnable(
973 cwd: world.workspace_root_for(file_id).map(|root| root.to_string_lossy().to_string()), 987 cwd: world.workspace_root_for(file_id).map(|root| root.to_string_lossy().to_string()),
974 }) 988 })
975} 989}
990
976fn highlight(world: &WorldSnapshot, file_id: FileId) -> Result<Vec<Decoration>> { 991fn highlight(world: &WorldSnapshot, file_id: FileId) -> Result<Vec<Decoration>> {
977 let line_index = world.analysis().file_line_index(file_id)?; 992 let line_index = world.analysis().file_line_index(file_id)?;
978 let res = world 993 let res = world
diff --git a/crates/rust-analyzer/src/req.rs b/crates/rust-analyzer/src/req.rs
index a3efe3b9f..156328df8 100644
--- a/crates/rust-analyzer/src/req.rs
+++ b/crates/rust-analyzer/src/req.rs
@@ -169,6 +169,7 @@ pub struct Runnable {
169 pub label: String, 169 pub label: String,
170 pub bin: String, 170 pub bin: String,
171 pub args: Vec<String>, 171 pub args: Vec<String>,
172 pub extra_args: Vec<String>,
172 pub env: FxHashMap<String, String>, 173 pub env: FxHashMap<String, String>,
173 pub cwd: Option<String>, 174 pub cwd: Option<String>,
174} 175}
diff --git a/crates/rust-analyzer/tests/heavy_tests/main.rs b/crates/rust-analyzer/tests/heavy_tests/main.rs
index 970185dec..55af6c5e0 100644
--- a/crates/rust-analyzer/tests/heavy_tests/main.rs
+++ b/crates/rust-analyzer/tests/heavy_tests/main.rs
@@ -75,7 +75,8 @@ fn foo() {
75 RunnablesParams { text_document: server.doc_id("lib.rs"), position: None }, 75 RunnablesParams { text_document: server.doc_id("lib.rs"), position: None },
76 json!([ 76 json!([
77 { 77 {
78 "args": [ "test", "--", "foo", "--nocapture" ], 78 "args": [ "test" ],
79 "extraArgs": [ "foo", "--nocapture" ],
79 "bin": "cargo", 80 "bin": "cargo",
80 "env": { "RUST_BACKTRACE": "short" }, 81 "env": { "RUST_BACKTRACE": "short" },
81 "cwd": null, 82 "cwd": null,
@@ -90,6 +91,7 @@ fn foo() {
90 "check", 91 "check",
91 "--all" 92 "--all"
92 ], 93 ],
94 "extraArgs": [],
93 "bin": "cargo", 95 "bin": "cargo",
94 "env": {}, 96 "env": {},
95 "cwd": null, 97 "cwd": null,
@@ -147,7 +149,8 @@ fn main() {}
147 }, 149 },
148 json!([ 150 json!([
149 { 151 {
150 "args": [ "test", "--package", "foo", "--test", "spam", "--", "test_eggs", "--exact", "--nocapture" ], 152 "args": [ "test", "--package", "foo", "--test", "spam" ],
153 "extraArgs": [ "test_eggs", "--exact", "--nocapture" ],
151 "bin": "cargo", 154 "bin": "cargo",
152 "env": { "RUST_BACKTRACE": "short" }, 155 "env": { "RUST_BACKTRACE": "short" },
153 "label": "test test_eggs", 156 "label": "test test_eggs",
@@ -165,6 +168,7 @@ fn main() {}
165 "--test", 168 "--test",
166 "spam" 169 "spam"
167 ], 170 ],
171 "extraArgs": [],
168 "bin": "cargo", 172 "bin": "cargo",
169 "env": {}, 173 "env": {},
170 "cwd": server.path().join("foo"), 174 "cwd": server.path().join("foo"),
diff --git a/editors/code/package.json b/editors/code/package.json
index 1fe8e9f8a..744585721 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -51,6 +51,9 @@
51 "typescript-formatter": "^7.2.2", 51 "typescript-formatter": "^7.2.2",
52 "vsce": "^1.74.0" 52 "vsce": "^1.74.0"
53 }, 53 },
54 "extensionDependencies": [
55 "vadimcn.vscode-lldb"
56 ],
54 "activationEvents": [ 57 "activationEvents": [
55 "onLanguage:rust", 58 "onLanguage:rust",
56 "onCommand:rust-analyzer.analyzerStatus", 59 "onCommand:rust-analyzer.analyzerStatus",
diff --git a/editors/code/src/commands/runnables.ts b/editors/code/src/commands/runnables.ts
index 06b513466..faa92799c 100644
--- a/editors/code/src/commands/runnables.ts
+++ b/editors/code/src/commands/runnables.ts
@@ -3,6 +3,7 @@ import * as lc from 'vscode-languageclient';
3import * as ra from '../rust-analyzer-api'; 3import * as ra from '../rust-analyzer-api';
4 4
5import { Ctx, Cmd } from '../ctx'; 5import { Ctx, Cmd } from '../ctx';
6import { debug } from 'vscode';
6 7
7export function run(ctx: Ctx): Cmd { 8export function run(ctx: Ctx): Cmd {
8 let prevRunnable: RunnableQuickPick | undefined; 9 let prevRunnable: RunnableQuickPick | undefined;
@@ -62,6 +63,31 @@ export function runSingle(ctx: Ctx): Cmd {
62 }; 63 };
63} 64}
64 65
66export function debugSingle(ctx: Ctx): Cmd {
67 return async (config: ra.Runnable) => {
68 const editor = ctx.activeRustEditor;
69 if (!editor) return;
70
71 if (config.args[0] === 'run') {
72 config.args[0] = 'build';
73 } else {
74 config.args.push('--no-run');
75 }
76
77 const debugConfig = {
78 type: "lldb",
79 request: "launch",
80 name: config.label,
81 cargo: {
82 args: config.args,
83 },
84 args: config.extraArgs,
85 cwd: config.cwd
86 };
87 return debug.startDebugging(undefined, debugConfig);
88 };
89}
90
65class RunnableQuickPick implements vscode.QuickPickItem { 91class RunnableQuickPick implements vscode.QuickPickItem {
66 public label: string; 92 public label: string;
67 public description?: string | undefined; 93 public description?: string | undefined;
@@ -87,7 +113,7 @@ function createTask(spec: ra.Runnable): vscode.Task {
87 type: 'cargo', 113 type: 'cargo',
88 label: spec.label, 114 label: spec.label,
89 command: spec.bin, 115 command: spec.bin,
90 args: spec.args, 116 args: spec.extraArgs ? [...spec.args, '--', ...spec.extraArgs] : spec.args,
91 env: spec.env, 117 env: spec.env,
92 }; 118 };
93 119
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts
index ecf53cf77..e01c89cc7 100644
--- a/editors/code/src/main.ts
+++ b/editors/code/src/main.ts
@@ -83,6 +83,7 @@ export async function activate(context: vscode.ExtensionContext) {
83 83
84 // Internal commands which are invoked by the server. 84 // Internal commands which are invoked by the server.
85 ctx.registerCommand('runSingle', commands.runSingle); 85 ctx.registerCommand('runSingle', commands.runSingle);
86 ctx.registerCommand('debugSingle', commands.debugSingle);
86 ctx.registerCommand('showReferences', commands.showReferences); 87 ctx.registerCommand('showReferences', commands.showReferences);
87 ctx.registerCommand('applySourceChange', commands.applySourceChange); 88 ctx.registerCommand('applySourceChange', commands.applySourceChange);
88 ctx.registerCommand('selectAndApplySourceChange', commands.selectAndApplySourceChange); 89 ctx.registerCommand('selectAndApplySourceChange', commands.selectAndApplySourceChange);
diff --git a/editors/code/src/rust-analyzer-api.ts b/editors/code/src/rust-analyzer-api.ts
index bd6e3ada0..e09a203c9 100644
--- a/editors/code/src/rust-analyzer-api.ts
+++ b/editors/code/src/rust-analyzer-api.ts
@@ -80,13 +80,12 @@ export interface Runnable {
80 label: string; 80 label: string;
81 bin: string; 81 bin: string;
82 args: Vec<string>; 82 args: Vec<string>;
83 extraArgs: Vec<string>;
83 env: FxHashMap<string, string>; 84 env: FxHashMap<string, string>;
84 cwd: Option<string>; 85 cwd: Option<string>;
85} 86}
86export const runnables = request<RunnablesParams, Vec<Runnable>>("runnables"); 87export const runnables = request<RunnablesParams, Vec<Runnable>>("runnables");
87 88
88
89
90export type InlayHint = InlayHint.TypeHint | InlayHint.ParamHint; 89export type InlayHint = InlayHint.TypeHint | InlayHint.ParamHint;
91 90
92export namespace InlayHint { 91export namespace InlayHint {