diff options
author | Aleksey Kladov <[email protected]> | 2021-01-11 13:24:50 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2021-01-11 13:24:50 +0000 |
commit | 8adf5cc0e364376183c0b8009b65bc9e46fa3e36 (patch) | |
tree | 58ec94a29bf262f2f90eaa9e63ca409d786fa01a /crates/ide/src | |
parent | 8c33ffecc1feea732f2ea18b3701c145adc73928 (diff) |
Goto for inner doc links works for module inner doc comments
Diffstat (limited to 'crates/ide/src')
-rw-r--r-- | crates/ide/src/goto_definition.rs | 57 | ||||
-rw-r--r-- | crates/ide/src/runnables.rs | 37 |
2 files changed, 54 insertions, 40 deletions
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs index c20185b16..cd4afc804 100644 --- a/crates/ide/src/goto_definition.rs +++ b/crates/ide/src/goto_definition.rs | |||
@@ -6,15 +6,13 @@ use ide_db::{ | |||
6 | symbol_index, RootDatabase, | 6 | symbol_index, RootDatabase, |
7 | }; | 7 | }; |
8 | use syntax::{ | 8 | use syntax::{ |
9 | ast::{self, NameOwner}, | 9 | ast, match_ast, AstNode, AstToken, SyntaxKind::*, SyntaxToken, TextSize, TokenAtOffset, T, |
10 | match_ast, AstNode, AstToken, | ||
11 | SyntaxKind::*, | ||
12 | SyntaxToken, TextSize, TokenAtOffset, T, | ||
13 | }; | 10 | }; |
14 | 11 | ||
15 | use crate::{ | 12 | use crate::{ |
16 | display::{ToNav, TryToNav}, | 13 | display::{ToNav, TryToNav}, |
17 | doc_links::extract_definitions_from_markdown, | 14 | doc_links::extract_definitions_from_markdown, |
15 | runnables::doc_owner_to_def, | ||
18 | FilePosition, NavigationTarget, RangeInfo, SymbolKind, | 16 | FilePosition, NavigationTarget, RangeInfo, SymbolKind, |
19 | }; | 17 | }; |
20 | 18 | ||
@@ -84,31 +82,23 @@ fn def_for_doc_comment( | |||
84 | doc_comment: &ast::Comment, | 82 | doc_comment: &ast::Comment, |
85 | ) -> Option<hir::ModuleDef> { | 83 | ) -> Option<hir::ModuleDef> { |
86 | let parent = doc_comment.syntax().parent(); | 84 | let parent = doc_comment.syntax().parent(); |
87 | let db = sema.db; | ||
88 | let (link, ns) = extract_positioned_link_from_comment(position, doc_comment)?; | 85 | let (link, ns) = extract_positioned_link_from_comment(position, doc_comment)?; |
89 | let link = &link; | 86 | |
90 | let name = match_ast! { | 87 | let def = doc_owner_to_def(sema, parent)?; |
91 | match parent { | 88 | match def { |
92 | ast::Name(name) => Some(name), | ||
93 | ast::Fn(func) => func.name(), | ||
94 | _ => None, | ||
95 | } | ||
96 | }?; | ||
97 | let definition = NameClass::classify(&sema, &name).and_then(|d| d.defined(sema.db))?; | ||
98 | match definition { | ||
99 | Definition::ModuleDef(def) => match def { | 89 | Definition::ModuleDef(def) => match def { |
100 | ModuleDef::Module(it) => it.resolve_doc_path(db, link, ns), | 90 | ModuleDef::Module(it) => it.resolve_doc_path(sema.db, &link, ns), |
101 | ModuleDef::Function(it) => it.resolve_doc_path(db, link, ns), | 91 | ModuleDef::Function(it) => it.resolve_doc_path(sema.db, &link, ns), |
102 | ModuleDef::Adt(it) => it.resolve_doc_path(db, link, ns), | 92 | ModuleDef::Adt(it) => it.resolve_doc_path(sema.db, &link, ns), |
103 | ModuleDef::Variant(it) => it.resolve_doc_path(db, link, ns), | 93 | ModuleDef::Variant(it) => it.resolve_doc_path(sema.db, &link, ns), |
104 | ModuleDef::Const(it) => it.resolve_doc_path(db, link, ns), | 94 | ModuleDef::Const(it) => it.resolve_doc_path(sema.db, &link, ns), |
105 | ModuleDef::Static(it) => it.resolve_doc_path(db, link, ns), | 95 | ModuleDef::Static(it) => it.resolve_doc_path(sema.db, &link, ns), |
106 | ModuleDef::Trait(it) => it.resolve_doc_path(db, link, ns), | 96 | ModuleDef::Trait(it) => it.resolve_doc_path(sema.db, &link, ns), |
107 | ModuleDef::TypeAlias(it) => it.resolve_doc_path(db, link, ns), | 97 | ModuleDef::TypeAlias(it) => it.resolve_doc_path(sema.db, &link, ns), |
108 | ModuleDef::BuiltinType(_) => return None, | 98 | ModuleDef::BuiltinType(_) => return None, |
109 | }, | 99 | }, |
110 | Definition::Macro(it) => it.resolve_doc_path(db, link, ns), | 100 | Definition::Macro(it) => it.resolve_doc_path(sema.db, &link, ns), |
111 | Definition::Field(it) => it.resolve_doc_path(db, link, ns), | 101 | Definition::Field(it) => it.resolve_doc_path(sema.db, &link, ns), |
112 | Definition::SelfType(_) | 102 | Definition::SelfType(_) |
113 | | Definition::Local(_) | 103 | | Definition::Local(_) |
114 | | Definition::GenericParam(_) | 104 | | Definition::GenericParam(_) |
@@ -1212,7 +1202,7 @@ fn foo<'foo>(_: &'foo ()) { | |||
1212 | } | 1202 | } |
1213 | 1203 | ||
1214 | #[test] | 1204 | #[test] |
1215 | fn goto_def_for_intra_rustdoc_link_same_file() { | 1205 | fn goto_def_for_intra_doc_link_same_file() { |
1216 | check( | 1206 | check( |
1217 | r#" | 1207 | r#" |
1218 | /// Blah, [`bar`](bar) .. [`foo`](foo)$0 has [`bar`](bar) | 1208 | /// Blah, [`bar`](bar) .. [`foo`](foo)$0 has [`bar`](bar) |
@@ -1225,4 +1215,19 @@ pub fn foo() { } | |||
1225 | }"#, | 1215 | }"#, |
1226 | ) | 1216 | ) |
1227 | } | 1217 | } |
1218 | |||
1219 | #[test] | ||
1220 | fn goto_def_for_intra_doc_link_inner() { | ||
1221 | check( | ||
1222 | r#" | ||
1223 | //- /main.rs | ||
1224 | mod m; | ||
1225 | struct S; | ||
1226 | //^ | ||
1227 | |||
1228 | //- /m.rs | ||
1229 | //! [`super::S$0`] | ||
1230 | "#, | ||
1231 | ) | ||
1232 | } | ||
1228 | } | 1233 | } |
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs index 3a1e204db..f5ee7de86 100644 --- a/crates/ide/src/runnables.rs +++ b/crates/ide/src/runnables.rs | |||
@@ -3,7 +3,7 @@ use std::fmt; | |||
3 | use assists::utils::test_related_attribute; | 3 | use assists::utils::test_related_attribute; |
4 | use cfg::CfgExpr; | 4 | use cfg::CfgExpr; |
5 | use hir::{AsAssocItem, HasAttrs, HasSource, Semantics}; | 5 | use hir::{AsAssocItem, HasAttrs, HasSource, Semantics}; |
6 | use ide_db::RootDatabase; | 6 | use ide_db::{defs::Definition, RootDatabase}; |
7 | use itertools::Itertools; | 7 | use itertools::Itertools; |
8 | use syntax::{ | 8 | use syntax::{ |
9 | ast::{self, AstNode, AttrsOwner, ModuleItemOwner}, | 9 | ast::{self, AstNode, AttrsOwner, ModuleItemOwner}, |
@@ -110,7 +110,10 @@ pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { | |||
110 | _ => None, | 110 | _ => None, |
111 | } | 111 | } |
112 | }; | 112 | }; |
113 | runnable.or_else(|| runnable_doctest(&sema, item)) | 113 | runnable.or_else(|| match doc_owner_to_def(&sema, item)? { |
114 | Definition::ModuleDef(def) => module_def_doctest(&sema, def), | ||
115 | _ => None, | ||
116 | }) | ||
114 | }) | 117 | }) |
115 | .collect() | 118 | .collect() |
116 | } | 119 | } |
@@ -170,20 +173,26 @@ pub(crate) fn runnable_mod( | |||
170 | Some(Runnable { nav, kind: RunnableKind::TestMod { path }, cfg }) | 173 | Some(Runnable { nav, kind: RunnableKind::TestMod { path }, cfg }) |
171 | } | 174 | } |
172 | 175 | ||
173 | fn runnable_doctest(sema: &Semantics<RootDatabase>, item: SyntaxNode) -> Option<Runnable> { | 176 | // FIXME: figure out a proper API here. |
174 | match_ast! { | 177 | pub(crate) fn doc_owner_to_def( |
178 | sema: &Semantics<RootDatabase>, | ||
179 | item: SyntaxNode, | ||
180 | ) -> Option<Definition> { | ||
181 | let res: hir::ModuleDef = match_ast! { | ||
175 | match item { | 182 | match item { |
176 | ast::Fn(it) => module_def_doctest(sema, sema.to_def(&it)?.into()), | 183 | ast::SourceFile(it) => sema.scope(&item).module()?.into(), |
177 | ast::Struct(it) => module_def_doctest(sema, sema.to_def(&it)?.into()), | 184 | ast::Fn(it) => sema.to_def(&it)?.into(), |
178 | ast::Enum(it) => module_def_doctest(sema, sema.to_def(&it)?.into()), | 185 | ast::Struct(it) => sema.to_def(&it)?.into(), |
179 | ast::Union(it) => module_def_doctest(sema, sema.to_def(&it)?.into()), | 186 | ast::Enum(it) => sema.to_def(&it)?.into(), |
180 | ast::Trait(it) => module_def_doctest(sema, sema.to_def(&it)?.into()), | 187 | ast::Union(it) => sema.to_def(&it)?.into(), |
181 | ast::Const(it) => module_def_doctest(sema, sema.to_def(&it)?.into()), | 188 | ast::Trait(it) => sema.to_def(&it)?.into(), |
182 | ast::Static(it) => module_def_doctest(sema, sema.to_def(&it)?.into()), | 189 | ast::Const(it) => sema.to_def(&it)?.into(), |
183 | ast::TypeAlias(it) => module_def_doctest(sema, sema.to_def(&it)?.into()), | 190 | ast::Static(it) => sema.to_def(&it)?.into(), |
184 | _ => None, | 191 | ast::TypeAlias(it) => sema.to_def(&it)?.into(), |
192 | _ => return None, | ||
185 | } | 193 | } |
186 | } | 194 | }; |
195 | Some(Definition::ModuleDef(res)) | ||
187 | } | 196 | } |
188 | 197 | ||
189 | fn module_def_doctest(sema: &Semantics<RootDatabase>, def: hir::ModuleDef) -> Option<Runnable> { | 198 | fn module_def_doctest(sema: &Semantics<RootDatabase>, def: hir::ModuleDef) -> Option<Runnable> { |