aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 f76715d84..0ba7f7225 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> {
113 res.extend(runnable.or_else(|| module_def_doctest(&sema, def))) 113 res.extend(runnable.or_else(|| module_def_doctest(&sema, def)))
114 } 114 }
115 Either::Right(impl_) => { 115 Either::Right(impl_) => {
116 res.extend(runnable_impl(&sema, &impl_));
116 res.extend(impl_.items(db).into_iter().filter_map(|assoc| match assoc { 117 res.extend(impl_.items(db).into_iter().filter_map(|assoc| match assoc {
117 hir::AssocItem::Function(it) => { 118 hir::AssocItem::Function(it) => {
118 runnable_fn(&sema, it).or_else(|| module_def_doctest(&sema, it.into())) 119 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) ->
270 Some(Runnable { nav, kind: RunnableKind::TestMod { path }, cfg }) 271 Some(Runnable { nav, kind: RunnableKind::TestMod { path }, cfg })
271} 272}
272 273
274pub(crate) fn runnable_impl(sema: &Semantics<RootDatabase>, def: &hir::Impl) -> Option<Runnable> {
275 let attrs = def.attrs(sema.db);
276 if !has_runnable_doc_test(&attrs) {
277 return None;
278 }
279 let cfg = attrs.cfg();
280 let nav = def.try_to_nav(sema.db)?;
281 let ty = def.self_ty(sema.db);
282 let adt_name = ty.as_adt()?.name(sema.db);
283 let mut ty_args = ty.type_arguments().peekable();
284 let params = if ty_args.peek().is_some() {
285 format!("<{}>", ty_args.format_with(", ", |ty, cb| cb(&ty.display(sema.db))))
286 } else {
287 String::new()
288 };
289 let test_id = TestId::Path(format!("{}{}", adt_name, params));
290
291 Some(Runnable { nav, kind: RunnableKind::DocTest { test_id }, cfg })
292}
293
273fn module_def_doctest(sema: &Semantics<RootDatabase>, def: hir::ModuleDef) -> Option<Runnable> { 294fn module_def_doctest(sema: &Semantics<RootDatabase>, def: hir::ModuleDef) -> Option<Runnable> {
274 let attrs = match def { 295 let attrs = match def {
275 hir::ModuleDef::Module(it) => it.attrs(sema.db), 296 hir::ModuleDef::Module(it) => it.attrs(sema.db),
@@ -610,8 +631,23 @@ fn should_have_no_runnable_6() {}
610/// ``` 631/// ```
611struct StructWithRunnable(String); 632struct StructWithRunnable(String);
612 633
634/// ```
635/// let x = 5;
636/// ```
637impl StructWithRunnable {}
638
639trait Test {
640 fn test() -> usize {
641 5usize
642 }
643}
644
645/// ```
646/// let x = 5;
647/// ```
648impl Test for StructWithRunnable {}
613"#, 649"#,
614 &[&BIN, &DOCTEST, &DOCTEST, &DOCTEST, &DOCTEST, &DOCTEST, &DOCTEST], 650 &[&BIN, &DOCTEST, &DOCTEST, &DOCTEST, &DOCTEST, &DOCTEST, &DOCTEST, &DOCTEST, &DOCTEST],
615 expect![[r#" 651 expect![[r#"
616 [ 652 [
617 Runnable { 653 Runnable {
@@ -717,6 +753,40 @@ struct StructWithRunnable(String);
717 }, 753 },
718 cfg: None, 754 cfg: None,
719 }, 755 },
756 Runnable {
757 nav: NavigationTarget {
758 file_id: FileId(
759 0,
760 ),
761 full_range: 967..1024,
762 focus_range: 1003..1021,
763 name: "impl",
764 kind: Impl,
765 },
766 kind: DocTest {
767 test_id: Path(
768 "StructWithRunnable",
769 ),
770 },
771 cfg: None,
772 },
773 Runnable {
774 nav: NavigationTarget {
775 file_id: FileId(
776 0,
777 ),
778 full_range: 1088..1154,
779 focus_range: 1133..1151,
780 name: "impl",
781 kind: Impl,
782 },
783 kind: DocTest {
784 test_id: Path(
785 "StructWithRunnable",
786 ),
787 },
788 cfg: None,
789 },
720 ] 790 ]
721 "#]], 791 "#]],
722 ); 792 );