]> git.lizzy.rs Git - rust.git/commitdiff
track items per-file instead of per-type
authorQuietMisdreavus <grey@quietmisdreavus.net>
Thu, 28 Feb 2019 21:27:42 +0000 (15:27 -0600)
committerQuietMisdreavus <grey@quietmisdreavus.net>
Thu, 28 Feb 2019 22:13:55 +0000 (16:13 -0600)
src/librustdoc/passes/calculate_doc_coverage.rs

index f70de1ce9510e72e2c23e7d70a3fd618b06e3f3a..6e0238b7a4d5ef58ff6972fa2fe4285d40553174 100644 (file)
@@ -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 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 
 #[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 @@ fn fold_item(&mut self, mut i: clean::Item) -> Option<clean::Item> {
             }
             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_),
-        }
-}