diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2018-03-28 17:32:15 +0200 |
|---|---|---|
| committer | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2018-03-29 13:43:55 +0200 |
| commit | 561e8efb7d221cc2f9274f3756cdf4c30556ae4b (patch) | |
| tree | be21b6791b4809e55d03d2e615a1d121cbfc3bdc | |
| parent | bcffdf1b6da161eecd761eb4a3ef703ff05c33f6 (diff) | |
| download | rust-561e8efb7d221cc2f9274f3756cdf4c30556ae4b.tar.gz rust-561e8efb7d221cc2f9274f3756cdf4c30556ae4b.zip | |
Add primitive intra-links
| -rw-r--r-- | src/librustdoc/clean/mod.rs | 85 | ||||
| -rw-r--r-- | src/test/rustdoc/primitive-link.rs | 19 |
2 files changed, 91 insertions, 13 deletions
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 42c9d9e52f3..62e5f730cae 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -19,6 +19,7 @@ pub use self::SelfTy::*; pub use self::FunctionRetTy::*; pub use self::Visibility::*; +use syntax; use syntax::abi::Abi; use syntax::ast::{self, AttrStyle}; use syntax::attr; @@ -64,6 +65,7 @@ use std::u32; use core::{self, DocContext}; use doctree; use visit_ast; +use html::render::{cache, ExternalLocation}; use html::item_type::ItemType; use html::markdown::markdown_links; @@ -346,7 +348,7 @@ impl Item { } pub fn links(&self) -> Vec<(String, String)> { - self.attrs.links() + self.attrs.links(&self.def_id.krate) } pub fn is_crate(&self) -> bool { @@ -697,7 +699,7 @@ pub struct Attributes { pub cfg: Option<Rc<Cfg>>, pub span: Option<syntax_pos::Span>, /// map from Rust paths to resolved defs and potential URL fragments - pub links: Vec<(String, DefId, Option<String>)>, + pub links: Vec<(String, Option<DefId>, Option<String>)>, } impl Attributes { @@ -869,17 +871,41 @@ impl Attributes { /// Get links as a vector /// /// Cache must be populated before call - pub fn links(&self) -> Vec<(String, String)> { + pub fn links(&self, krate: &CrateNum) -> Vec<(String, String)> { use html::format::href; self.links.iter().filter_map(|&(ref s, did, ref fragment)| { - if let Some((mut href, ..)) = href(did) { - if let Some(ref fragment) = *fragment { - href.push_str("#"); - href.push_str(fragment); + match did { + Some(did) => { + if let Some((mut href, ..)) = href(did) { + if let Some(ref fragment) = *fragment { + href.push_str("#"); + href.push_str(fragment); + } + Some((s.clone(), href)) + } else { + None + } + } + None => { + if let Some(ref fragment) = *fragment { + let cache = cache(); + let url = match cache.extern_locations.get(krate) { + Some(&(_, ref src, ExternalLocation::Local)) => + src.to_str().expect("invalid file path"), + Some(&(_, _, ExternalLocation::Remote(ref s))) => s, + Some(&(_, _, ExternalLocation::Unknown)) | None => + "https://doc.rust-lang.org/nightly", + }; + // This is a primitive so the url is done "by hand". + Some((s.clone(), + format!("{}{}std/primitive.{}.html", + url, + if !url.ends_with('/') { "/" } else { "" }, + fragment))) + } else { + panic!("This isn't a primitive?!"); + } } - Some((s.clone(), href)) - } else { - None } }).collect() } @@ -959,6 +985,34 @@ fn handle_variant(cx: &DocContext, def: Def) -> Result<(Def, Option<String>), () Ok((parent_def, Some(format!("{}.v", variant.name)))) } +const PRIMITIVES: &[(&str, Def)] = &[ + ("u8", Def::PrimTy(hir::PrimTy::TyUint(syntax::ast::UintTy::U8))), + ("u16", Def::PrimTy(hir::PrimTy::TyUint(syntax::ast::UintTy::U16))), + ("u32", Def::PrimTy(hir::PrimTy::TyUint(syntax::ast::UintTy::U32))), + ("u64", Def::PrimTy(hir::PrimTy::TyUint(syntax::ast::UintTy::U64))), + ("u128", Def::PrimTy(hir::PrimTy::TyUint(syntax::ast::UintTy::U128))), + ("usize", Def::PrimTy(hir::PrimTy::TyUint(syntax::ast::UintTy::Usize))), + ("i8", Def::PrimTy(hir::PrimTy::TyInt(syntax::ast::IntTy::I8))), + ("i16", Def::PrimTy(hir::PrimTy::TyInt(syntax::ast::IntTy::I16))), + ("i32", Def::PrimTy(hir::PrimTy::TyInt(syntax::ast::IntTy::I32))), + ("i64", Def::PrimTy(hir::PrimTy::TyInt(syntax::ast::IntTy::I64))), + ("i128", Def::PrimTy(hir::PrimTy::TyInt(syntax::ast::IntTy::I128))), + ("isize", Def::PrimTy(hir::PrimTy::TyInt(syntax::ast::IntTy::Isize))), + ("f32", Def::PrimTy(hir::PrimTy::TyFloat(syntax::ast::FloatTy::F32))), + ("f64", Def::PrimTy(hir::PrimTy::TyFloat(syntax::ast::FloatTy::F64))), + ("str", Def::PrimTy(hir::PrimTy::TyStr)), + ("bool", Def::PrimTy(hir::PrimTy::TyBool)), + ("char", Def::PrimTy(hir::PrimTy::TyChar)), +]; + +fn is_primitive(path_str: &str, is_val: bool) -> Option<Def> { + if is_val { + None + } else { + PRIMITIVES.iter().find(|x| x.0 == path_str).map(|x| x.1) + } +} + /// Resolve a given string as a path, along with whether or not it is /// in the value namespace. Also returns an optional URL fragment in the case /// of variants and methods @@ -987,6 +1041,8 @@ fn resolve(cx: &DocContext, path_str: &str, is_val: bool) -> Result<(Def, Option if value != is_val { return Err(()) } + } else if let Some(prim) = is_primitive(path_str, is_val) { + return Ok((prim, Some(path_str.to_owned()))) } else { // If resolution failed, it may still be a method // because methods are not handled by the resolver @@ -1051,7 +1107,6 @@ fn resolve(cx: &DocContext, path_str: &str, is_val: bool) -> Result<(Def, Option } _ => Err(()) } - } else { Err(()) } @@ -1218,8 +1273,12 @@ impl Clean<Attributes> for [ast::Attribute] { } }; - let id = register_def(cx, def); - attrs.links.push((ori_link, id, fragment)); + if let Def::PrimTy(_) = def { + attrs.links.push((ori_link, None, fragment)); + } else { + let id = register_def(cx, def); + attrs.links.push((ori_link, Some(id), fragment)); + } } cx.sess().abort_if_errors(); diff --git a/src/test/rustdoc/primitive-link.rs b/src/test/rustdoc/primitive-link.rs new file mode 100644 index 00000000000..b0cf8acc7c0 --- /dev/null +++ b/src/test/rustdoc/primitive-link.rs @@ -0,0 +1,19 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_name = "foo"] + +// ignore-tidy-linelength + +// @has foo/struct.Foo.html '//*[@class="docblock"]/p/a[@href="https://doc.rust-lang.org/nightly/std/primitive.u32.html"]' 'u32' +// @has foo/struct.Foo.html '//*[@class="docblock"]/p/a[@href="https://doc.rust-lang.org/nightly/std/primitive.i64.html"]' 'i64' + +/// It contains [`u32`] and [i64]. +pub struct Foo; |
