From 629ab189948e7a0fc726542d4c902ca4f8731c4f Mon Sep 17 00:00:00 2001 From: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com> Date: Sun, 23 May 2021 22:59:24 +0200 Subject: add support of impl block for doctest into runnables Signed-off-by: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com> --- crates/ide/src/runnables.rs | 72 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) 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 { 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, def: hir::Module) -> Some(Runnable { nav, kind: RunnableKind::TestMod { path }, cfg }) } +pub(crate) fn runnable_impl(sema: &Semantics, def: &hir::Impl) -> Option { + 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, def: hir::ModuleDef) -> Option { 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, + }, ] "#]], ); -- cgit v1.2.3