diff options
Diffstat (limited to 'crates/ra_ide/src')
-rw-r--r-- | crates/ra_ide/src/runnables.rs | 70 |
1 files changed, 65 insertions, 5 deletions
diff --git a/crates/ra_ide/src/runnables.rs b/crates/ra_ide/src/runnables.rs index fa8a9d92c..009ea813a 100644 --- a/crates/ra_ide/src/runnables.rs +++ b/crates/ra_ide/src/runnables.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir::Semantics; | 3 | use hir::{AsAssocItem, HirDisplay, Semantics}; |
4 | use itertools::Itertools; | 4 | use itertools::Itertools; |
5 | use ra_ide_db::RootDatabase; | 5 | use ra_ide_db::RootDatabase; |
6 | use ra_syntax::{ | 6 | use ra_syntax::{ |
@@ -65,14 +65,36 @@ fn runnable_fn(sema: &Semantics<RootDatabase>, fn_def: ast::FnDef) -> Option<Run | |||
65 | RunnableKind::Bin | 65 | RunnableKind::Bin |
66 | } else { | 66 | } else { |
67 | let test_id = if let Some(module) = sema.to_def(&fn_def).map(|def| def.module(sema.db)) { | 67 | let test_id = if let Some(module) = sema.to_def(&fn_def).map(|def| def.module(sema.db)) { |
68 | let path = module | 68 | let def = sema.to_def(&fn_def)?; |
69 | let impl_trait_name = | ||
70 | def.as_assoc_item(sema.db).and_then(|assoc_item| { | ||
71 | match assoc_item.container(sema.db) { | ||
72 | hir::AssocItemContainer::Trait(trait_item) => { | ||
73 | Some(trait_item.name(sema.db).to_string()) | ||
74 | } | ||
75 | hir::AssocItemContainer::ImplDef(impl_def) => impl_def | ||
76 | .target_ty(sema.db) | ||
77 | .as_adt() | ||
78 | .map(|adt| adt.name(sema.db).to_string()), | ||
79 | } | ||
80 | }); | ||
81 | |||
82 | let path_iter = module | ||
69 | .path_to_root(sema.db) | 83 | .path_to_root(sema.db) |
70 | .into_iter() | 84 | .into_iter() |
71 | .rev() | 85 | .rev() |
72 | .filter_map(|it| it.name(sema.db)) | 86 | .filter_map(|it| it.name(sema.db)) |
73 | .map(|name| name.to_string()) | 87 | .map(|name| name.to_string()); |
74 | .chain(std::iter::once(name_string)) | 88 | |
75 | .join("::"); | 89 | let path = if let Some(impl_trait_name) = impl_trait_name { |
90 | path_iter | ||
91 | .chain(std::iter::once(impl_trait_name)) | ||
92 | .chain(std::iter::once(name_string)) | ||
93 | .join("::") | ||
94 | } else { | ||
95 | path_iter.chain(std::iter::once(name_string)).join("::") | ||
96 | }; | ||
97 | |||
76 | TestId::Path(path) | 98 | TestId::Path(path) |
77 | } else { | 99 | } else { |
78 | TestId::Name(name_string) | 100 | TestId::Name(name_string) |
@@ -238,6 +260,44 @@ mod tests { | |||
238 | } | 260 | } |
239 | 261 | ||
240 | #[test] | 262 | #[test] |
263 | fn test_runnables_doc_test_in_impl() { | ||
264 | let (analysis, pos) = analysis_and_position( | ||
265 | r#" | ||
266 | //- /lib.rs | ||
267 | <|> //empty | ||
268 | fn main() {} | ||
269 | |||
270 | struct Data; | ||
271 | impl Data { | ||
272 | /// ``` | ||
273 | /// let x = 5; | ||
274 | /// ``` | ||
275 | fn foo() {} | ||
276 | } | ||
277 | "#, | ||
278 | ); | ||
279 | let runnables = analysis.runnables(pos.file_id).unwrap(); | ||
280 | assert_debug_snapshot!(&runnables, | ||
281 | @r###" | ||
282 | [ | ||
283 | Runnable { | ||
284 | range: 1..21, | ||
285 | kind: Bin, | ||
286 | }, | ||
287 | Runnable { | ||
288 | range: 52..106, | ||
289 | kind: DocTest { | ||
290 | test_id: Path( | ||
291 | "Data::foo", | ||
292 | ), | ||
293 | }, | ||
294 | }, | ||
295 | ] | ||
296 | "### | ||
297 | ); | ||
298 | } | ||
299 | |||
300 | #[test] | ||
241 | fn test_runnables_module() { | 301 | fn test_runnables_module() { |
242 | let (analysis, pos) = analysis_and_position( | 302 | let (analysis, pos) = analysis_and_position( |
243 | r#" | 303 | r#" |