From de74c0dcab2efd50d68f70d15de3fced718e8c7a Mon Sep 17 00:00:00 2001 From: vsrs Date: Sat, 6 Jun 2020 12:00:46 +0300 Subject: [PATCH 1/5] Preliminary runnables refactoring --- crates/ra_ide/src/runnables.rs | 78 +++++++++++++++++ .../rust-analyzer/src/main_loop/handlers.rs | 86 +++++++++---------- crates/rust-analyzer/src/to_proto.rs | 12 +-- 3 files changed, 122 insertions(+), 54 deletions(-) diff --git a/crates/ra_ide/src/runnables.rs b/crates/ra_ide/src/runnables.rs index f32ce0d229..9f7b5edfd5 100644 --- a/crates/ra_ide/src/runnables.rs +++ b/crates/ra_ide/src/runnables.rs @@ -42,6 +42,42 @@ pub enum RunnableKind { Bin, } +#[derive(Debug, Eq, PartialEq)] +pub struct RunnableAction { + pub run_title: &'static str, + pub debugee: bool, +} + +const TEST: RunnableAction = RunnableAction { run_title: "▶\u{fe0e} Run Test", debugee: true }; +const DOCTEST: RunnableAction = + RunnableAction { run_title: "▶\u{fe0e} Run Doctest", debugee: false }; +const BENCH: RunnableAction = RunnableAction { run_title: "▶\u{fe0e} Run Bench", debugee: true }; +const BIN: RunnableAction = RunnableAction { run_title: "▶\u{fe0e} Run", debugee: true }; + +impl Runnable { + // test package::module::testname + pub fn label(&self, target: Option) -> String { + match &self.kind { + RunnableKind::Test { test_id, .. } => format!("test {}", test_id), + RunnableKind::TestMod { path } => format!("test-mod {}", path), + RunnableKind::Bench { test_id } => format!("bench {}", test_id), + RunnableKind::DocTest { test_id, .. } => format!("doctest {}", test_id), + RunnableKind::Bin => { + target.map_or_else(|| "run binary".to_string(), |t| format!("run {}", t)) + } + } + } + + pub fn action(&self) -> &'static RunnableAction { + match &self.kind { + RunnableKind::Test { .. } | RunnableKind::TestMod { .. } => &TEST, + RunnableKind::DocTest { .. } => &DOCTEST, + RunnableKind::Bench { .. } => &BENCH, + RunnableKind::Bin => &BIN, + } + } +} + // Feature: Run // // Shows a popup suggesting to run a test/benchmark/binary **at the current cursor @@ -207,6 +243,15 @@ mod tests { use crate::mock_analysis::analysis_and_position; + use super::{Runnable, RunnableAction, BENCH, BIN, DOCTEST, TEST}; + + fn assert_actions(runnables: &[Runnable], actions: &[&RunnableAction]) { + assert_eq!( + actions, + runnables.into_iter().map(|it| it.action()).collect::>().as_slice() + ); + } + #[test] fn test_runnables() { let (analysis, pos) = analysis_and_position( @@ -221,6 +266,9 @@ mod tests { #[test] #[ignore] fn test_foo() {} + + #[bench] + fn bench() {} "#, ); let runnables = analysis.runnables(pos.file_id).unwrap(); @@ -295,9 +343,32 @@ mod tests { }, cfg_exprs: [], }, + Runnable { + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 82..104, + name: "bench", + kind: FN_DEF, + focus_range: Some( + 94..99, + ), + container_name: None, + description: None, + docs: None, + }, + kind: Bench { + test_id: Path( + "bench", + ), + }, + cfg_exprs: [], + }, ] "### ); + assert_actions(&runnables, &[&BIN, &TEST, &TEST, &BENCH]); } #[test] @@ -361,6 +432,7 @@ mod tests { ] "### ); + assert_actions(&runnables, &[&BIN, &DOCTEST]); } #[test] @@ -427,6 +499,7 @@ mod tests { ] "### ); + assert_actions(&runnables, &[&BIN, &DOCTEST]); } #[test] @@ -493,6 +566,7 @@ mod tests { ] "### ); + assert_actions(&runnables, &[&TEST, &TEST]); } #[test] @@ -561,6 +635,7 @@ mod tests { ] "### ); + assert_actions(&runnables, &[&TEST, &TEST]); } #[test] @@ -631,6 +706,7 @@ mod tests { ] "### ); + assert_actions(&runnables, &[&TEST, &TEST]); } #[test] @@ -681,6 +757,7 @@ mod tests { ] "### ); + assert_actions(&runnables, &[&TEST]); } #[test] @@ -739,6 +816,7 @@ mod tests { ] "### ); + assert_actions(&runnables, &[&TEST]); } #[test] diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs index 3ff7797024..da16976d3d 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::{ TextDocumentIdentifier, Url, WorkspaceEdit, }; use ra_ide::{ - FileId, FilePosition, FileRange, HoverAction, Query, RangeInfo, RunnableKind, SearchScope, + FileId, FilePosition, FileRange, HoverAction, Query, RangeInfo, Runnable, RunnableKind, SearchScope, TextEdit, }; use ra_prof::profile; @@ -403,16 +403,11 @@ pub fn handle_runnables( if !runnable.nav.full_range().contains_inclusive(offset) { continue; } + } + if is_lib_target(&runnable, cargo_spec.as_ref()) { + continue; } - // Do not suggest binary run on other target than binary - if let RunnableKind::Bin = runnable.kind { - if let Some(spec) = &cargo_spec { - match spec.target_kind { - TargetKind::Bin => {} - _ => continue, - } - } - } + res.push(to_proto::runnable(&snap, file_id, runnable)?); } @@ -817,53 +812,26 @@ pub fn handle_code_lens( if snap.config.lens.runnable() { // Gather runnables for runnable in snap.analysis().runnables(file_id)? { - let (run_title, debugee) = match &runnable.kind { - RunnableKind::Test { .. } | RunnableKind::TestMod { .. } => { - ("▶\u{fe0e} Run Test", true) - } - RunnableKind::DocTest { .. } => { - // cargo does not support -no-run for doctests - ("▶\u{fe0e} Run Doctest", false) - } - RunnableKind::Bench { .. } => { - // Nothing wrong with bench debugging - ("Run Bench", true) - } - RunnableKind::Bin => { - // Do not suggest binary run on other target than binary - match &cargo_spec { - Some(spec) => match spec.target_kind { - TargetKind::Bin => ("Run", true), - _ => continue, - }, - None => continue, - } - } - }; + if is_lib_target(&runnable, cargo_spec.as_ref()) { + continue; + } + let action = runnable.action(); let range = to_proto::range(&line_index, runnable.nav.range()); let r = to_proto::runnable(&snap, file_id, runnable)?; if snap.config.lens.run { let lens = CodeLens { range, - command: Some(Command { - title: run_title.to_string(), - command: "rust-analyzer.runSingle".into(), - arguments: Some(vec![to_value(&r).unwrap()]), - }), + command: Some(run_single_command(&r, action.run_title)), data: None, }; lenses.push(lens); } - if debugee && snap.config.lens.debug { + if action.debugee && snap.config.lens.debug { let debug_lens = CodeLens { range, - command: Some(Command { - title: "Debug".into(), - command: "rust-analyzer.debugSingle".into(), - arguments: Some(vec![to_value(r).unwrap()]), - }), + command: Some(debug_single_command(r)), data: None, }; lenses.push(debug_lens); @@ -1169,6 +1137,22 @@ fn show_references_command( } } +fn run_single_command(runnable: &lsp_ext::Runnable, title: &str) -> Command { + Command { + title: title.to_string(), + command: "rust-analyzer.runSingle".into(), + arguments: Some(vec![to_value(runnable).unwrap()]), + } +} + +fn debug_single_command(runnable: lsp_ext::Runnable) -> Command { + Command { + title: "Debug".into(), + command: "rust-analyzer.debugSingle".into(), + arguments: Some(vec![to_value(runnable).unwrap()]), + } +} + fn to_command_link(command: Command, tooltip: String) -> lsp_ext::CommandLink { lsp_ext::CommandLink { tooltip: Some(tooltip), command } } @@ -1214,3 +1198,17 @@ fn prepare_hover_actions( }) .collect() } + +fn is_lib_target(runnable: &Runnable, cargo_spec: Option<&CargoTargetSpec>) -> bool { + // Do not suggest binary run on other target than binary + if let RunnableKind::Bin = runnable.kind { + if let Some(spec) = cargo_spec { + match spec.target_kind { + TargetKind::Bin => return true, + _ => () + } + } + } + + false +} \ 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 1da4d80ece..710df1fbde 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -4,7 +4,7 @@ use ra_ide::{ Assist, CompletionItem, CompletionItemKind, Documentation, FileSystemEdit, Fold, FoldKind, FunctionSignature, Highlight, HighlightModifier, HighlightTag, HighlightedRange, Indel, InlayHint, InlayKind, InsertTextFormat, LineIndex, NavigationTarget, ReferenceAccess, - ResolvedAssist, Runnable, RunnableKind, Severity, SourceChange, SourceFileEdit, TextEdit, + ResolvedAssist, Runnable, Severity, SourceChange, SourceFileEdit, TextEdit, }; use ra_syntax::{SyntaxKind, TextRange, TextSize}; use ra_vfs::LineEndings; @@ -662,15 +662,7 @@ pub(crate) fn runnable( let target = spec.as_ref().map(|s| s.target.clone()); let (cargo_args, executable_args) = CargoTargetSpec::runnable_args(spec, &runnable.kind, &runnable.cfg_exprs)?; - let label = match &runnable.kind { - RunnableKind::Test { test_id, .. } => format!("test {}", test_id), - RunnableKind::TestMod { path } => format!("test-mod {}", path), - RunnableKind::Bench { test_id } => format!("bench {}", test_id), - RunnableKind::DocTest { test_id, .. } => format!("doctest {}", test_id), - RunnableKind::Bin => { - target.map_or_else(|| "run binary".to_string(), |t| format!("run {}", t)) - } - }; + let label = runnable.label(target); let location = location_link(snap, None, runnable.nav)?; Ok(lsp_ext::Runnable { From 3434f1dd2c47fff3df159b9d62115c2df3fd6401 Mon Sep 17 00:00:00 2001 From: vsrs Date: Sat, 6 Jun 2020 14:30:29 +0300 Subject: [PATCH 2/5] Add Run|Debug hover actions --- crates/ra_ide/src/hover.rs | 129 +++++++++++++++++- crates/ra_ide/src/runnables.rs | 14 +- crates/rust-analyzer/src/config.rs | 2 + .../rust-analyzer/src/main_loop/handlers.rs | 49 +++++-- crates/rust-analyzer/src/to_proto.rs | 4 +- editors/code/package.json | 10 ++ 6 files changed, 184 insertions(+), 24 deletions(-) diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs index 846d8c69ba..138a7a7a9c 100644 --- a/crates/ra_ide/src/hover.rs +++ b/crates/ra_ide/src/hover.rs @@ -14,34 +14,42 @@ use ra_syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffs use crate::{ display::{macro_label, rust_code_markup, rust_code_markup_with_doc, ShortLabel, ToNav}, - FilePosition, NavigationTarget, RangeInfo, + runnables::runnable, + FileId, FilePosition, NavigationTarget, RangeInfo, Runnable, }; #[derive(Clone, Debug, PartialEq, Eq)] pub struct HoverConfig { pub implementations: bool, + pub run: bool, + pub debug: bool, } impl Default for HoverConfig { fn default() -> Self { - Self { implementations: true } + Self { implementations: true, run: true, debug: true } } } impl HoverConfig { - pub const NO_ACTIONS: Self = Self { implementations: false }; + pub const NO_ACTIONS: Self = Self { implementations: false, run: false, debug: false }; pub fn any(&self) -> bool { - self.implementations + self.implementations || self.runnable() } pub fn none(&self) -> bool { !self.any() } + + pub fn runnable(&self) -> bool { + self.run || self.debug + } } #[derive(Debug, Clone)] pub enum HoverAction { + Runnable(Runnable), Implementaion(FilePosition), } @@ -125,6 +133,10 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option Option, + def: Definition, + file_id: FileId, +) -> Option { + match def { + Definition::ModuleDef(it) => match it { + ModuleDef::Module(it) => match it.definition_source(sema.db).value { + ModuleSource::Module(it) => runnable(&sema, it.syntax().clone(), file_id) + .map(|it| HoverAction::Runnable(it)), + _ => None, + }, + ModuleDef::Function(it) => { + runnable(&sema, it.source(sema.db).value.syntax().clone(), file_id) + .map(|it| HoverAction::Runnable(it)) + } + _ => None, + }, + _ => None, + } +} + fn hover_text( docs: Option, desc: Option, @@ -292,6 +326,7 @@ fn pick_best(tokens: TokenAtOffset) -> Option { #[cfg(test)] mod tests { use super::*; + use insta::assert_debug_snapshot; use ra_db::FileLoader; use ra_syntax::TextRange; @@ -309,6 +344,7 @@ mod tests { fn assert_impl_action(action: &HoverAction, position: u32) { let offset = match action { HoverAction::Implementaion(pos) => pos.offset, + it => panic!("Unexpected hover action: {:#?}", it), }; assert_eq!(offset, position.into()); } @@ -1176,4 +1212,89 @@ fn func(foo: i32) { if true { <|>foo; }; } ); assert_impl_action(&actions[0], 5); } + + #[test] + fn test_hover_test_has_action() { + let (_, actions) = check_hover_result( + " + //- /lib.rs + #[test] + fn foo_<|>test() {} + ", + &["fn foo_test()"], + ); + assert_debug_snapshot!(actions, + @r###" + [ + Runnable( + Runnable { + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 0..24, + name: "foo_test", + kind: FN_DEF, + focus_range: Some( + 11..19, + ), + container_name: None, + description: None, + docs: None, + }, + kind: Test { + test_id: Path( + "foo_test", + ), + attr: TestAttr { + ignore: false, + }, + }, + cfg_exprs: [], + }, + ), + ] + "###); + } + + #[test] + fn test_hover_test_mod_has_action() { + let (_, actions) = check_hover_result( + " + //- /lib.rs + mod tests<|> { + #[test] + fn foo_test() {} + } + ", + &["mod tests"], + ); + assert_debug_snapshot!(actions, + @r###" + [ + Runnable( + Runnable { + nav: NavigationTarget { + file_id: FileId( + 1, + ), + full_range: 0..46, + name: "tests", + kind: MODULE, + focus_range: Some( + 4..9, + ), + container_name: None, + description: None, + docs: None, + }, + kind: TestMod { + path: "tests", + }, + cfg_exprs: [], + }, + ), + ] + "###); + } } diff --git a/crates/ra_ide/src/runnables.rs b/crates/ra_ide/src/runnables.rs index 9f7b5edfd5..fc57dc33d7 100644 --- a/crates/ra_ide/src/runnables.rs +++ b/crates/ra_ide/src/runnables.rs @@ -11,14 +11,14 @@ use ra_syntax::{ use crate::{display::ToNav, FileId, NavigationTarget}; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct Runnable { pub nav: NavigationTarget, pub kind: RunnableKind, pub cfg_exprs: Vec, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum TestId { Name(String), Path(String), @@ -33,7 +33,7 @@ impl fmt::Display for TestId { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum RunnableKind { Test { test_id: TestId, attr: TestAttr }, TestMod { path: String }, @@ -95,7 +95,11 @@ pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec { source_file.syntax().descendants().filter_map(|i| runnable(&sema, i, file_id)).collect() } -fn runnable(sema: &Semantics, item: SyntaxNode, file_id: FileId) -> Option { +pub(crate) fn runnable( + sema: &Semantics, + item: SyntaxNode, + file_id: FileId, +) -> Option { match_ast! { match item { ast::FnDef(it) => runnable_fn(sema, it, file_id), @@ -171,7 +175,7 @@ fn runnable_fn( Some(Runnable { nav, kind, cfg_exprs }) } -#[derive(Debug)] +#[derive(Debug, Copy, Clone)] pub struct TestAttr { pub ignore: bool, } diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 8d6efdbe8c..17671f89ee 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -285,6 +285,8 @@ impl Config { set(value, "/hoverActions/enable", &mut use_hover_actions); if use_hover_actions { set(value, "/hoverActions/implementations", &mut self.hover.implementations); + set(value, "/hoverActions/run", &mut self.hover.run); + set(value, "/hoverActions/debug", &mut self.hover.debug); } else { self.hover = HoverConfig::NO_ACTIONS; } diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs index da16976d3d..cae447eea8 100644 --- a/crates/rust-analyzer/src/main_loop/handlers.rs +++ b/crates/rust-analyzer/src/main_loop/handlers.rs @@ -18,8 +18,8 @@ use lsp_types::{ TextDocumentIdentifier, Url, WorkspaceEdit, }; use ra_ide::{ - FileId, FilePosition, FileRange, HoverAction, Query, RangeInfo, Runnable, RunnableKind, SearchScope, - TextEdit, + FileId, FilePosition, FileRange, HoverAction, Query, RangeInfo, Runnable, RunnableKind, + SearchScope, TextEdit, }; use ra_prof::profile; use ra_project_model::TargetKind; @@ -403,12 +403,12 @@ pub fn handle_runnables( if !runnable.nav.full_range().contains_inclusive(offset) { continue; } - } + } if is_lib_target(&runnable, cargo_spec.as_ref()) { continue; } - res.push(to_proto::runnable(&snap, file_id, runnable)?); + res.push(to_proto::runnable(&snap, file_id, &runnable)?); } // Add `cargo check` and `cargo test` for the whole package @@ -550,7 +550,7 @@ pub fn handle_hover( }), range: Some(range), }, - actions: prepare_hover_actions(&snap, info.info.actions()), + actions: prepare_hover_actions(&snap, position.file_id, info.info.actions()), }; Ok(Some(hover)) @@ -818,7 +818,7 @@ pub fn handle_code_lens( let action = runnable.action(); let range = to_proto::range(&line_index, runnable.nav.range()); - let r = to_proto::runnable(&snap, file_id, runnable)?; + let r = to_proto::runnable(&snap, file_id, &runnable)?; if snap.config.lens.run { let lens = CodeLens { range, @@ -829,11 +829,8 @@ pub fn handle_code_lens( } if action.debugee && snap.config.lens.debug { - let debug_lens = CodeLens { - range, - command: Some(debug_single_command(r)), - data: None, - }; + let debug_lens = + CodeLens { range, command: Some(debug_single_command(r)), data: None }; lenses.push(debug_lens); } } @@ -1183,8 +1180,33 @@ fn show_impl_command_link( None } +fn to_runnable_action( + snap: &GlobalStateSnapshot, + file_id: FileId, + runnable: &Runnable, +) -> Option { + to_proto::runnable(snap, file_id, runnable).ok().map(|r| { + let mut group = lsp_ext::CommandLinkGroup::default(); + + let action = runnable.action(); + if snap.config.hover.run { + let run_command = run_single_command(&r, action.run_title); + group.commands.push(to_command_link(run_command, r.label.clone())); + } + + if snap.config.hover.debug { + let hint = r.label.clone(); + let dbg_command = debug_single_command(r); + group.commands.push(to_command_link(dbg_command, hint)); + } + + group + }) +} + fn prepare_hover_actions( snap: &GlobalStateSnapshot, + file_id: FileId, actions: &[HoverAction], ) -> Vec { if snap.config.hover.none() || !snap.config.client_caps.hover_actions { @@ -1195,6 +1217,7 @@ fn prepare_hover_actions( .iter() .filter_map(|it| match it { HoverAction::Implementaion(position) => show_impl_command_link(snap, position), + HoverAction::Runnable(r) => to_runnable_action(snap, file_id, r), }) .collect() } @@ -1205,10 +1228,10 @@ fn is_lib_target(runnable: &Runnable, cargo_spec: Option<&CargoTargetSpec>) -> b if let Some(spec) = cargo_spec { match spec.target_kind { TargetKind::Bin => return true, - _ => () + _ => (), } } } false -} \ 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 710df1fbde..5daf037dab 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -656,14 +656,14 @@ pub(crate) fn resolved_code_action( pub(crate) fn runnable( snap: &GlobalStateSnapshot, file_id: FileId, - runnable: Runnable, + runnable: &Runnable, ) -> Result { let spec = CargoTargetSpec::for_file(snap, file_id)?; let target = spec.as_ref().map(|s| s.target.clone()); let (cargo_args, executable_args) = CargoTargetSpec::runnable_args(spec, &runnable.kind, &runnable.cfg_exprs)?; let label = runnable.label(target); - let location = location_link(snap, None, runnable.nav)?; + let location = location_link(snap, None, runnable.nav.clone())?; Ok(lsp_ext::Runnable { label, diff --git a/editors/code/package.json b/editors/code/package.json index b9c57db3bc..7fdb5c27d9 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -486,6 +486,16 @@ "type": "boolean", "default": true }, + "rust-analyzer.hoverActions.run": { + "markdownDescription": "Whether to show `Run` action. Only applies when `#rust-analyzer.hoverActions.enable#` is set.", + "type": "boolean", + "default": true + }, + "rust-analyzer.hoverActions.debug": { + "markdownDescription": "Whether to show `Debug` action. Only applies when `#rust-analyzer.hoverActions.enable#` is set.", + "type": "boolean", + "default": true + }, "rust-analyzer.linkedProjects": { "markdownDescription": [ "Disable project auto-discovery in favor of explicitly specified set of projects.", From 46084f8a96dc94cad06c269d93269e7c5f7e4fad Mon Sep 17 00:00:00 2001 From: vsrs Date: Sat, 6 Jun 2020 20:10:36 +0300 Subject: [PATCH 3/5] Disable runnables lookup in macro-generated code. --- crates/ra_ide/src/hover.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs index 138a7a7a9c..bbff5e81a4 100644 --- a/crates/ra_ide/src/hover.rs +++ b/crates/ra_ide/src/hover.rs @@ -200,7 +200,16 @@ fn runnable_action( _ => None, }, ModuleDef::Function(it) => { - runnable(&sema, it.source(sema.db).value.syntax().clone(), file_id) + let src = it.source(sema.db); + if src.file_id != file_id.into() { + // Don't try to find runnables in a macro generated code. + // See tests below: + // test_hover_macro_generated_struct_fn_doc_comment + // test_hover_macro_generated_struct_fn_doc_attr + return None; + } + + runnable(&sema, src.value.syntax().clone(), file_id) .map(|it| HoverAction::Runnable(it)) } _ => None, From 9b4256dc4d9e0b633b73f5c07e6e0721bc1e9108 Mon Sep 17 00:00:00 2001 From: vsrs Date: Sat, 6 Jun 2020 22:11:17 +0300 Subject: [PATCH 4/5] Add lib target filtering. --- .../rust-analyzer/src/main_loop/handlers.rs | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs index cae447eea8..eaa43f2bdc 100644 --- a/crates/rust-analyzer/src/main_loop/handlers.rs +++ b/crates/rust-analyzer/src/main_loop/handlers.rs @@ -404,7 +404,7 @@ pub fn handle_runnables( continue; } } - if is_lib_target(&runnable, cargo_spec.as_ref()) { + if should_skip_target(&runnable, cargo_spec.as_ref()) { continue; } @@ -812,7 +812,7 @@ pub fn handle_code_lens( if snap.config.lens.runnable() { // Gather runnables for runnable in snap.analysis().runnables(file_id)? { - if is_lib_target(&runnable, cargo_spec.as_ref()) { + if should_skip_target(&runnable, cargo_spec.as_ref()) { continue; } @@ -1185,6 +1185,11 @@ fn to_runnable_action( file_id: FileId, runnable: &Runnable, ) -> Option { + let cargo_spec = CargoTargetSpec::for_file(&snap, file_id).ok()?; + if should_skip_target(runnable, cargo_spec.as_ref()) { + return None; + } + to_proto::runnable(snap, file_id, runnable).ok().map(|r| { let mut group = lsp_ext::CommandLinkGroup::default(); @@ -1222,16 +1227,18 @@ fn prepare_hover_actions( .collect() } -fn is_lib_target(runnable: &Runnable, cargo_spec: Option<&CargoTargetSpec>) -> bool { - // Do not suggest binary run on other target than binary - if let RunnableKind::Bin = runnable.kind { - if let Some(spec) = cargo_spec { - match spec.target_kind { - TargetKind::Bin => return true, - _ => (), +fn should_skip_target(runnable: &Runnable, cargo_spec: Option<&CargoTargetSpec>) -> bool { + match runnable.kind { + RunnableKind::Bin => { + // Do not suggest binary run on other target than binary + match &cargo_spec { + Some(spec) => match spec.target_kind { + TargetKind::Bin => false, + _ => true, + }, + None => true, } } + _ => false, } - - false } From b7db9f058ad51b7ba47db02b581a76b6756d74e8 Mon Sep 17 00:00:00 2001 From: vsrs Date: Mon, 8 Jun 2020 13:56:31 +0300 Subject: [PATCH 5/5] Apply suggestions from code review --- crates/ra_ide/src/hover.rs | 12 ++++++--- .../rust-analyzer/src/main_loop/handlers.rs | 26 ++++++++----------- crates/rust-analyzer/src/to_proto.rs | 4 +-- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs index bbff5e81a4..ad78b76712 100644 --- a/crates/ra_ide/src/hover.rs +++ b/crates/ra_ide/src/hover.rs @@ -17,6 +17,7 @@ use crate::{ runnables::runnable, FileId, FilePosition, NavigationTarget, RangeInfo, Runnable, }; +use test_utils::mark; #[derive(Clone, Debug, PartialEq, Eq)] pub struct HoverConfig { @@ -202,10 +203,9 @@ fn runnable_action( ModuleDef::Function(it) => { let src = it.source(sema.db); if src.file_id != file_id.into() { - // Don't try to find runnables in a macro generated code. - // See tests below: - // test_hover_macro_generated_struct_fn_doc_comment - // test_hover_macro_generated_struct_fn_doc_attr + mark::hit!(hover_macro_generated_struct_fn_doc_comment); + mark::hit!(hover_macro_generated_struct_fn_doc_attr); + return None; } @@ -1121,6 +1121,8 @@ fn func(foo: i32) { if true { <|>foo; }; } #[test] fn test_hover_macro_generated_struct_fn_doc_comment() { + mark::check!(hover_macro_generated_struct_fn_doc_comment); + check_hover_result( r#" //- /lib.rs @@ -1147,6 +1149,8 @@ fn func(foo: i32) { if true { <|>foo; }; } #[test] fn test_hover_macro_generated_struct_fn_doc_attr() { + mark::check!(hover_macro_generated_struct_fn_doc_attr); + check_hover_result( r#" //- /lib.rs diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs index eaa43f2bdc..a41adf8b0b 100644 --- a/crates/rust-analyzer/src/main_loop/handlers.rs +++ b/crates/rust-analyzer/src/main_loop/handlers.rs @@ -408,7 +408,7 @@ pub fn handle_runnables( continue; } - res.push(to_proto::runnable(&snap, file_id, &runnable)?); + res.push(to_proto::runnable(&snap, file_id, runnable)?); } // Add `cargo check` and `cargo test` for the whole package @@ -818,7 +818,7 @@ pub fn handle_code_lens( let action = runnable.action(); let range = to_proto::range(&line_index, runnable.nav.range()); - let r = to_proto::runnable(&snap, file_id, &runnable)?; + let r = to_proto::runnable(&snap, file_id, runnable)?; if snap.config.lens.run { let lens = CodeLens { range, @@ -830,7 +830,7 @@ pub fn handle_code_lens( if action.debugee && snap.config.lens.debug { let debug_lens = - CodeLens { range, command: Some(debug_single_command(r)), data: None }; + CodeLens { range, command: Some(debug_single_command(&r)), data: None }; lenses.push(debug_lens); } } @@ -1142,7 +1142,7 @@ fn run_single_command(runnable: &lsp_ext::Runnable, title: &str) -> Command { } } -fn debug_single_command(runnable: lsp_ext::Runnable) -> Command { +fn debug_single_command(runnable: &lsp_ext::Runnable) -> Command { Command { title: "Debug".into(), command: "rust-analyzer.debugSingle".into(), @@ -1183,26 +1183,25 @@ fn show_impl_command_link( fn to_runnable_action( snap: &GlobalStateSnapshot, file_id: FileId, - runnable: &Runnable, + runnable: Runnable, ) -> Option { let cargo_spec = CargoTargetSpec::for_file(&snap, file_id).ok()?; - if should_skip_target(runnable, cargo_spec.as_ref()) { + if should_skip_target(&runnable, cargo_spec.as_ref()) { return None; } + let action: &'static _ = runnable.action(); to_proto::runnable(snap, file_id, runnable).ok().map(|r| { let mut group = lsp_ext::CommandLinkGroup::default(); - let action = runnable.action(); if snap.config.hover.run { let run_command = run_single_command(&r, action.run_title); group.commands.push(to_command_link(run_command, r.label.clone())); } if snap.config.hover.debug { - let hint = r.label.clone(); - let dbg_command = debug_single_command(r); - group.commands.push(to_command_link(dbg_command, hint)); + let dbg_command = debug_single_command(&r); + group.commands.push(to_command_link(dbg_command, r.label)); } group @@ -1222,7 +1221,7 @@ fn prepare_hover_actions( .iter() .filter_map(|it| match it { HoverAction::Implementaion(position) => show_impl_command_link(snap, position), - HoverAction::Runnable(r) => to_runnable_action(snap, file_id, r), + HoverAction::Runnable(r) => to_runnable_action(snap, file_id, r.clone()), }) .collect() } @@ -1232,10 +1231,7 @@ fn should_skip_target(runnable: &Runnable, cargo_spec: Option<&CargoTargetSpec>) RunnableKind::Bin => { // Do not suggest binary run on other target than binary match &cargo_spec { - Some(spec) => match spec.target_kind { - TargetKind::Bin => false, - _ => true, - }, + Some(spec) => spec.target_kind != TargetKind::Bin, None => true, } } diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 5daf037dab..710df1fbde 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -656,14 +656,14 @@ pub(crate) fn resolved_code_action( pub(crate) fn runnable( snap: &GlobalStateSnapshot, file_id: FileId, - runnable: &Runnable, + runnable: Runnable, ) -> Result { let spec = CargoTargetSpec::for_file(snap, file_id)?; let target = spec.as_ref().map(|s| s.target.clone()); let (cargo_args, executable_args) = CargoTargetSpec::runnable_args(spec, &runnable.kind, &runnable.cfg_exprs)?; let label = runnable.label(target); - let location = location_link(snap, None, runnable.nav.clone())?; + let location = location_link(snap, None, runnable.nav)?; Ok(lsp_ext::Runnable { label,