about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-01-11 13:25:51 +0000
committerGitHub <noreply@github.com>2021-01-11 13:25:51 +0000
commitb84c49b9af92af628019fbcb11898be117af4f97 (patch)
tree58ec94a29bf262f2f90eaa9e63ca409d786fa01a
parent8c33ffecc1feea732f2ea18b3701c145adc73928 (diff)
parent8adf5cc0e364376183c0b8009b65bc9e46fa3e36 (diff)
downloadrust-b84c49b9af92af628019fbcb11898be117af4f97.tar.gz
rust-b84c49b9af92af628019fbcb11898be117af4f97.zip
Merge #7244
7244: Goto for inner doc links works for module inner doc comments r=matklad a=matklad

bors r+
🤖

Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
-rw-r--r--crates/ide/src/goto_definition.rs57
-rw-r--r--crates/ide/src/runnables.rs37
2 files changed, 54 insertions, 40 deletions
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index c20185b1648..cd4afc8041d 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -6,15 +6,13 @@ use ide_db::{
     symbol_index, RootDatabase,
 };
 use syntax::{
-    ast::{self, NameOwner},
-    match_ast, AstNode, AstToken,
-    SyntaxKind::*,
-    SyntaxToken, TextSize, TokenAtOffset, T,
+    ast, match_ast, AstNode, AstToken, SyntaxKind::*, SyntaxToken, TextSize, TokenAtOffset, T,
 };
 
 use crate::{
     display::{ToNav, TryToNav},
     doc_links::extract_definitions_from_markdown,
+    runnables::doc_owner_to_def,
     FilePosition, NavigationTarget, RangeInfo, SymbolKind,
 };
 
@@ -84,31 +82,23 @@ fn def_for_doc_comment(
     doc_comment: &ast::Comment,
 ) -> Option<hir::ModuleDef> {
     let parent = doc_comment.syntax().parent();
-    let db = sema.db;
     let (link, ns) = extract_positioned_link_from_comment(position, doc_comment)?;
-    let link = &link;
-    let name = match_ast! {
-        match parent {
-            ast::Name(name) => Some(name),
-            ast::Fn(func) => func.name(),
-            _ => None,
-        }
-    }?;
-    let definition = NameClass::classify(&sema, &name).and_then(|d| d.defined(sema.db))?;
-    match definition {
+
+    let def = doc_owner_to_def(sema, parent)?;
+    match def {
         Definition::ModuleDef(def) => match def {
-            ModuleDef::Module(it) => it.resolve_doc_path(db, link, ns),
-            ModuleDef::Function(it) => it.resolve_doc_path(db, link, ns),
-            ModuleDef::Adt(it) => it.resolve_doc_path(db, link, ns),
-            ModuleDef::Variant(it) => it.resolve_doc_path(db, link, ns),
-            ModuleDef::Const(it) => it.resolve_doc_path(db, link, ns),
-            ModuleDef::Static(it) => it.resolve_doc_path(db, link, ns),
-            ModuleDef::Trait(it) => it.resolve_doc_path(db, link, ns),
-            ModuleDef::TypeAlias(it) => it.resolve_doc_path(db, link, ns),
+            ModuleDef::Module(it) => it.resolve_doc_path(sema.db, &link, ns),
+            ModuleDef::Function(it) => it.resolve_doc_path(sema.db, &link, ns),
+            ModuleDef::Adt(it) => it.resolve_doc_path(sema.db, &link, ns),
+            ModuleDef::Variant(it) => it.resolve_doc_path(sema.db, &link, ns),
+            ModuleDef::Const(it) => it.resolve_doc_path(sema.db, &link, ns),
+            ModuleDef::Static(it) => it.resolve_doc_path(sema.db, &link, ns),
+            ModuleDef::Trait(it) => it.resolve_doc_path(sema.db, &link, ns),
+            ModuleDef::TypeAlias(it) => it.resolve_doc_path(sema.db, &link, ns),
             ModuleDef::BuiltinType(_) => return None,
         },
-        Definition::Macro(it) => it.resolve_doc_path(db, link, ns),
-        Definition::Field(it) => it.resolve_doc_path(db, link, ns),
+        Definition::Macro(it) => it.resolve_doc_path(sema.db, &link, ns),
+        Definition::Field(it) => it.resolve_doc_path(sema.db, &link, ns),
         Definition::SelfType(_)
         | Definition::Local(_)
         | Definition::GenericParam(_)
@@ -1212,7 +1202,7 @@ fn foo<'foo>(_: &'foo ()) {
     }
 
     #[test]
-    fn goto_def_for_intra_rustdoc_link_same_file() {
+    fn goto_def_for_intra_doc_link_same_file() {
         check(
             r#"
 /// Blah, [`bar`](bar) .. [`foo`](foo)$0 has [`bar`](bar)
@@ -1225,4 +1215,19 @@ pub fn foo() { }
 }"#,
         )
     }
+
+    #[test]
+    fn goto_def_for_intra_doc_link_inner() {
+        check(
+            r#"
+//- /main.rs
+mod m;
+struct S;
+     //^
+
+//- /m.rs
+//! [`super::S$0`]
+"#,
+        )
+    }
 }
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs
index 3a1e204db54..f5ee7de86d3 100644
--- a/crates/ide/src/runnables.rs
+++ b/crates/ide/src/runnables.rs
@@ -3,7 +3,7 @@ use std::fmt;
 use assists::utils::test_related_attribute;
 use cfg::CfgExpr;
 use hir::{AsAssocItem, HasAttrs, HasSource, Semantics};
-use ide_db::RootDatabase;
+use ide_db::{defs::Definition, RootDatabase};
 use itertools::Itertools;
 use syntax::{
     ast::{self, AstNode, AttrsOwner, ModuleItemOwner},
@@ -110,7 +110,10 @@ pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
                     _ => None,
                 }
             };
