Skip to content

Commit 1833036

Browse files
committed
Fix doc attr parsing, fixes links from std/core/alloc
1 parent f98e311 commit 1833036

File tree

1 file changed

+19
-13
lines changed

1 file changed

+19
-13
lines changed

crates/ra_ide/src/hover.rs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use ra_ide_db::{
1919
use ra_syntax::{
2020
ast, ast::Path, match_ast, AstNode, SyntaxKind::*, SyntaxNode, SyntaxToken, TokenAtOffset,
2121
};
22-
use ra_tt::{Ident, Leaf, Literal, Punct, TokenTree};
22+
use ra_tt::{Ident, Leaf, Literal, TokenTree};
2323
use url::Url;
2424

2525
use crate::{
@@ -410,6 +410,8 @@ fn map_links<'e>(
410410
}
411411
Event::Text(s) if in_link => {
412412
link_text = s.clone();
413+
// TODO: This can unintentionally strip words from path-based links.
414+
// See std::box::Box -> std::box link as an example.
413415
Event::Text(CowStr::Boxed(strip_prefixes_suffixes(&s).into()))
414416
}
415417
Event::Code(s) if in_link => {
@@ -603,29 +605,33 @@ fn try_resolve_path(db: &RootDatabase, definition: &Definition, link: &str) -> O
603605
}
604606

605607
/// Try to get the root URL of the documentation of a crate.
606-
// FIXME: Special case standard, core, alloc libraries
607608
fn get_doc_url(db: &RootDatabase, krate: &Crate) -> Option<Url> {
608609
// Look for #![doc(html_root_url = "...")]
609610
let attrs = db.attrs(AttrDef::from(krate.root_module(db)?).into());
610611
let doc_attr_q = attrs.by_key("doc");
612+
613+
// TODO: Tests for this parsing
611614
let doc_url = if doc_attr_q.exists() {
612-
doc_attr_q.tt_values().filter_map(|tt| match tt.token_trees.as_slice() {
613-
&[
614-
TokenTree::Leaf(Leaf::Ident(Ident{text: ref ident_text, ..})),
615-
TokenTree::Leaf(Leaf::Punct(Punct{r#char: '=', ..})),
616-
TokenTree::Leaf(Leaf::Literal(Literal{ref text, ..}))
617-
] if ident_text == "html_root_url" => Some(text.to_string()),
618-
_ => {
619-
None
620-
}
621-
}).next()
615+
doc_attr_q.tt_values().map(|tt| {
616+
let name = tt.token_trees.iter()
617+
.skip_while(|tt| !matches!(tt, TokenTree::Leaf(Leaf::Ident(Ident{text: ref ident, ..})) if ident == "html_root_url"))
618+
.skip(2)
619+
.next();
620+
621+
match name {
622+
Some(TokenTree::Leaf(Leaf::Literal(Literal{ref text, ..}))) => Some(text),
623+
_ => None
624+
}
625+
}).flat_map(|t| t).next().map(|s| s.to_string())
622626
} else {
623627
// Fallback to docs.rs
624628
// FIXME: Specify an exact version here (from Cargo.lock)
625629
Some(format!("https://docs.rs/{}/*", krate.display_name(db)?))
626630
};
627631

628-
doc_url.map(|s| s.trim_matches('"').to_owned() + "/").and_then(|s| Url::parse(&s).ok())
632+
doc_url
633+
.map(|s| s.trim_matches('"').trim_end_matches("/").to_owned() + "/")
634+
.and_then(|s| Url::parse(&s).ok())
629635
}
630636

631637
/// Get the filename and extension generated for a symbol by rustdoc.

0 commit comments

Comments
 (0)