aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_ide/src/runnables.rs78
-rw-r--r--crates/rust-analyzer/src/main_loop/handlers.rs86
-rw-r--r--crates/rust-analyzer/src/to_proto.rs12
3 files changed, 122 insertions, 54 deletions
diff --git a/crates/ra_ide/src/runnables.rs b/crates/ra_ide/src/runnables.rs
index f32ce0d22..9f7b5edfd 100644
--- a/crates/ra_ide/src/runnables.rs
+++ b/crates/ra_ide/src/runnables.rs
@@ -42,6 +42,42 @@ pub enum RunnableKind {
42 Bin, 42 Bin,
43} 43}
44 44
45#[derive(Debug, Eq, PartialEq)]
46pub struct RunnableAction {
47 pub run_title: &'static str,
48 pub debugee: bool,
49}
50
51const TEST: RunnableAction = RunnableAction { run_title: "▶\u{fe0e} Run Test", debugee: true };
52const DOCTEST: RunnableAction =
53 RunnableAction { run_title: "▶\u{fe0e} Run Doctest", debugee: false };
54const BENCH: RunnableAction = RunnableAction { run_title: "▶\u{fe0e} Run Bench", debugee: true };
55const BIN: RunnableAction = RunnableAction { run_title: "▶\u{fe0e} Run", debugee: true };
56
57impl Runnable {
58 // test package::module::testname
59 pub fn label(&self, target: Option<String>) -> String {
60 match &self.kind {
61 RunnableKind::Test { test_id, .. } => format!("test {}", test_id),
62 RunnableKind::TestMod { path } => format!("test-mod {}", path),
63 RunnableKind::Bench { test_id } => format!("bench {}", test_id),
64 RunnableKind::DocTest { test_id, .. } => format!("doctest {}", test_id),
65 RunnableKind::Bin => {
66 target.map_or_else(|| "run binary".to_string(), |t| format!("run {}", t))
67 }
68 }
69 }
70
71 pub fn action(&self) -> &'static RunnableAction {
72 match &self.kind {
73 RunnableKind::Test { .. } | RunnableKind::TestMod { .. } => &TEST,
74 RunnableKind::DocTest { .. } => &DOCTEST,
75 RunnableKind::Bench { .. } => &BENCH,
76 RunnableKind::Bin => &BIN,
77 }
78 }
79}
80
45// Feature: Run 81// Feature: Run
46// 82//
47// Shows a popup suggesting to run a test/benchmark/binary **at the current cursor 83// Shows a popup suggesting to run a test/benchmark/binary **at the current cursor
@@ -207,6 +243,15 @@ mod tests {
207 243
208 use crate::mock_analysis::analysis_and_position; 244 use crate::mock_analysis::analysis_and_position;
209 245
246 use super::{Runnable, RunnableAction, BENCH, BIN, DOCTEST, TEST};
247
248 fn assert_actions(runnables: &[Runnable], actions: &[&RunnableAction]) {
249 assert_eq!(
250 actions,
251 runnables.into_iter().map(|it| it.action()).collect::<Vec<_>>().as_slice()
252 );
253 }
254
210 #[test] 255 #[test]
211 fn test_runnables() { 256 fn test_runnables() {
212 let (analysis, pos) = analysis_and_position( 257 let (analysis, pos) = analysis_and_position(
@@ -221,6 +266,9 @@ mod tests {
221 #[test] 266 #[test]
222 #[ignore] 267 #[ignore]
223 fn test_foo() {} 268 fn test_foo() {}
269
270 #[bench]
271 fn bench() {}
224 "#, 272 "#,
225 ); 273 );
226 let runnables = analysis.runnables(pos.file_id).unwrap(); 274 let runnables = analysis.runnables(pos.file_id).unwrap();
@@ -295,9 +343,32 @@ mod tests {
295 }, 343 },
296 cfg_exprs: [], 344 cfg_exprs: [],
297 }, 345 },
346 Runnable {
347 nav: NavigationTarget {
348 file_id: FileId(
349 1,
350 ),
351 full_range: 82..104,
352 name: "bench",
353 kind: FN_DEF,
354 focus_range: Some(
355 94..99,
356 ),
357 container_name: None,
358 description: None,
359 docs: None,
360 },
361 kind: Bench {
362 test_id: Path(
363 "bench",
364 ),
365 },
366 cfg_exprs: [],
367 },
298 ] 368 ]
299 "### 369 "###
300 ); 370 );
371 assert_actions(&runnables, &[&BIN, &TEST, &TEST, &BENCH]);
301 } 372 }
302 373
303 #[test] 374 #[test]
@@ -361,6 +432,7 @@ mod tests {
361 ] 432 ]
362 "### 433 "###
363 ); 434 );
435 assert_actions(&runnables, &[&BIN, &DOCTEST]);
364 } 436 }
365 437
366 #[test] 438 #[test]
@@ -427,6 +499,7 @@ mod tests {
427 ] 499 ]
428 "### 500 "###
429 ); 501 );
502 assert_actions(&runnables, &[&BIN, &DOCTEST]);
430 } 503 }
431 504
432 #[test] 505 #[test]
@@ -493,6 +566,7 @@ mod tests {
493 ] 566 ]
494 "### 567 "###
495 ); 568 );
569 assert_actions(&runnables, &[&TEST, &TEST]);
496 } 570 }
497 571
498 #[test] 572 #[test]
@@ -561,6 +635,7 @@ mod tests {
561 ] 635 ]
562 "### 636 "###
563 ); 637 );
638 assert_actions(&runnables, &[&TEST, &TEST]);
564 } 639 }
565 640
566 #[test] 641 #[test]
@@ -631,6 +706,7 @@ mod tests {
631 ] 706 ]
632 "### 707 "###
633 ); 708 );
709 assert_actions(&runnables, &[&TEST, &TEST]);
634 } 710 }
635 711
636 #[test] 712 #[test]
@@ -681,6 +757,7 @@ mod tests {
681 ] 757 ]
682 "### 758 "###
683 ); 759 );
760 assert_actions(&runnables, &[&TEST]);
684 } 761 }
685 762
686 #[test] 763 #[test]
@@ -739,6 +816,7 @@ mod tests {
739 ] 816 ]
740 "### 817 "###
741 ); 818 );
819 assert_actions(&runnables, &[&TEST]);
742 } 820 }
743 821
744 #[test] 822 #[test]
diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs
index 3ff779702..da16976d3 100644
--- a/crates/rust-analyzer/src/main_loop/handlers.rs
+++ b/crates/rust-analyzer/src/main_loop/handlers.rs
@@ -18,7 +18,7 @@ use lsp_types::{
18 TextDocumentIdentifier, Url, WorkspaceEdit, 18 TextDocumentIdentifier, Url, WorkspaceEdit,
19}; 19};
20use ra_ide::{ 20use ra_ide::{
21 FileId, FilePosition, FileRange, HoverAction, Query, RangeInfo, RunnableKind, SearchScope, 21 FileId, FilePosition, FileRange, HoverAction, Query, RangeInfo, Runnable, RunnableKind, SearchScope,
22 TextEdit, 22 TextEdit,
23}; 23};
24use ra_prof::profile; 24use ra_prof::profile;
@@ -403,16 +403,11 @@ pub fn handle_runnables(
403 if !runnable.nav.full_range().contains_inclusive(offset) { 403 if !runnable.nav.full_range().contains_inclusive(offset) {
404 continue; 404 continue;
405 } 405 }
406 }
407 if is_lib_target(&runnable, cargo_spec.as_ref()) {
408 continue;
406 } 409 }
407 // Do not suggest binary run on other target than binary 410
408 if let RunnableKind::Bin = runnable.kind {
409 if let Some(spec) = &cargo_spec {
410 match spec.target_kind {
411 TargetKind::Bin => {}
412 _ => continue,
413 }
414 }
415 }
416 res.push(to_proto::runnable(&snap, file_id, runnable)?); 411 res.push(to_proto::runnable(&snap, file_id, runnable)?);
417 } 412 }
418 413
@@ -817,53 +812,26 @@ pub fn handle_code_lens(
817 if snap.config.lens.runnable() { 812 if snap.config.lens.runnable() {
818 // Gather runnables 813 // Gather runnables
819 for runnable in snap.analysis().runnables(file_id)? { 814 for runnable in snap.analysis().runnables(file_id)? {
820 let (run_title, debugee) = match &runnable.kind { 815 if is_lib_target(&runnable, cargo_spec.as_ref()) {
821 RunnableKind::Test { .. } | RunnableKind::TestMod { .. } => { 816 continue;
822 ("▶\u{fe0e} Run Test", true) 817 }
823 }
824 RunnableKind::DocTest { .. } => {
825 // cargo does not support -no-run for doctests
826 ("▶\u{fe0e} Run Doctest", false)
827 }
828 RunnableKind::Bench { .. } => {
829 // Nothing wrong with bench debugging
830 ("Run Bench", true)
831 }
832 RunnableKind::Bin => {
833 // Do not suggest binary run on other target than binary
834 match &cargo_spec {
835 Some(spec) => match spec.target_kind {
836 TargetKind::Bin => ("Run", true),
837 _ => continue,
838 },
839 None => continue,
840 }
841 }
842 };
843 818
819 let action = runnable.action();
844 let range = to_proto::range(&line_index, runnable.nav.range()); 820 let range = to_proto::range(&line_index, runnable.nav.range());
845 let r = to_proto::runnable(&snap, file_id, runnable)?; 821 let r = to_proto::runnable(&snap, file_id, runnable)?;
846 if snap.config.lens.run { 822 if snap.config.lens.run {
847 let lens = CodeLens { 823 let lens = CodeLens {
848 range, 824 range,
849 command: Some(Command { 825 command: Some(run_single_command(&r, action.run_title)),
850 title: run_title.to_string(),
851 command: "rust-analyzer.runSingle".into(),
852 arguments: Some(vec![to_value(&r).unwrap()]),
853 }),
854 data: None, 826 data: None,
855 }; 827 };
856 lenses.push(lens); 828 lenses.push(lens);
857 } 829 }
858 830
859 if debugee && snap.config.lens.debug { 831 if action.debugee && snap.config.lens.debug {
860 let debug_lens = CodeLens { 832 let debug_lens = CodeLens {
861 range, 833 range,
862 command: Some(Command { 834 command: Some(debug_single_command(r)),
863 title: "Debug".into(),
864 command: "rust-analyzer.debugSingle".into(),
865 arguments: Some(vec![to_value(r).unwrap()]),
866 }),
867 data: None, 835 data: None,
868 }; 836 };
869 lenses.push(debug_lens); 837 lenses.push(debug_lens);
@@ -1169,6 +1137,22 @@ fn show_references_command(
1169 } 1137 }
1170} 1138}
1171 1139
1140fn run_single_command(runnable: &lsp_ext::Runnable, title: &str) -> Command {
1141 Command {
1142 title: title.to_string(),
1143 command: "rust-analyzer.runSingle".into(),
1144 arguments: Some(vec![to_value(runnable).unwrap()]),
1145 }
1146}
1147
1148fn debug_single_command(runnable: lsp_ext::Runnable) -> Command {
1149 Command {
1150 title: "Debug".into(),
1151 command: "rust-analyzer.debugSingle".into(),
1152 arguments: Some(vec![to_value(runnable).unwrap()]),
1153 }
1154}
1155
1172fn to_command_link(command: Command, tooltip: String) -> lsp_ext::CommandLink { 1156fn to_command_link(command: Command, tooltip: String) -> lsp_ext::CommandLink {
1173 lsp_ext::CommandLink { tooltip: Some(tooltip), command } 1157 lsp_ext::CommandLink { tooltip: Some(tooltip), command }
1174} 1158}
@@ -1214,3 +1198,17 @@ fn prepare_hover_actions(
1214 }) 1198 })
1215 .collect() 1199 .collect()
1216} 1200}
1201
1202fn is_lib_target(runnable: &Runnable, cargo_spec: Option<&CargoTargetSpec>) -> bool {
1203 // Do not suggest binary run on other target than binary
1204 if let RunnableKind::Bin = runnable.kind {
1205 if let Some(spec) = cargo_spec {
1206 match spec.target_kind {
1207 TargetKind::Bin => return true,
1208 _ => ()
1209 }
1210 }
1211 }
1212
1213 false
1214} \ No newline at end of file
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index 1da4d80ec..710df1fbd 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -4,7 +4,7 @@ use ra_ide::{
4 Assist, CompletionItem, CompletionItemKind, Documentation, FileSystemEdit, Fold, FoldKind, 4 Assist, CompletionItem, CompletionItemKind, Documentation, FileSystemEdit, Fold, FoldKind,
5 FunctionSignature, Highlight, HighlightModifier, HighlightTag, HighlightedRange, Indel, 5 FunctionSignature, Highlight, HighlightModifier, HighlightTag, HighlightedRange, Indel,
6 InlayHint, InlayKind, InsertTextFormat, LineIndex, NavigationTarget, ReferenceAccess, 6 InlayHint, InlayKind, InsertTextFormat, LineIndex, NavigationTarget, ReferenceAccess,
7 ResolvedAssist, Runnable, RunnableKind, Severity, SourceChange, SourceFileEdit, TextEdit, 7 ResolvedAssist, Runnable, Severity, SourceChange, SourceFileEdit, TextEdit,
8}; 8};
9use ra_syntax::{SyntaxKind, TextRange, TextSize}; 9use ra_syntax::{SyntaxKind, TextRange, TextSize};
10use ra_vfs::LineEndings; 10use ra_vfs::LineEndings;
@@ -662,15 +662,7 @@ pub(crate) fn runnable(
662 let target = spec.as_ref().map(|s| s.target.clone()); 662 let target = spec.as_ref().map(|s| s.target.clone());
663 let (cargo_args, executable_args) = 663 let (cargo_args, executable_args) =
664 CargoTargetSpec::runnable_args(spec, &runnable.kind, &runnable.cfg_exprs)?; 664 CargoTargetSpec::runnable_args(spec, &runnable.kind, &runnable.cfg_exprs)?;
665 let label = match &runnable.kind { 665 let label = runnable.label(target);
666 RunnableKind::Test { test_id, .. } => format!("test {}", test_id),
667 RunnableKind::TestMod { path } => format!("test-mod {}", path),
668 RunnableKind::Bench { test_id } => format!("bench {}", test_id),
669 RunnableKind::DocTest { test_id, .. } => format!("doctest {}", test_id),
670 RunnableKind::Bin => {
671 target.map_or_else(|| "run binary".to_string(), |t| format!("run {}", t))
672 }
673 };
674 let location = location_link(snap, None, runnable.nav)?; 666 let location = location_link(snap, None, runnable.nav)?;
675 667
676 Ok(lsp_ext::Runnable { 668 Ok(lsp_ext::Runnable {