diff options
Diffstat (limited to 'src/librustdoc/html/render.rs')
| -rw-r--r-- | src/librustdoc/html/render.rs | 220 | 
1 files changed, 85 insertions, 135 deletions
| diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 4dd2a6562a4..f51f47a8d33 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -42,9 +42,6 @@ use std::rc::Rc; use std::str; use std::sync::Arc; -use rustc::middle::privacy::AccessLevels; -use rustc::middle::stability; -use rustc_ast::ast; use rustc_ast_pretty::pprust; use rustc_data_structures::flock; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; @@ -52,6 +49,8 @@ use rustc_feature::UnstableFeatures; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::Mutability; +use rustc_middle::middle::privacy::AccessLevels; +use rustc_middle::middle::stability; use rustc_span::edition::Edition; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::FileName; @@ -59,8 +58,8 @@ use rustc_span::symbol::{sym, Symbol}; use serde::ser::SerializeSeq; use serde::{Serialize, Serializer}; -use crate::clean::{self, AttributesExt, Deprecation, GetDefId, SelfTy}; -use crate::config::RenderOptions; +use crate::clean::{self, AttributesExt, Deprecation, GetDefId, SelfTy, TypeKind}; +use crate::config::{OutputFormat, RenderOptions}; use crate::docfs::{DocFS, ErrorStorage, PathError}; use crate::doctree; use crate::html::escape::Escape; @@ -270,6 +269,7 @@ pub struct RenderInfo { pub deref_trait_did: Option<DefId>, pub deref_mut_trait_did: Option<DefId>, pub owned_box_did: Option<DefId>, + pub output_format: Option<OutputFormat>, } // Helper structs for rendering items/sidebars and carrying along contextual @@ -302,19 +302,25 @@ impl Serialize for IndexItem { /// A type used for the search index. #[derive(Debug)] -struct Type { +struct RenderType { + ty: Option<DefId>, + idx: Option<usize>, name: Option<String>, - generics: Option<Vec<String>>, + generics: Option<Vec<Generic>>, } -impl Serialize for Type { +impl Serialize for RenderType { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, { if let Some(name) = &self.name { let mut seq = serializer.serialize_seq(None)?; - seq.serialize_element(&name)?; + if let Some(id) = self.idx { + seq.serialize_element(&id)?; + } else { + seq.serialize_element(&name)?; + } if let Some(generics) = &self.generics { seq.serialize_element(&generics)?; } @@ -325,11 +331,32 @@ impl Serialize for Type { } } +/// A type used for the search index. +#[derive(Debug)] +struct Generic { + name: String, + defid: Option<DefId>, + idx: Option<usize>, +} + +impl Serialize for Generic { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + if let Some(id) = self.idx { + serializer.serialize_some(&id) + } else { + serializer.serialize_some(&self.name) + } + } +} + /// Full type of functions/methods in the search index. #[derive(Debug)] struct IndexItemFunctionType { - inputs: Vec<Type>, - output: Option<Vec<Type>>, + inputs: Vec<TypeWithKind>, + output: Option<Vec<TypeWithKind>>, } impl Serialize for IndexItemFunctionType { @@ -340,8 +367,8 @@ impl Serialize for IndexItemFunctionType { // If we couldn't figure out a type, just write `null`. let mut iter = self.inputs.iter(); if match self.output { - Some(ref output) => iter.chain(output.iter()).any(|ref i| i.name.is_none()), - None => iter.any(|ref i| i.name.is_none()), + Some(ref output) => iter.chain(output.iter()).any(|ref i| i.ty.name.is_none()), + None => iter.any(|ref i| i.ty.name.is_none()), } { serializer.serialize_none() } else { @@ -359,6 +386,31 @@ impl Serialize for IndexItemFunctionType { } } +#[derive(Debug)] +pub struct TypeWithKind { + ty: RenderType, + kind: TypeKind, +} + +impl From<(RenderType, TypeKind)> for TypeWithKind { + fn from(x: (RenderType, TypeKind)) -> TypeWithKind { + TypeWithKind { ty: x.0, kind: x.1 } + } +} + +impl Serialize for TypeWithKind { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + let mut seq = serializer.serialize_seq(None)?; + seq.serialize_element(&self.ty.name)?; + let x: ItemType = self.kind.into(); + seq.serialize_element(&x)?; + seq.end() + } +} + thread_local!(static CACHE_KEY: RefCell<Arc<Cache>> = Default::default()); thread_local!(pub static CURRENT_DEPTH: Cell<usize> = Cell::new(0)); @@ -730,7 +782,7 @@ themePicker.onblur = handleThemeButtonsBlur; .split('"') .next() .map(|s| s.to_owned()) - .unwrap_or_else(|| String::new()), + .unwrap_or_else(String::new), ); } } @@ -1542,7 +1594,7 @@ impl Context { } if self.shared.sort_modules_alphabetically { - for (_, items) in &mut map { + for items in map.values_mut() { items.sort(); } } @@ -1565,7 +1617,7 @@ impl Context { let mut path = String::new(); - // We can safely ignore macros from other libraries + // We can safely ignore synthetic `SourceFile`s. let file = match item.source.filename { FileName::Real(ref path) => path, _ => return None, @@ -2106,7 +2158,7 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean: docs = MarkdownSummaryLine(doc_value, &myitem.links()).to_string(), class = myitem.type_(), add = add, - stab = stab.unwrap_or_else(|| String::new()), + stab = stab.unwrap_or_else(String::new), unsafety_flag = unsafety_flag, href = item_path(myitem.type_(), myitem.name.as_ref().unwrap()), title = [full_path(cx, myitem), myitem.type_().to_string()] @@ -2325,7 +2377,7 @@ fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Func f.generics.print() ) .len(); - write!(w, "{}<pre class='rust fn'>", render_spotlight_traits(it)); + write!(w, "<pre class='rust fn'>"); render_attributes(w, it, false); write!( w, @@ -2528,13 +2580,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait) let item_type = m.type_(); let id = cx.derive_id(format!("{}.{}", item_type, name)); let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space())); - write!( - w, - "<h3 id='{id}' class='method'>{extra}<code id='{ns_id}'>", - extra = render_spotlight_traits(m), - id = id, - ns_id = ns_id - ); + write!(w, "<h3 id='{id}' class='method'><code id='{ns_id}'>", id = id, ns_id = ns_id); render_assoc_item(w, m, AssocItemLink::Anchor(Some(&id)), ItemType::Impl); write!(w, "</code>"); render_stability_since(w, m, t); @@ -2727,7 +2773,7 @@ fn naive_assoc_href(it: &clean::Item, link: AssocItemLink<'_>) -> String { let name = it.name.as_ref().unwrap(); let ty = match it.type_() { Typedef | AssocType => AssocType, - s @ _ => s, + s => s, }; let anchor = format!("#{}.{}", ty, name); @@ -3131,26 +3177,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) { render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } -fn render_attribute(attr: &ast::MetaItem) -> Option<String> { - let path = pprust::path_to_string(&attr.path); - - if attr.is_word() { - Some(path) - } else if let Some(v) = attr.value_str() { - Some(format!("{} = {:?}", path, v)) - } else if let Some(values) = attr.meta_item_list() { - let display: Vec<_> = values - .iter() - .filter_map(|attr| attr.meta_item().and_then(|mi| render_attribute(mi))) - .collect(); - - if !display.is_empty() { Some(format!("{}({})", path, display.join(", "))) } else { None } - } else { - None - } -} - -const ATTRIBUTE_WHITELIST: &'static [Symbol] = &[ +const ATTRIBUTE_WHITELIST: &[Symbol] = &[ sym::export_name, sym::lang, sym::link_section, @@ -3175,9 +3202,8 @@ fn render_attributes(w: &mut Buffer, it: &clean::Item, top: bool) { if !ATTRIBUTE_WHITELIST.contains(&attr.name_or_empty()) { continue; } - if let Some(s) = render_attribute(&attr.meta().unwrap()) { - attrs.push_str(&format!("#[{}]\n", s)); - } + + attrs.push_str(&pprust::attribute_to_string(&attr)); } if !attrs.is_empty() { write!( @@ -3401,10 +3427,8 @@ fn render_assoc_items( let deref_impl = traits.iter().find(|t| t.inner_impl().trait_.def_id() == c.deref_trait_did); if let Some(impl_) = deref_impl { - let has_deref_mut = traits - .iter() - .find(|t| t.inner_impl().trait_.def_id() == c.deref_mut_trait_did) - .is_some(); + let has_deref_mut = + traits.iter().any(|t| t.inner_impl().trait_.def_id() == c.deref_mut_trait_did); render_deref_methods(w, cx, impl_, containing_item, has_deref_mut); } @@ -3520,76 +3544,6 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool) -> bool { } } -fn render_spotlight_traits(item: &clean::Item) -> String { - match item.inner { - clean::FunctionItem(clean::Function { ref decl, .. }) - | clean::TyMethodItem(clean::TyMethod { ref decl, .. }) - | clean::MethodItem(clean::Method { ref decl, .. }) - | clean::ForeignFunctionItem(clean::Function { ref decl, .. }) => spotlight_decl(decl), - _ => String::new(), - } -} - -fn spotlight_decl(decl: &clean::FnDecl) -> String { - let mut out = Buffer::html(); - let mut trait_ = String::new(); - - if let Some(did) = decl.output.def_id() { - let c = cache(); - if let Some(impls) = c.impls.get(&did) { - for i in impls { - let impl_ = i.inner_impl(); - if impl_.trait_.def_id().map_or(false, |d| c.traits[&d].is_spotlight) { - if out.is_empty() { - out.push_str(&format!( - "<h3 class=\"important\">Important traits for {}</h3>\ - <code class=\"content\">", - impl_.for_.print() - )); - trait_.push_str(&impl_.for_.print().to_string()); - } - - //use the "where" class here to make it small - out.push_str(&format!( - "<span class=\"where fmt-newline\">{}</span>", - impl_.print() - )); - let t_did = impl_.trait_.def_id().unwrap(); - for it in &impl_.items { - if let clean::TypedefItem(ref tydef, _) = it.inner { - out.push_str("<span class=\"where fmt-newline\"> "); - assoc_type( - &mut out, - it, - &[], - Some(&tydef.type_), - AssocItemLink::GotoSource(t_did, &FxHashSet::default()), - "", - ); - out.push_str(";</span>"); - } - } - } - } - } - } - - if !out.is_empty() { - out.insert_str( - 0, - &format!( - "<div class=\"important-traits\"><div class='tooltip'>ⓘ\ - <span class='tooltiptext'>Important traits for {}</span></div>\ - <div class=\"content hidden\">", - trait_ - ), - ); - out.push_str("</code></div></div>"); - } - - out.into_inner() -} - fn render_impl( w: &mut Buffer, cx: &Context, @@ -3601,7 +3555,7 @@ fn render_impl( use_absolute: Option<bool>, is_on_foreign_type: bool, show_default_items: bool, - // This argument is used to reference same type with different pathes to avoid duplication + // This argument is used to reference same type with different paths to avoid duplication // in documentation pages for trait with automatic implementations like "Send" and "Sync". aliases: &[String], ) { @@ -3696,14 +3650,13 @@ fn render_impl( (true, " hidden") }; match item.inner { - clean::MethodItem(clean::Method { ref decl, .. }) - | clean::TyMethodItem(clean::TyMethod { ref decl, .. }) => { + clean::MethodItem(clean::Method { .. }) + | clean::TyMethodItem(clean::TyMethod { .. }) => { // Only render when the method is not static or we allow static methods if render_method_item { let id = cx.derive_id(format!("{}.{}", item_type, name)); let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space())); write!(w, "<h4 id='{}' class=\"{}{}\">", id, item_type, extra_class); - write!(w, "{}", spotlight_decl(decl)); write!(w, "<code id='{}'>", ns_id); render_assoc_item(w, item, link.anchor(&id), ItemType::Impl); write!(w, "</code>"); @@ -3816,7 +3769,7 @@ fn render_impl( ) { for trait_item in &t.items { let n = trait_item.name.clone(); - if i.items.iter().find(|m| m.name == n).is_some() { + if i.items.iter().any(|m| m.name == n) { continue; } let did = i.trait_.as_ref().unwrap().def_id().unwrap(); @@ -4610,7 +4563,7 @@ fn item_keyword(w: &mut Buffer, cx: &Context, it: &clean::Item) { document(w, cx, it) } -crate const BASIC_KEYWORDS: &'static str = "rust, rustlang, rust-lang"; +crate const BASIC_KEYWORDS: &str = "rust, rustlang, rust-lang"; fn make_item_keywords(it: &clean::Item) -> String { format!("{}, {}", BASIC_KEYWORDS, it.name.as_ref().unwrap()) @@ -4640,12 +4593,9 @@ fn collect_paths_for_type(first_ty: clean::Type) -> Vec<String> { let get_extern = || cache.external_paths.get(&did).map(|s| s.0.clone()); let fqp = cache.exact_paths.get(&did).cloned().or_else(get_extern); - match fqp { - Some(path) => { - out.push(path.join("::")); - } - _ => {} - }; + if let Some(path) = fqp { + out.push(path.join("::")); + } } clean::Type::Tuple(tys) => { work.extend(tys.into_iter()); | 
