about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-05-31 15:48:41 +0000
committerGitHub <noreply@github.com>2021-05-31 15:48:41 +0000
commit10b15b27f2f4bee6de63f66c344f741482becd21 (patch)
tree2873a060f977b0fe48b0b9c5c31be21a1abc96a8
parentd1b1867af7b603f15dc299399c5e2a56dca58df6 (diff)
parent629ab189948e7a0fc726542d4c902ca4f8731c4f (diff)
Merge #8952
8952: add support of impl block for doctest into runnables r=matklad a=bnjjj

close #6356 

Co-authored-by: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com>
-rw-r--r--crates/ide/src/runnables.rs72
1 files changed, 71 insertions, 1 deletions
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs
index ce1c76f3718..55205495118 100644
--- a/crates/ide/src/runnables.rs
+++ b/crates/ide/src/runnables.rs
@@ -113,6 +113,7 @@ pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
             res.extend(runnable.or_else(|| module_def_doctest(&sema, def)))
         }
         Either::Right(impl_) => {
+            res.extend(runnable_impl(&sema, &impl_));
             res.extend(impl_.items(db).into_iter().filter_map(|assoc| match assoc {
                 hir::AssocItem::Function(it) => {
                     runnable_fn(&sema, it).or_else(|| module_def_doctest(&sema, it.into()))
@@ -270,6 +271,26 @@ pub(crate) fn runnable_mod(sema: &Semantics<RootDatabase>, def: hir::Module) ->
     Some(Runnable { nav, kind: RunnableKind::TestMod { path }, cfg })
 }
 
+pub(crate) fn runnable_impl(sema: &Semantics<RootDatabase>, def: &hir::Impl) -> Option<Runnable> {
+    let attrs = def.attrs(sema.db);
+    if !has_runnable_doc_test(&attrs) {
+        return None;
+    }
+    let cfg = attrs.cfg();
+    let nav = def.try_to_nav(sema.db)?;
+    let ty = def.self_ty(sema.db);
+    let adt_name = ty.as_adt()?.name(sema.db);
+    let mut ty_args = ty.type_arguments().peekable();
+    let params = if ty_args.peek().is_some() {
+        format!("<{}>", ty_args.format_with(", ", |ty, cb| cb(&ty.display(sema.db))))
+    } else {
+        String::new()
+    };
+    let test_id = TestId::Path(format!("{}{}", adt_name, params));
+
+    Some(Runnable { nav, kind: RunnableKind::DocTest { test_id }, cfg })
+}
+
 fn module_def_doctest(sema: &Semantics<RootDatabase>, def: hir::ModuleDef) -> Option<Runnable> {
     let attrs = match def {
         hir::ModuleDef::Module(it) => it.attrs(sema.db),
@@ -610,8 +631,23 @@ fn should_have_no_runnable_6() {}
 /// ```
 struct StructWithRunnable(String);
 
+/// ```
+/// let x = 5;
+/// ```
+impl StructWithRunnable {}
+
+trait Test {
+    fn test() -> usize {
+        5usize
+    }
+}
+
+/// ```
+/// let x = 5;
+/// ```
+impl Test for StructWithRunnable {}
 "#,
-            &[&BIN, &DOCTEST, &DOCTEST, &DOCTEST, &DOCTEST, &DOCTEST, &DOCTEST],
+            &[&BIN, &DOCTEST, &DOCTEST, &DOCTEST, &DOCTEST, &DOCTEST, &DOCTEST, &DOCTEST, &DOCTEST],
             expect![[r#"
                 [
                     Runnable {
@@ -717,6 +753,40 @@ struct StructWithRunnable(String);
                         },
                         cfg: None,
                     },
+                    Runnable {
+                        nav: NavigationTarget {
+                            file_id: FileId(
+                                0,
+                            ),
+                            full_range: 967..1024,
+                            focus_range: 1003..1021,
+                            name: "impl",
+                            kind: Impl,
+                        },
+                        kind: DocTest {
+                            test_id: Path(
+                                "StructWithRunnable",
+                            ),
+                        },
+                        cfg: None,
+                    },
+                    Runnable {
+                        nav: NavigationTarget {
+                            file_id: FileId(
+                                0,
+                            ),
+                            full_range: 1088..1154,
+                            focus_range: 1133..1151,
+                            name: "impl",
+                            kind: Impl,
+                        },
+                        kind: DocTest {
+                            test_id: Path(
+                                "StructWithRunnable",
+                            ),
+                        },
+                        cfg: None,
+                    },
                 ]
             "#]],
         );