Skip to content

Commit 1b63543

Browse files
track items per-file instead of per-type
1 parent 80b4919 commit 1b63543

File tree

1 file changed

+33
-117
lines changed

1 file changed

+33
-117
lines changed
+33-117
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use crate::clean;
22
use crate::core::DocContext;
3-
use crate::html::item_type::ItemType;
43
use crate::fold::{self, DocFolder};
54
use crate::passes::Pass;
65

76
use syntax::attr;
7+
use syntax_pos::FileName;
88

99
use std::collections::BTreeMap;
1010
use std::fmt;
@@ -75,74 +75,51 @@ impl fmt::Display for ItemCount {
7575

7676
#[derive(Default)]
7777
struct CoverageCalculator {
78-
items: BTreeMap<ItemType, ItemCount>,
78+
items: BTreeMap<FileName, ItemCount>,
7979
}
8080

8181
impl CoverageCalculator {
8282
fn print_results(&self) {
83-
use crate::html::item_type::ItemType::*;
84-
8583
let mut total = ItemCount::default();
8684

87-
let main_types = [
88-
Module, Function,
89-
Struct, StructField,
90-
Enum, Variant,
91-
Union,
92-
Method,
93-
Trait, TyMethod,
94-
AssociatedType, AssociatedConst,
95-
Macro,
96-
Static, Constant,
97-
ForeignType, Existential,
98-
Typedef, TraitAlias,
99-
Primitive, Keyword,
100-
];
101-
102-
println!("+-{0:->25}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", "");
103-
println!("| {:<25} | {:>10} | {:>10} | {:>10} |",
104-
"Item Type", "Documented", "Total", "Percentage");
105-
println!("+-{0:->25}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", "");
106-
107-
for item_type in &main_types {
108-
let count = self.items.get(item_type).cloned().unwrap_or_default();
109-
110-
if let Some(percentage) = count.percentage() {
111-
println!("| {:<25} | {:>10} | {:>10} | {:>9.1}% |",
112-
table_name(item_type), count.with_docs, count.total, percentage);
85+
fn print_table_line() {
86+
println!("+-{0:->35}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", "");
87+
}
11388

114-
total += count;
115-
}
89+
fn print_table_record(name: &str, count: ItemCount, percentage: f64) {
90+
println!("| {:<35} | {:>10} | {:>10} | {:>9.1}% |",
91+
name, count.with_docs, count.total, percentage);
11692
}
11793

118-
println!("+-{0:->25}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", "");
94+
print_table_line();
95+
println!("| {:<35} | {:>10} | {:>10} | {:>10} |",
96+
"File", "Documented", "Total", "Percentage");
97+
print_table_line();
11998

120-
if let Some(count) = self.items.get(&Impl) {
99+
for (file, &count) in &self.items {
121100
if let Some(percentage) = count.percentage() {
122-
if let Some(percentage) = total.percentage() {
123-
println!("| {:<25} | {:>10} | {:>10} | {:>9.1}% |",
124-
"Total (non trait impls)", total.with_docs, total.total, percentage);
101+
let mut name = file.to_string();
102+
// if a filename is too long, shorten it so we don't blow out the table
103+
// FIXME(misdreavus): this needs to count graphemes, and probably also track
104+
// double-wide characters...
105+
if name.len() > 35 {
106+
name = "...".to_string() + &name[name.len()-32..];
125107
}
126108

127-
println!("+-{0:->25}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", "");
128-
129-
println!("| {:<25} | {:>10} | {:>10} | {:>9.1}% |",
130-
table_name(&Impl), count.with_docs, count.total, percentage);
131-
132-
println!("+-{0:->25}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", "");
109+
print_table_record(&name, count, percentage);
133110

134-
total += *count;
111+
total += count;
135112
}
136113
}
137114

138-
println!("| {:<25} | {:>10} | {:>10} | {:>9.1}% |",
139-
"Total", total.with_docs, total.total, total.percentage().unwrap_or(0.0));
140-
println!("+-{0:->25}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+", "");
115+
print_table_line();
116+
print_table_record("Total", total, total.percentage().unwrap_or(0.0));
117+
print_table_line();
141118
}
142119
}
143120

144121
impl fold::DocFolder for CoverageCalculator {
145-
fn fold_item(&mut self, mut i: clean::Item) -> Option<clean::Item> {
122+
fn fold_item(&mut self, i: clean::Item) -> Option<clean::Item> {
146123
let has_docs = !i.attrs.doc_strings.is_empty();
147124

148125
match i.inner {
@@ -171,87 +148,26 @@ impl fold::DocFolder for CoverageCalculator {
171148
}
172149
clean::ImplItem(ref impl_) => {
173150
if let Some(ref tr) = impl_.trait_ {
174-
debug!("counting impl {:#} for {:#}", tr, impl_.for_);
175-
176-
// trait impls inherit their docs from the trait definition, so documenting
177-
// them can be considered optional
178-
self.items.entry(ItemType::Impl).or_default().count_item(has_docs);
179-
180-
for it in &impl_.items {
181-
let has_docs = !it.attrs.doc_strings.is_empty();
182-
self.items.entry(ItemType::Impl).or_default().count_item(has_docs);
183-
}
151+
debug!("impl {:#} for {:#} in {}", tr, impl_.for_, i.source.filename);
184152

185-
// now skip recursing, so that we don't double-count this impl's items
153+
// don't count trait impls, the missing-docs lint doesn't so we shouldn't
154+
// either
186155
return Some(i);
187156
} else {
188157
// inherent impls *can* be documented, and those docs show up, but in most
189158
// cases it doesn't make sense, as all methods on a type are in one single
190159
// impl block
191-
debug!("not counting impl {:#}", impl_.for_);
160+
debug!("impl {:#} in {}", impl_.for_, i.source.filename);
192161
}
193162
}
194-
clean::MacroItem(..) | clean::ProcMacroItem(..) => {
195-
// combine `macro_rules!` macros and proc-macros in the same count
196-
debug!("counting macro {:?}", i.name);
197-
self.items.entry(ItemType::Macro).or_default().count_item(has_docs);
198-
}
199-
clean::TraitItem(ref mut trait_) => {
200-
// because both trait methods with a default impl and struct methods are
201-
// ItemType::Method, we need to properly tag trait methods as TyMethod instead
202-
debug!("counting trait {:?}", i.name);
203-
self.items.entry(ItemType::Trait).or_default().count_item(has_docs);
204-
205-
// since we're not going on to document the crate, it doesn't matter if we discard
206-
// the item after counting it
207-
trait_.items.retain(|it| {
208-
if it.type_() == ItemType::Method {
209-
let has_docs = !it.attrs.doc_strings.is_empty();
210-
self.items.entry(ItemType::TyMethod).or_default().count_item(has_docs);
211-
false
212-
} else {
213-
true
214-
}
215-
});
216-
}
217163
_ => {
218-
debug!("counting {} {:?}", i.type_(), i.name);
219-
self.items.entry(i.type_()).or_default().count_item(has_docs);
164+
debug!("counting {} {:?} in {}", i.type_(), i.name, i.source.filename);
165+
self.items.entry(i.source.filename.clone())
166+
.or_default()
167+
.count_item(has_docs);
220168
}
221169
}
222170

223171
self.fold_item_recur(i)
224172
}
225173
}
226-
227-
fn table_name(type_: &ItemType) -> &'static str {
228-
match *type_ {
229-
ItemType::Module => "Modules",
230-
ItemType::Struct => "Structs",
231-
ItemType::Union => "Unions",
232-
ItemType::Enum => "Enums",
233-
ItemType::Function => "Functions",
234-
ItemType::Typedef => "Type Aliases",
235-
ItemType::Static => "Statics",
236-
ItemType::Trait => "Traits",
237-
// inherent impls aren't counted, and trait impls get all their items thrown into this
238-
// counter
239-
ItemType::Impl => "Trait Impl Items",
240-
// even though trait methods with a default impl get cleaned as Method, we convert them
241-
// to TyMethod when counting
242-
ItemType::TyMethod => "Trait Methods",
243-
ItemType::Method => "Methods",
244-
ItemType::StructField => "Struct Fields",
245-
ItemType::Variant => "Enum Variants",
246-
ItemType::Macro => "Macros",
247-
ItemType::Primitive => "Primitives",
248-
ItemType::AssociatedType => "Associated Types",
249-
ItemType::Constant => "Constants",
250-
ItemType::AssociatedConst => "Associated Constants",
251-
ItemType::ForeignType => "Extern Types",
252-
ItemType::Keyword => "Keywords",
253-
ItemType::Existential => "Existential Types",
254-
ItemType::TraitAlias => "Trait Aliases",
255-
_ => panic!("unanticipated ItemType: {}", type_),
256-
}
257-
}

0 commit comments

Comments
 (0)