diff options
Diffstat (limited to 'crates/hir/src/doc_links.rs')
-rw-r--r-- | crates/hir/src/doc_links.rs | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/crates/hir/src/doc_links.rs b/crates/hir/src/doc_links.rs index a77758675..ddaffbec2 100644 --- a/crates/hir/src/doc_links.rs +++ b/crates/hir/src/doc_links.rs | |||
@@ -2,22 +2,33 @@ | |||
2 | 2 | ||
3 | use std::iter::once; | 3 | use std::iter::once; |
4 | 4 | ||
5 | use hir_def::{db::DefDatabase, resolver::Resolver}; | 5 | use hir_def::resolver::Resolver; |
6 | use itertools::Itertools; | 6 | use itertools::Itertools; |
7 | use syntax::ast::Path; | 7 | use syntax::ast::Path; |
8 | use url::Url; | 8 | use url::Url; |
9 | 9 | ||
10 | use crate::{db::HirDatabase, Adt, AsName, Crate, Hygiene, ItemInNs, ModPath, ModuleDef}; | 10 | use crate::{db::HirDatabase, Adt, AsName, Crate, Hygiene, ItemInNs, ModPath, ModuleDef}; |
11 | 11 | ||
12 | pub fn resolve_doc_link<T: Resolvable + Clone, D: DefDatabase + HirDatabase>( | 12 | pub fn resolve_doc_link<T: Resolvable + Clone>( |
13 | db: &D, | 13 | db: &dyn HirDatabase, |
14 | definition: &T, | 14 | definition: &T, |
15 | link_text: &str, | 15 | link_text: &str, |
16 | link_target: &str, | 16 | link_target: &str, |
17 | ) -> Option<(String, String)> { | 17 | ) -> Option<(String, String)> { |
18 | try_resolve_intra(db, definition, link_text, &link_target).or_else(|| { | 18 | let resolver = definition.resolver(db)?; |
19 | let definition = definition.clone().try_into_module_def()?; | 19 | let module_def = definition.clone().try_into_module_def(); |
20 | try_resolve_path(db, &definition, &link_target) | 20 | resolve_doc_link_impl(db, &resolver, module_def, link_text, link_target) |
21 | } | ||
22 | |||
23 | fn resolve_doc_link_impl( | ||
24 | db: &dyn HirDatabase, | ||
25 | resolver: &Resolver, | ||
26 | module_def: Option<ModuleDef>, | ||
27 | link_text: &str, | ||
28 | link_target: &str, | ||
29 | ) -> Option<(String, String)> { | ||
30 | try_resolve_intra(db, &resolver, link_text, &link_target).or_else(|| { | ||
31 | try_resolve_path(db, &module_def?, &link_target) | ||
21 | .map(|target| (target, link_text.to_string())) | 32 | .map(|target| (target, link_text.to_string())) |
22 | }) | 33 | }) |
23 | } | 34 | } |
@@ -25,9 +36,9 @@ pub fn resolve_doc_link<T: Resolvable + Clone, D: DefDatabase + HirDatabase>( | |||
25 | /// Try to resolve path to local documentation via intra-doc-links (i.e. `super::gateway::Shard`). | 36 | /// Try to resolve path to local documentation via intra-doc-links (i.e. `super::gateway::Shard`). |
26 | /// | 37 | /// |
27 | /// See [RFC1946](https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md). | 38 | /// See [RFC1946](https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md). |
28 | fn try_resolve_intra<T: Resolvable, D: DefDatabase + HirDatabase>( | 39 | fn try_resolve_intra( |
29 | db: &D, | 40 | db: &dyn HirDatabase, |
30 | definition: &T, | 41 | resolver: &Resolver, |
31 | link_text: &str, | 42 | link_text: &str, |
32 | link_target: &str, | 43 | link_target: &str, |
33 | ) -> Option<(String, String)> { | 44 | ) -> Option<(String, String)> { |
@@ -41,10 +52,7 @@ fn try_resolve_intra<T: Resolvable, D: DefDatabase + HirDatabase>( | |||
41 | let path = Path::parse(doclink.path).ok()?; | 52 | let path = Path::parse(doclink.path).ok()?; |
42 | let modpath = ModPath::from_src(path, &Hygiene::new_unhygienic()).unwrap(); | 53 | let modpath = ModPath::from_src(path, &Hygiene::new_unhygienic()).unwrap(); |
43 | 54 | ||
44 | // Resolve it relative to symbol's location (according to the RFC this should consider small scopes) | 55 | let resolved = resolver.resolve_module_path_in_items(db.upcast(), &modpath); |
45 | let resolver = definition.resolver(db)?; | ||
46 | |||
47 | let resolved = resolver.resolve_module_path_in_items(db, &modpath); | ||
48 | let (defid, namespace) = match doclink.namespace { | 56 | let (defid, namespace) = match doclink.namespace { |
49 | // FIXME: .or(resolved.macros) | 57 | // FIXME: .or(resolved.macros) |
50 | None => resolved | 58 | None => resolved |
@@ -225,6 +233,6 @@ impl Namespace { | |||
225 | 233 | ||
226 | /// Sealed trait used solely for the generic bound on [`resolve_doc_link`]. | 234 | /// Sealed trait used solely for the generic bound on [`resolve_doc_link`]. |
227 | pub trait Resolvable { | 235 | pub trait Resolvable { |
228 | fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver>; | 236 | fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver>; |
229 | fn try_into_module_def(self) -> Option<ModuleDef>; | 237 | fn try_into_module_def(self) -> Option<ModuleDef>; |
230 | } | 238 | } |