diff options
Diffstat (limited to 'crates/ra_ide/src/runnables.rs')
-rw-r--r-- | crates/ra_ide/src/runnables.rs | 72 |
1 files changed, 67 insertions, 5 deletions
diff --git a/crates/ra_ide/src/runnables.rs b/crates/ra_ide/src/runnables.rs index 4f7eb2c5b..3a3d0b0ac 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::{Attrs, HirFileId, InFile, Semantics}; | 3 | use hir::{AsAssocItem, Attrs, HirFileId, InFile, 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::{ |
@@ -70,14 +70,36 @@ fn runnable_fn( | |||
70 | RunnableKind::Bin | 70 | RunnableKind::Bin |
71 | } else { | 71 | } else { |
72 | let test_id = if let Some(module) = sema.to_def(&fn_def).map(|def| def.module(sema.db)) { | 72 | let test_id = if let Some(module) = sema.to_def(&fn_def).map(|def| def.module(sema.db)) { |
73 | let path = module | 73 | let def = sema.to_def(&fn_def)?; |
74 | let impl_trait_name = | ||
75 | def.as_assoc_item(sema.db).and_then(|assoc_item| { | ||
76 | match assoc_item.container(sema.db) { | ||
77 | hir::AssocItemContainer::Trait(trait_item) => { | ||
78 | Some(trait_item.name(sema.db).to_string()) | ||
79 | } | ||
80 | hir::AssocItemContainer::ImplDef(impl_def) => impl_def | ||
81 | .target_ty(sema.db) | ||
82 | .as_adt() | ||
83 | .map(|adt| adt.name(sema.db).to_string()), | ||
84 | } | ||
85 | }); | ||
86 | |||
87 | let path_iter = module | ||
74 | .path_to_root(sema.db) | 88 | .path_to_root(sema.db) |
75 | .into_iter() | 89 | .into_iter() |
76 | .rev() | 90 | .rev() |
77 | .filter_map(|it| it.name(sema.db)) | 91 | .filter_map(|it| it.name(sema.db)) |
78 | .map(|name| name.to_string()) | 92 | .map(|name| name.to_string()); |
79 | .chain(std::iter::once(name_string)) | 93 | |
80 | .join("::"); | 94 | let path = if let Some(impl_trait_name) = impl_trait_name { |
95 | path_iter | ||
96 | .chain(std::iter::once(impl_trait_name)) | ||
97 | .chain(std::iter::once(name_string)) | ||
98 | .join("::") | ||
99 | } else { | ||
100 | path_iter.chain(std::iter::once(name_string)).join("::") | ||
101 | }; | ||
102 | |||
81 | TestId::Path(path) | 103 | TestId::Path(path) |
82 | } else { | 104 | } else { |
83 | TestId::Name(name_string) | 105 | TestId::Name(name_string) |
@@ -279,6 +301,46 @@ mod tests { | |||
279 | } | 301 | } |
280 | 302 | ||
281 | #[test] | 303 | #[test] |
304 | fn test_runnables_doc_test_in_impl() { | ||
305 | let (analysis, pos) = analysis_and_position( | ||
306 | r#" | ||
307 | //- /lib.rs | ||
308 | <|> //empty | ||
309 | fn main() {} | ||
310 | |||
311 | struct Data; | ||
312 | impl Data { | ||
313 | /// ``` | ||
314 | /// let x = 5; | ||
315 | /// ``` | ||
316 | fn foo() {} | ||
317 | } | ||
318 | "#, | ||
319 | ); | ||
320 | let runnables = analysis.runnables(pos.file_id).unwrap(); | ||
321 | assert_debug_snapshot!(&runnables, | ||
322 | @r###" | ||
323 | [ | ||
324 | Runnable { | ||
325 | range: 1..21, | ||
326 | kind: Bin, | ||
327 | features_needed: None, | ||
328 | }, | ||
329 | Runnable { | ||
330 | range: 51..105, | ||
331 | kind: DocTest { | ||
332 | test_id: Path( | ||
333 | "Data::foo", | ||
334 | ), | ||
335 | }, | ||
336 | features_needed: None, | ||
337 | }, | ||
338 | ] | ||
339 | "### | ||
340 | ); | ||
341 | } | ||
342 | |||
343 | #[test] | ||
282 | fn test_runnables_module() { | 344 | fn test_runnables_module() { |
283 | let (analysis, pos) = analysis_and_position( | 345 | let (analysis, pos) = analysis_and_position( |
284 | r#" | 346 | r#" |