diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/hir/src/code_model.rs | 18 | ||||
-rw-r--r-- | crates/hir/src/doc_links.rs | 23 |
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 | ||
134 | fn get_doc_url(db: &dyn HirDatabase, krate: &Crate) -> Option<Url> { | 130 | fn 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 | ||
163 | struct IntraDocLink<'s> { | ||
164 | path: &'s str, | ||
165 | namespace: Option<Namespace>, | ||
166 | } | ||
167 | |||
168 | impl<'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)] |
168 | enum Namespace { | 175 | enum Namespace { |
169 | Types, | 176 | Types, |