diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustdoc/passes/calculate_doc_coverage.rs | 150 |
1 files changed, 33 insertions, 117 deletions
diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index f70de1ce951..6e0238b7a4d 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -1,10 +1,10 @@ use crate::clean; use crate::core::DocContext; -use crate::html::item_type::ItemType; use crate::fold::{self, DocFolder}; use crate::passes::Pass; use syntax::attr; +use syntax_pos::FileName; use std::collections::BTreeMap; use std::fmt; @@ -75,74 +75,51 @@ impl fmt::Display for ItemCount { #[derive(Default)] struct CoverageCalculator { - items: BTreeMap<ItemType, ItemCount>, + items: BTreeMap<FileName, ItemCount>, } impl CoverageCalculator { fn print_results(&self) { - use crate::html::item_type::ItemType::*; - let mut total = ItemCount::default(); - let main_types = [ - Module, Function, - Struct, StructField, - Enum, Variant, - Union, - Method, - Trait, TyMethod, - AssociatedType, AssociatedConst, - Macro, - Static, Constant, - ForeignType, Existential, - Typedef, TraitAlias, - Primitive, Keyword, - ]; - - println!("+-{0:->25}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", ""); - println!("| {:<25} | {:>10} | {:>10} | {:>10} |", - "Item Type", "Documented", "Total", "Percentage"); - println!("+-{0:->25}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", ""); - - for item_type in &main_types { - let count = self.items.get(item_type).cloned().unwrap_or_default(); - - if let Some(percentage) = count.percentage() { - println!("| {:<25} | {:>10} | {:>10} | {:>9.1}% |", - table_name(item_type), count.with_docs, count.total, percentage); + fn print_table_line() { + println!("+-{0:->35}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", ""); + } - total += count; - } + fn print_table_record(name: &str, count: ItemCount, percentage: f64) { + println!("| {:<35} | {:>10} | {:>10} | {:>9.1}% |", + name, count.with_docs, count.total, percentage); } - println!("+-{0:->25}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", ""); + print_table_line(); + println!("| {:<35} | {:>10} | {:>10} | {:>10} |", + "File", "Documented", "Total", "Percentage"); + print_table_line(); - if let Some(count) = self.items.get(&Impl) { + for (file, &count) in &self.items { if let Some(percentage) = count.percentage() { - if let Some(percentage) = total.percentage() { - println!("| {:<25} | {:>10} | {:>10} | {:>9.1}% |", - "Total (non trait impls)", total.with_docs, total.total, percentage); + let mut name = file.to_string(); + // if a filename is too long, shorten it so we don't blow out the table + // FIXME(misdreavus): this needs to count graphemes, and probably also track + // double-wide characters... + if name.len() > 35 { + name = "...".to_string() + &name[name.len()-32..]; } - println!("+-{0:->25}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", ""); - - println!("| {:<25} | {:>10} | {:>10} | {:>9.1}% |", - table_name(&Impl), count.with_docs, count.total, percentage); - - println!("+-{0:->25}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", ""); + print_table_record(&name, count, percentage); - total += *count; + total += count; } } - println!("| {:<25} | {:>10} | {:>10} | {:>9.1}% |", - "Total", total.with_docs, total.total, total.percentage().unwrap_or(0.0)); - println!("+-{0:->25}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", ""); + print_table_line(); + print_table_record("Total", total, total.percentage().unwrap_or(0.0)); + print_table_line(); } } impl fold::DocFolder for CoverageCalculator { - fn fold_item(&mut self, mut i: clean::Item) -> Option<clean::Item> { + fn fold_item(&mut self, i: clean::Item) -> Option<clean::Item> { let has_docs = !i.attrs.doc_strings.is_empty(); match i.inner { @@ -171,87 +148,26 @@ impl fold::DocFolder for CoverageCalculator { } clean::ImplItem(ref impl_) => { if let Some(ref tr) = impl_.trait_ { - debug!("counting impl {:#} for {:#}", tr, impl_.for_); - - // trait impls inherit their docs from the trait definition, so documenting - // them can be considered optional - self.items.entry(ItemType::Impl).or_default().count_item(has_docs); - - for it in &impl_.items { - let has_docs = !it.attrs.doc_strings.is_empty(); - self.items.entry(ItemType::Impl).or_default().count_item(has_docs); - } + debug!("impl {:#} for {:#} in {}", tr, impl_.for_, i.source.filename); - // now skip recursing, so that we don't double-count this impl's items + // don't count trait impls, the missing-docs lint doesn't so we shouldn't + // either return Some(i); } else { // inherent impls *can* be documented, and those docs show up, but in most // cases it doesn't make sense, as all methods on a type are in one single // impl block - debug!("not counting impl {:#}", impl_.for_); + debug!("impl {:#} in {}", impl_.for_, i.source.filename); } } - clean::MacroItem(..) | clean::ProcMacroItem(..) => { - // combine `macro_rules!` macros and proc-macros in the same count - debug!("counting macro {:?}", i.name); - self.items.entry(ItemType::Macro).or_default().count_item(has_docs); - } - clean::TraitItem(ref mut trait_) => { - // because both trait methods with a default impl and struct methods are - // ItemType::Method, we need to properly tag trait methods as TyMethod instead - debug!("counting trait {:?}", i.name); - self.items.entry(ItemType::Trait).or_default().count_item(has_docs); - - // since we're not going on to document the crate, it doesn't matter if we discard - // the item after counting it - trait_.items.retain(|it| { - if it.type_() == ItemType::Method { - let has_docs = !it.attrs.doc_strings.is_empty(); - self.items.entry(ItemType::TyMethod).or_default().count_item(has_docs); - false - } else { - true - } - }); - } _ => { - debug!("counting {} {:?}", i.type_(), i.name); - self.items.entry(i.type_()).or_default().count_item(has_docs); + debug!("counting {} {:?} in {}", i.type_(), i.name, i.source.filename); + self.items.entry(i.source.filename.clone()) + .or_default() + .count_item(has_docs); } } self.fold_item_recur(i) } } - -fn table_name(type_: &ItemType) -> &'static str { - match *type_ { - ItemType::Module => "Modules", - ItemType::Struct => "Structs", - ItemType::Union => "Unions", - ItemType::Enum => "Enums", - ItemType::Function => "Functions", - ItemType::Typedef => "Type Aliases", - ItemType::Static => "Statics", - ItemType::Trait => "Traits", - // inherent impls aren't counted, and trait impls get all their items thrown into this - // counter - ItemType::Impl => "Trait Impl Items", - // even though trait methods with a default impl get cleaned as Method, we convert them - // to TyMethod when counting - ItemType::TyMethod => "Trait Methods", - ItemType::Method => "Methods", - ItemType::StructField => "Struct Fields", - ItemType::Variant => "Enum Variants", - ItemType::Macro => "Macros", - ItemType::Primitive => "Primitives", - ItemType::AssociatedType => "Associated Types", - ItemType::Constant => "Constants", - ItemType::AssociatedConst => "Associated Constants", - ItemType::ForeignType => "Extern Types", - ItemType::Keyword => "Keywords", - ItemType::Existential => "Existential Types", - ItemType::TraitAlias => "Trait Aliases", - _ => panic!("unanticipated ItemType: {}", type_), - } -} |
