aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/hir/src/code_model.rs18
-rw-r--r--crates/hir/src/doc_links.rs23
2 files changed, 23 insertions, 18 deletions
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs
index bd80102fa..94dd7f6f5 100644
--- a/crates/hir/src/code_model.rs
+++ b/crates/hir/src/code_model.rs
@@ -126,13 +126,16 @@ impl Crate {
126 } 126 }
127 127
128 /// Try to get the root URL of the documentation of a crate. 128 /// Try to get the root URL of the documentation of a crate.
129 pub fn get_doc_url(self: &Crate, db: &dyn HirDatabase) -> Option<String> { 129 pub fn get_html_root_url(self: &Crate, db: &dyn HirDatabase) -> Option<String> {
130 // Look for #![doc(html_root_url = "...")] 130 // Look for #![doc(html_root_url = "...")]
131 let attrs = db.attrs(AttrDef::from(self.root_module(db)).into()); 131 let attrs = db.attrs(AttrDef::from(self.root_module(db)).into());
132 let doc_attr_q = attrs.by_key("doc"); 132 let doc_attr_q = attrs.by_key("doc");
133 133
134 let doc_url = if doc_attr_q.exists() { 134 if !doc_attr_q.exists() {
135 doc_attr_q.tt_values().map(|tt| { 135 return None;
136 }
137
138 let doc_url = doc_attr_q.tt_values().map(|tt| {
136 let name = tt.token_trees.iter() 139 let name = tt.token_trees.iter()
137 .skip_while(|tt| !matches!(tt, TokenTree::Leaf(Leaf::Ident(Ident{text: ref ident, ..})) if ident == "html_root_url")) 140 .skip_while(|tt| !matches!(tt, TokenTree::Leaf(Leaf::Ident(Ident{text: ref ident, ..})) if ident == "html_root_url"))
138 .skip(2) 141 .skip(2)
@@ -142,14 +145,9 @@ impl Crate {
142 Some(TokenTree::Leaf(Leaf::Literal(Literal{ref text, ..}))) => Some(text), 145 Some(TokenTree::Leaf(Leaf::Literal(Literal{ref text, ..}))) => Some(text),
143 _ => None 146 _ => None
144 } 147 }
145 }).flat_map(|t| t).next().map(|s| s.to_string()) 148 }).flat_map(|t| t).next();
146 } else {
147 None
148 };
149 149
150 doc_url 150 doc_url.map(|s| s.trim_matches('"').trim_end_matches("/").to_owned() + "/")
151 .map(|s| s.trim_matches('"').trim_end_matches("/").to_owned() + "/")
152 .map(|s| s.to_string())
153 } 151 }
154} 152}
155 153
diff --git a/crates/hir/src/doc_links.rs b/crates/hir/src/doc_links.rs
index 45b26519e..dd2379bfc 100644
--- a/crates/hir/src/doc_links.rs
+++ b/crates/hir/src/doc_links.rs
@@ -38,21 +38,17 @@ fn try_resolve_intra<T: Resolvable, D: DefDatabase + HirDatabase>(
38 let link_target = 38 let link_target =
39 if link_target.is_empty() { link_text.trim_matches('`') } else { link_target }; 39 if link_target.is_empty() { link_text.trim_matches('`') } else { link_target };
40 40
41 // Namespace disambiguation 41 let doclink = IntraDocLink::from(link_target);
42 let namespace = Namespace::from_intra_spec(link_target);
43
44 // Strip prefixes/suffixes
45 let link_target = strip_prefixes_suffixes(link_target);
46 42
47 // Parse link as a module path 43 // Parse link as a module path
48 let path = Path::parse(link_target).ok()?; 44 let path = Path::parse(doclink.path).ok()?;
49 let modpath = ModPath::from_src(path, &Hygiene::new_unhygienic()).unwrap(); 45 let modpath = ModPath::from_src(path, &Hygiene::new_unhygienic()).unwrap();
50 46
51 // Resolve it relative to symbol's location (according to the RFC this should consider small scopes) 47 // Resolve it relative to symbol's location (according to the RFC this should consider small scopes)
52 let resolver = definition.resolver(db)?; 48 let resolver = definition.resolver(db)?;
53 49
54 let resolved = resolver.resolve_module_path_in_items(db, &modpath); 50 let resolved = resolver.resolve_module_path_in_items(db, &modpath);
55 let (defid, namespace) = match namespace { 51 let (defid, namespace) = match doclink.namespace {
56 // FIXME: .or(resolved.macros) 52 // FIXME: .or(resolved.macros)
57 None => resolved 53 None => resolved
58 .types 54 .types
@@ -133,7 +129,7 @@ fn strip_prefixes_suffixes(mut s: &str) -> &str {
133 129
134fn get_doc_url(db: &dyn HirDatabase, krate: &Crate) -> Option<Url> { 130fn get_doc_url(db: &dyn HirDatabase, krate: &Crate) -> Option<Url> {
135 krate 131 krate
136 .get_doc_url(db) 132 .get_html_root_url(db)
137 .or_else(|| 133 .or_else(||
138 // Fallback to docs.rs 134 // Fallback to docs.rs
139 // FIXME: Specify an exact version here. This may be difficult, as multiple versions of the same crate could exist. 135 // FIXME: Specify an exact version here. This may be difficult, as multiple versions of the same crate could exist.
@@ -164,6 +160,17 @@ fn get_symbol_filename(db: &dyn HirDatabase, definition: &ModuleDef) -> Option<S
164 }) 160 })
165} 161}
166 162
163struct IntraDocLink<'s> {
164 path: &'s str,
165 namespace: Option<Namespace>,
166}
167
168impl<'s> From<&'s str> for IntraDocLink<'s> {
169 fn from(s: &'s str) -> Self {
170 Self { path: strip_prefixes_suffixes(s), namespace: Namespace::from_intra_spec(s) }
171 }
172}
173
167#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)] 174#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
168enum Namespace { 175enum Namespace {
169 Types, 176 Types,