diff options
Diffstat (limited to 'crates/ide/src')
-rw-r--r-- | crates/ide/src/hover.rs | 4 | ||||
-rw-r--r-- | crates/ide/src/runnables.rs | 75 |
2 files changed, 42 insertions, 37 deletions
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 8cb4a51d8..939efa43f 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs | |||
@@ -17,7 +17,7 @@ use crate::{ | |||
17 | doc_links::{remove_links, rewrite_links}, | 17 | doc_links::{remove_links, rewrite_links}, |
18 | markdown_remove::remove_markdown, | 18 | markdown_remove::remove_markdown, |
19 | markup::Markup, | 19 | markup::Markup, |
20 | runnables::{runnable, runnable_fn}, | 20 | runnables::{runnable_fn, runnable_mod}, |
21 | FileId, FilePosition, NavigationTarget, RangeInfo, Runnable, | 21 | FileId, FilePosition, NavigationTarget, RangeInfo, Runnable, |
22 | }; | 22 | }; |
23 | 23 | ||
@@ -192,7 +192,7 @@ fn runnable_action( | |||
192 | Definition::ModuleDef(it) => match it { | 192 | Definition::ModuleDef(it) => match it { |
193 | ModuleDef::Module(it) => match it.definition_source(sema.db).value { | 193 | ModuleDef::Module(it) => match it.definition_source(sema.db).value { |
194 | ModuleSource::Module(it) => { | 194 | ModuleSource::Module(it) => { |
195 | runnable(&sema, it.syntax().clone()).map(|it| HoverAction::Runnable(it)) | 195 | runnable_mod(&sema, it).map(|it| HoverAction::Runnable(it)) |
196 | } | 196 | } |
197 | _ => None, | 197 | _ => None, |
198 | }, | 198 | }, |
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs index 557563d7e..3a1e204db 100644 --- a/crates/ide/src/runnables.rs +++ b/crates/ide/src/runnables.rs | |||
@@ -96,21 +96,23 @@ impl Runnable { | |||
96 | pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { | 96 | pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { |
97 | let sema = Semantics::new(db); | 97 | let sema = Semantics::new(db); |
98 | let source_file = sema.parse(file_id); | 98 | let source_file = sema.parse(file_id); |
99 | source_file.syntax().descendants().filter_map(|i| runnable(&sema, i)).collect() | 99 | source_file |
100 | } | 100 | .syntax() |
101 | 101 | .descendants() | |
102 | pub(crate) fn runnable(sema: &Semantics<RootDatabase>, item: SyntaxNode) -> Option<Runnable> { | 102 | .filter_map(|item| { |
103 | let runnable_item = match_ast! { | 103 | let runnable = match_ast! { |
104 | match (item.clone()) { | 104 | match item { |
105 | ast::Fn(func) => { | 105 | ast::Fn(func) => { |
106 | let def = sema.to_def(&func)?; | 106 | let def = sema.to_def(&func)?; |
107 | runnable_fn(sema, def) | 107 | runnable_fn(&sema, def) |
108 | }, | 108 | }, |
109 | ast::Module(it) => runnable_mod(sema, it), | 109 | ast::Module(it) => runnable_mod(&sema, it), |
110 | _ => None, | 110 | _ => None, |
111 | } | 111 | } |
112 | }; | 112 | }; |
113 | runnable_item.or_else(|| runnable_doctest(sema, item)) | 113 | runnable.or_else(|| runnable_doctest(&sema, item)) |
114 | }) | ||
115 | .collect() | ||
114 | } | 116 | } |
115 | 117 | ||
116 | pub(crate) fn runnable_fn(sema: &Semantics<RootDatabase>, def: hir::Function) -> Option<Runnable> { | 118 | pub(crate) fn runnable_fn(sema: &Semantics<RootDatabase>, def: hir::Function) -> Option<Runnable> { |
@@ -145,6 +147,29 @@ pub(crate) fn runnable_fn(sema: &Semantics<RootDatabase>, def: hir::Function) -> | |||
145 | Some(Runnable { nav, kind, cfg }) | 147 | Some(Runnable { nav, kind, cfg }) |
146 | } | 148 | } |
147 | 149 | ||
150 | pub(crate) fn runnable_mod( | ||
151 | sema: &Semantics<RootDatabase>, | ||
152 | module: ast::Module, | ||
153 | ) -> Option<Runnable> { | ||
154 | if !has_test_function_or_multiple_test_submodules(&module) { | ||
155 | return None; | ||
156 | } | ||
157 | let module_def = sema.to_def(&module)?; | ||
158 | |||
159 | let path = module_def | ||
160 | .path_to_root(sema.db) | ||
161 | .into_iter() | ||
162 | .rev() | ||
163 | .filter_map(|it| it.name(sema.db)) | ||
164 | .join("::"); | ||
165 | |||
166 | let def = sema.to_def(&module)?; | ||
167 | let attrs = def.attrs(sema.db); | ||
168 | let cfg = attrs.cfg(); | ||
169 | let nav = module_def.to_nav(sema.db); | ||
170 | Some(Runnable { nav, kind: RunnableKind::TestMod { path }, cfg }) | ||
171 | } | ||
172 | |||
148 | fn runnable_doctest(sema: &Semantics<RootDatabase>, item: SyntaxNode) -> Option<Runnable> { | 173 | fn runnable_doctest(sema: &Semantics<RootDatabase>, item: SyntaxNode) -> Option<Runnable> { |
149 | match_ast! { | 174 | match_ast! { |
150 | match item { | 175 | match item { |
@@ -253,26 +278,6 @@ fn has_runnable_doc_test(attrs: &hir::Attrs) -> bool { | |||
253 | }) | 278 | }) |
254 | } | 279 | } |
255 | 280 | ||
256 | fn runnable_mod(sema: &Semantics<RootDatabase>, module: ast::Module) -> Option<Runnable> { | ||
257 | if !has_test_function_or_multiple_test_submodules(&module) { | ||
258 | return None; | ||
259 | } | ||
260 | let module_def = sema.to_def(&module)?; | ||
261 | |||
262 | let path = module_def | ||
263 | .path_to_root(sema.db) | ||
264 | .into_iter() | ||
265 | .rev() | ||
266 | .filter_map(|it| it.name(sema.db)) | ||
267 | .join("::"); | ||
268 | |||
269 | let def = sema.to_def(&module)?; | ||
270 | let attrs = def.attrs(sema.db); | ||
271 | let cfg = attrs.cfg(); | ||
272 | let nav = module_def.to_nav(sema.db); | ||
273 | Some(Runnable { nav, kind: RunnableKind::TestMod { path }, cfg }) | ||
274 | } | ||
275 | |||
276 | // We could create runnables for modules with number_of_test_submodules > 0, | 281 | // We could create runnables for modules with number_of_test_submodules > 0, |
277 | // but that bloats the runnables for no real benefit, since all tests can be run by the submodule already | 282 | // but that bloats the runnables for no real benefit, since all tests can be run by the submodule already |
278 | fn has_test_function_or_multiple_test_submodules(module: &ast::Module) -> bool { | 283 | fn has_test_function_or_multiple_test_submodules(module: &ast::Module) -> bool { |