-            runnable.or_else(|| runnable_doctest(&sema, item))
+            runnable.or_else(|| match doc_owner_to_def(&sema, item)? {
+                Definition::ModuleDef(def) => module_def_doctest(&sema, def),
+                _ => None,
+            })
         })
         .collect()
 }
@@ -170,20 +173,26 @@ pub(crate) fn runnable_mod(
     Some(Runnable { nav, kind: RunnableKind::TestMod { path }, cfg })
 }
 
-fn runnable_doctest(sema: &Semantics<RootDatabase>, item: SyntaxNode) -> Option<Runnable> {
-    match_ast! {
+// FIXME: figure out a proper API here.
+pub(crate) fn doc_owner_to_def(
+    sema: &Semantics<RootDatabase>,
+    item: SyntaxNode,
+) -> Option<Definition> {
+    let res: hir::ModuleDef = match_ast! {
         match item {
-            ast::Fn(it) => module_def_doctest(sema, sema.to_def(&it)?.into()),
-            ast::Struct(it) => module_def_doctest(sema, sema.to_def(&it)?.into()),
-            ast::Enum(it) => module_def_doctest(sema, sema.to_def(&it)?.into()),
-            ast::Union(it) => module_def_doctest(sema, sema.to_def(&it)?.into()),
-            ast::Trait(it) => module_def_doctest(sema, sema.to_def(&it)?.into()),
-            ast::Const(it) => module_def_doctest(sema, sema.to_def(&it)?.into()),
-            ast::Static(it) => module_def_doctest(sema, sema.to_def(&it)?.into()),
-            ast::TypeAlias(it) => module_def_doctest(sema, sema.to_def(&it)?.into()),
-            _ => None,
+            ast::SourceFile(it) => sema.scope(&item).module()?.into(),
+            ast::Fn(it) => sema.to_def(&it)?.into(),
+            ast::Struct(it) => sema.to_def(&it)?.into(),
+            ast::Enum(it) => sema.to_def(&it)?.into(),
+            ast::Union(it) => sema.to_def(&it)?.into(),
+            ast::Trait(it) => sema.to_def(&it)?.into(),
+            ast::Const(it) => sema.to_def(&it)?.into(),
+            ast::Static(it) => sema.to_def(&it)?.into(),
+            ast::TypeAlias(it) => sema.to_def(&it)?.into(),
+            _ => return None,
         }
-    }
+    };
+    Some(Definition::ModuleDef(res))
 }
 
 fn module_def_doctest(sema: &Semantics<RootDatabase>, def: hir::ModuleDef) -> Option<Runnable> {