aboutsummaryrefslogtreecommitdiff
path: root/crates/hir/src/doc_links.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir/src/doc_links.rs')
-rw-r--r--crates/hir/src/doc_links.rs36
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
3use std::iter::once; 3use std::iter::once;
4 4
5use hir_def::{db::DefDatabase, resolver::Resolver}; 5use hir_def::resolver::Resolver;
6use itertools::Itertools; 6use itertools::Itertools;
7use syntax::ast::Path; 7use syntax::ast::Path;
8use url::Url; 8use url::Url;
9 9
10use crate::{db::HirDatabase, Adt, AsName, Crate, Hygiene, ItemInNs, ModPath, ModuleDef}; 10use crate::{db::HirDatabase, Adt, AsName, Crate, Hygiene, ItemInNs, ModPath, ModuleDef};
11 11
12pub fn resolve_doc_link<T: Resolvable + Clone, D: DefDatabase + HirDatabase>( 12pub 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
23fn 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).
28fn try_resolve_intra<T: Resolvable, D: DefDatabase + HirDatabase>( 39fn 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`].
227pub trait Resolvable { 235pub 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}