aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/runnables.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide/src/runnables.rs')
-rw-r--r--crates/ide/src/runnables.rs59
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
3use ast::NameOwner; 3use ast::NameOwner;
4use cfg::CfgExpr; 4use cfg::CfgExpr;
5use either::Either;
5use hir::{AsAssocItem, HasAttrs, HasSource, HirDisplay, Semantics}; 6use hir::{AsAssocItem, HasAttrs, HasSource, HirDisplay, Semantics};
6use ide_assists::utils::test_related_attribute; 7use ide_assists::utils::test_related_attribute;
7use ide_db::{ 8use ide_db::{
@@ -102,13 +103,27 @@ impl Runnable {
102// |=== 103// |===
103pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { 104pub(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
214fn 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
247pub(crate) fn runnable_fn(sema: &Semantics<RootDatabase>, def: hir::Function) -> Option<Runnable> { 229pub(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