|
1 | 1 | //! FIXME: write short doc here
|
2 | 2 |
|
3 |
| -use hir::Semantics; |
| 3 | +use hir::{AsAssocItem, Semantics}; |
4 | 4 | use itertools::Itertools;
|
5 | 5 | use ra_ide_db::RootDatabase;
|
6 | 6 | use ra_syntax::{
|
@@ -65,14 +65,36 @@ fn runnable_fn(sema: &Semantics<RootDatabase>, fn_def: ast::FnDef) -> Option<Run
|
65 | 65 | RunnableKind::Bin
|
66 | 66 | } else {
|
67 | 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 | 83 | .path_to_root(sema.db)
|
70 | 84 | .into_iter()
|
71 | 85 | .rev()
|
72 | 86 | .filter_map(|it| it.name(sema.db))
|
73 |
| - .map(|name| name.to_string()) |
74 |
| - .chain(std::iter::once(name_string)) |
75 |
| - .join("::"); |
| 87 | + .map(|name| name.to_string()); |
| 88 | + |
| 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 | 98 | TestId::Path(path)
|
77 | 99 | } else {
|
78 | 100 | TestId::Name(name_string)
|
@@ -237,6 +259,44 @@ mod tests {
|
237 | 259 | );
|
238 | 260 | }
|
239 | 261 |
|
| 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: 51..105, |
| 289 | + kind: DocTest { |
| 290 | + test_id: Path( |
| 291 | + "Data::foo", |
| 292 | + ), |
| 293 | + }, |
| 294 | + }, |
| 295 | + ] |
| 296 | + "### |
| 297 | + ); |
| 298 | + } |
| 299 | + |
240 | 300 | #[test]
|
241 | 301 | fn test_runnables_module() {
|
242 | 302 | let (analysis, pos) = analysis_and_position(
|
|
0 commit comments