@@ -2,8 +2,9 @@ use crate::clean;
22use crate :: config:: OutputFormat ;
33use crate :: core:: DocContext ;
44use crate :: fold:: { self , DocFolder } ;
5+ use crate :: html:: markdown:: { find_testable_code, ErrorCodes } ;
6+ use crate :: passes:: doc_test_lints:: Tests ;
57use crate :: passes:: Pass ;
6-
78use rustc_span:: symbol:: sym;
89use rustc_span:: FileName ;
910use serde:: Serialize ;
@@ -30,15 +31,19 @@ fn calculate_doc_coverage(krate: clean::Crate, ctx: &DocContext<'_>) -> clean::C
3031struct ItemCount {
3132 total : u64 ,
3233 with_docs : u64 ,
34+ with_examples : u64 ,
3335}
3436
3537impl ItemCount {
36- fn count_item ( & mut self , has_docs : bool ) {
38+ fn count_item ( & mut self , has_docs : bool , has_doc_example : bool ) {
3739 self . total += 1 ;
3840
3941 if has_docs {
4042 self . with_docs += 1 ;
4143 }
44+ if has_doc_example {
45+ self . with_examples += 1 ;
46+ }
4247 }
4348
4449 fn percentage ( & self ) -> Option < f64 > {
@@ -48,20 +53,33 @@ impl ItemCount {
4853 None
4954 }
5055 }
56+
57+ fn examples_percentage ( & self ) -> Option < f64 > {
58+ if self . total > 0 {
59+ Some ( ( self . with_examples as f64 * 100.0 ) / self . total as f64 )
60+ } else {
61+ None
62+ }
63+ }
5164}
5265
5366impl ops:: Sub for ItemCount {
5467 type Output = Self ;
5568
5669 fn sub ( self , rhs : Self ) -> Self {
57- ItemCount { total : self . total - rhs. total , with_docs : self . with_docs - rhs. with_docs }
70+ ItemCount {
71+ total : self . total - rhs. total ,
72+ with_docs : self . with_docs - rhs. with_docs ,
73+ with_examples : self . with_examples - rhs. with_examples ,
74+ }
5875 }
5976}
6077
6178impl ops:: AddAssign for ItemCount {
6279 fn add_assign ( & mut self , rhs : Self ) {
6380 self . total += rhs. total ;
6481 self . with_docs += rhs. with_docs ;
82+ self . with_examples += rhs. with_examples ;
6583 }
6684}
6785
@@ -103,40 +121,73 @@ impl CoverageCalculator {
103121 let mut total = ItemCount :: default ( ) ;
104122
105123 fn print_table_line ( ) {
106- println ! ( "+-{0:->35}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+" , "" ) ;
124+ println ! ( "+-{0:->35}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+-{0:->10}-+ " , "" ) ;
107125 }
108126
109- fn print_table_record ( name : & str , count : ItemCount , percentage : f64 ) {
127+ fn print_table_record (
128+ name : & str ,
129+ count : ItemCount ,
130+ percentage : f64 ,
131+ examples_percentage : f64 ,
132+ ) {
110133 println ! (
111- "| {:<35} | {:>10} | {:>10} | {:>9.1}% |" ,
112- name, count. with_docs, count. total, percentage
134+ "| {:<35} | {:>10} | {:>10} | {:>9.1}% | {:>10} | {:>9.1}% |" ,
135+ name,
136+ count. with_docs,
137+ count. total,
138+ percentage,
139+ count. with_examples,
140+ examples_percentage,
113141 ) ;
114142 }
115143
116144 print_table_line ( ) ;
117145 println ! (
118- "| {:<35} | {:>10} | {:>10} | {:>10} |" ,
119- "File" , "Documented" , "Total" , "Percentage"
146+ "| {:<35} | {:>10} | {:>10} | {:>10} | {:>10} | {:>10} | " ,
147+ "File" , "Documented" , "Total" , "Percentage" , "Examples" , "Percentage" ,
120148 ) ;
121149 print_table_line ( ) ;
122150
123151 for ( file, & count) in & self . items {
124- if let Some ( percentage) = count. percentage ( ) {
125- print_table_record ( & limit_filename_len ( file. to_string ( ) ) , count, percentage) ;
152+ if let ( Some ( percentage) , Some ( examples_percentage) ) =
153+ ( count. percentage ( ) , count. examples_percentage ( ) )
154+ {
155+ print_table_record (
156+ & limit_filename_len ( file. to_string ( ) ) ,
157+ count,
158+ percentage,
159+ examples_percentage,
160+ ) ;
126161
127162 total += count;
128163 }
129164 }
130165
131166 print_table_line ( ) ;
132- print_table_record ( "Total" , total, total. percentage ( ) . unwrap_or ( 0.0 ) ) ;
167+ print_table_record (
168+ "Total" ,
169+ total,
170+ total. percentage ( ) . unwrap_or ( 0.0 ) ,
171+ total. examples_percentage ( ) . unwrap_or ( 0.0 ) ,
172+ ) ;
133173 print_table_line ( ) ;
134174 }
135175}
136176
137177impl fold:: DocFolder for CoverageCalculator {
138178 fn fold_item ( & mut self , i : clean:: Item ) -> Option < clean:: Item > {
139179 let has_docs = !i. attrs . doc_strings . is_empty ( ) ;
180+ let mut tests = Tests { found_tests : 0 } ;
181+
182+ find_testable_code (
183+ & i. attrs . doc_strings . iter ( ) . map ( |d| d. as_str ( ) ) . collect :: < Vec < _ > > ( ) . join ( "\n " ) ,
184+ & mut tests,
185+ ErrorCodes :: No ,
186+ false ,
187+ None ,
188+ ) ;
189+
190+ let has_doc_example = tests. found_tests != 0 ;
140191
141192 match i. inner {
142193 _ if !i. def_id . is_local ( ) => {
@@ -187,7 +238,10 @@ impl fold::DocFolder for CoverageCalculator {
187238 }
188239 _ => {
189240 debug ! ( "counting {:?} {:?} in {}" , i. type_( ) , i. name, i. source. filename) ;
190- self . items . entry ( i. source . filename . clone ( ) ) . or_default ( ) . count_item ( has_docs) ;
241+ self . items
242+ . entry ( i. source . filename . clone ( ) )
243+ . or_default ( )
244+ . count_item ( has_docs, has_doc_example) ;
191245 }
192246 }
193247
0 commit comments