diff options
Diffstat (limited to 'crates/ide/src/runnables.rs')
-rw-r--r-- | crates/ide/src/runnables.rs | 60 |
1 files changed, 21 insertions, 39 deletions
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs index 27d35de5b..0c7a8fbf8 100644 --- a/crates/ide/src/runnables.rs +++ b/crates/ide/src/runnables.rs | |||
@@ -2,11 +2,13 @@ use std::fmt; | |||
2 | 2 | ||
3 | use ast::NameOwner; | 3 | use ast::NameOwner; |
4 | use cfg::CfgExpr; | 4 | use cfg::CfgExpr; |
5 | use either::Either; | ||
5 | use hir::{AsAssocItem, HasAttrs, HasSource, HirDisplay, Semantics}; | 6 | use hir::{AsAssocItem, HasAttrs, HasSource, HirDisplay, Semantics}; |
6 | use ide_assists::utils::test_related_attribute; | 7 | use ide_assists::utils::test_related_attribute; |
7 | use ide_db::{ | 8 | use ide_db::{ |
8 | base_db::{FilePosition, FileRange}, | 9 | base_db::{FilePosition, FileRange}, |
9 | defs::Definition, | 10 | defs::Definition, |
11 | helpers::visit_file_defs, | ||
10 | search::SearchScope, | 12 | search::SearchScope, |
11 | RootDatabase, SymbolKind, | 13 | RootDatabase, SymbolKind, |
12 | }; | 14 | }; |
@@ -102,13 +104,27 @@ impl Runnable { | |||
102 | // |=== | 104 | // |=== |
103 | pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { | 105 | pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { |
104 | let sema = Semantics::new(db); | 106 | let sema = Semantics::new(db); |
105 | let module = match sema.to_module_def(file_id) { | ||
106 | None => return Vec::new(), | ||
107 | Some(it) => it, | ||
108 | }; | ||
109 | 107 | ||
110 | let mut res = Vec::new(); | 108 | let mut res = Vec::new(); |
111 | runnables_mod(&sema, &mut res, module); | 109 | visit_file_defs(&sema, file_id, &mut |def| match def { |
110 | Either::Left(def) => { | ||
111 | let runnable = match def { | ||
112 | hir::ModuleDef::Module(it) => runnable_mod(&sema, it), | ||
113 | hir::ModuleDef::Function(it) => runnable_fn(&sema, it), | ||
114 | _ => None, | ||
115 | }; | ||
116 | res.extend(runnable.or_else(|| module_def_doctest(&sema, def))) | ||
117 | } | ||
118 | Either::Right(impl_) => { | ||
119 | res.extend(impl_.items(db).into_iter().filter_map(|assoc| match assoc { | ||
120 | hir::AssocItem::Function(it) => { | ||
121 | runnable_fn(&sema, it).or_else(|| module_def_doctest(&sema, it.into())) | ||
122 | } | ||
123 | hir::AssocItem::Const(it) => module_def_doctest(&sema, it.into()), | ||
124 | hir::AssocItem::TypeAlias(it) => module_def_doctest(&sema, it.into()), | ||
125 | })) | ||
126 | } | ||
127 | }); | ||
112 | res | 128 | res |
113 | } | 129 | } |
114 | 130 | ||
@@ -211,39 +227,6 @@ fn parent_test_module(sema: &Semantics<RootDatabase>, fn_def: &ast::Fn) -> Optio | |||
211 | }) | 227 | }) |
212 | } | 228 | } |
213 | 229 | ||
214 | fn runnables_mod(sema: &Semantics<RootDatabase>, acc: &mut Vec<Runnable>, module: hir::Module) { | ||
215 | acc.extend(module.declarations(sema.db).into_iter().filter_map(|def| { | ||
216 | let runnable = match def { | ||
217 | hir::ModuleDef::Module(it) => runnable_mod(&sema, it), | ||
218 | hir::ModuleDef::Function(it) => runnable_fn(&sema, it), | ||
219 | _ => None, | ||
220 | }; | ||
221 | runnable.or_else(|| module_def_doctest(&sema, def)) | ||
222 | })); | ||
223 | |||
224 | acc.extend(module.impl_defs(sema.db).into_iter().flat_map(|it| it.items(sema.db)).filter_map( | ||
225 | |def| match def { | ||
226 | hir::AssocItem::Function(it) => { | ||
227 | runnable_fn(&sema, it).or_else(|| module_def_doctest(&sema, it.into())) | ||
228 | } | ||
229 | hir::AssocItem::Const(it) => module_def_doctest(&sema, it.into()), | ||
230 | hir::AssocItem::TypeAlias(it) => module_def_doctest(&sema, it.into()), | ||
231 | }, | ||
232 | )); | ||
233 | |||
234 | for def in module.declarations(sema.db) { | ||
235 | if let hir::ModuleDef::Module(submodule) = def { | ||
236 | match submodule.definition_source(sema.db).value { | ||
237 | hir::ModuleSource::Module(_) => runnables_mod(sema, acc, submodule), | ||
238 | hir::ModuleSource::SourceFile(_) => { | ||
239 | cov_mark::hit!(dont_recurse_in_outline_submodules) | ||
240 | } | ||
241 | hir::ModuleSource::BlockExpr(_) => {} // inner items aren't runnable | ||
242 | } | ||
243 | } | ||
244 | } | ||
245 | } | ||
246 | |||
247 | pub(crate) fn runnable_fn(sema: &Semantics<RootDatabase>, def: hir::Function) -> Option<Runnable> { | 230 | pub(crate) fn runnable_fn(sema: &Semantics<RootDatabase>, def: hir::Function) -> Option<Runnable> { |
248 | let func = def.source(sema.db)?; | 231 | let func = def.source(sema.db)?; |
249 | let name_string = def.name(sema.db).to_string(); | 232 | let name_string = def.name(sema.db).to_string(); |
@@ -1178,7 +1161,6 @@ mod tests { | |||
1178 | 1161 | ||
1179 | #[test] | 1162 | #[test] |
1180 | fn dont_recurse_in_outline_submodules() { | 1163 | fn dont_recurse_in_outline_submodules() { |
1181 | cov_mark::check!(dont_recurse_in_outline_submodules); | ||
1182 | check( | 1164 | check( |
1183 | r#" | 1165 | r#" |
1184 | //- /lib.rs | 1166 | //- /lib.rs |