diff options
Diffstat (limited to 'crates/ide/src/runnables.rs')
-rw-r--r-- | crates/ide/src/runnables.rs | 59 |
1 files changed, 20 insertions, 39 deletions
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs index 27d35de5b..17454f270 100644 --- a/crates/ide/src/runnables.rs +++ b/crates/ide/src/runnables.rs | |||
@@ -2,6 +2,7 @@ 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::{ |
@@ -102,13 +103,27 @@ impl Runnable { | |||
102 | // |=== | 103 | // |=== |
103 | pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { | 104 | pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { |
104 | let sema = Semantics::new(db); | 105 | 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 | 106 | ||
110 | let mut res = Vec::new(); | 107 | let mut res = Vec::new(); |
111 | runnables_mod(&sema, &mut res, module); | 108 | sema.visit_file_defs(file_id, &mut |def| match def { |
109 | Either::Left(def) => { | ||
110 | let runnable = match def { | ||
111 | hir::ModuleDef::Module(it) => runnable_mod(&sema, it), | ||
112 | hir::ModuleDef::Function(it) => runnable_fn(&sema, it), | ||
113 | _ => None, | ||
114 | }; | ||
115 | res.extend(runnable.or_else(|| module_def_doctest(&sema, def))) | ||
116 | } | ||
117 | Either::Right(impl_) => { | ||
118 | res.extend(impl_.items(db).into_iter().filter_map(|assoc| match assoc { | ||
119 | hir::AssocItem::Function(it) => { | ||
120 | runnable_fn(&sema, it).or_else(|| module_def_doctest(&sema, it.into())) | ||
121 | } | ||
122 | hir::AssocItem::Const(it) => module_def_doctest(&sema, it.into()), | ||
123 | hir::AssocItem::TypeAlias(it) => module_def_doctest(&sema, it.into()), | ||
124 | })) | ||
125 | } | ||
126 | }); | ||
112 | res | 127 | res |
113 | } | 128 | } |
114 | 129 | ||
@@ -211,39 +226,6 @@ fn parent_test_module(sema: &Semantics<RootDatabase>, fn_def: &ast::Fn) -> Optio | |||
211 | }) | 226 | }) |
212 | } | 227 | } |
213 | 228 | ||
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> { | 229 | pub(crate) fn runnable_fn(sema: &Semantics<RootDatabase>, def: hir::Function) -> Option<Runnable> { |
248 | let func = def.source(sema.db)?; | 230 | let func = def.source(sema.db)?; |
249 | let name_string = def.name(sema.db).to_string(); | 231 | let name_string = def.name(sema.db).to_string(); |
@@ -1178,7 +1160,6 @@ mod tests { | |||
1178 | 1160 | ||
1179 | #[test] | 1161 | #[test] |
1180 | fn dont_recurse_in_outline_submodules() { | 1162 | fn dont_recurse_in_outline_submodules() { |
1181 | cov_mark::check!(dont_recurse_in_outline_submodules); | ||
1182 | check( | 1163 | check( |
1183 | r#" | 1164 | r#" |
1184 | //- /lib.rs | 1165 | //- /lib.rs |