@@ -2,8 +2,9 @@ use crate::clean;
2
2
use crate :: config:: OutputFormat ;
3
3
use crate :: core:: DocContext ;
4
4
use crate :: fold:: { self , DocFolder } ;
5
+ use crate :: html:: markdown:: { find_testable_code, ErrorCodes } ;
6
+ use crate :: passes:: doc_test_lints:: Tests ;
5
7
use crate :: passes:: Pass ;
6
-
7
8
use rustc_span:: symbol:: sym;
8
9
use rustc_span:: FileName ;
9
10
use serde:: Serialize ;
@@ -30,15 +31,19 @@ fn calculate_doc_coverage(krate: clean::Crate, ctx: &DocContext<'_>) -> clean::C
30
31
struct ItemCount {
31
32
total : u64 ,
32
33
with_docs : u64 ,
34
+ with_examples : u64 ,
33
35
}
34
36
35
37
impl ItemCount {
36
- fn count_item ( & mut self , has_docs : bool ) {
38
+ fn count_item ( & mut self , has_docs : bool , has_doc_example : bool ) {
37
39
self . total += 1 ;
38
40
39
41
if has_docs {
40
42
self . with_docs += 1 ;
41
43
}
44
+ if has_doc_example {
45
+ self . with_examples += 1 ;
46
+ }
42
47
}
43
48
44
49
fn percentage ( & self ) -> Option < f64 > {
@@ -48,20 +53,33 @@ impl ItemCount {
48
53
None
49
54
}
50
55
}
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
+ }
51
64
}
52
65
53
66
impl ops:: Sub for ItemCount {
54
67
type Output = Self ;
55
68
56
69
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
+ }
58
75
}
59
76
}
60
77
61
78
impl ops:: AddAssign for ItemCount {
62
79
fn add_assign ( & mut self , rhs : Self ) {
63
80
self . total += rhs. total ;
64
81
self . with_docs += rhs. with_docs ;
82
+ self . with_examples += rhs. with_examples ;
65
83
}
66
84
}
67
85
@@ -103,40 +121,73 @@ impl CoverageCalculator {
103
121
let mut total = ItemCount :: default ( ) ;
104
122
105
123
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}-+ " , "" ) ;
107
125
}
108
126
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
+ ) {
110
133
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,
113
141
) ;
114
142
}
115
143
116
144
print_table_line ( ) ;
117
145
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" ,
120
148
) ;
121
149
print_table_line ( ) ;
122
150
123
151
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
+ ) ;
126
161
127
162
total += count;
128
163
}
129
164
}
130
165
131
166
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
+ ) ;
133
173
print_table_line ( ) ;
134
174
}
135
175
}
136
176
137
177
impl fold:: DocFolder for CoverageCalculator {
138
178
fn fold_item ( & mut self , i : clean:: Item ) -> Option < clean:: Item > {
139
179
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 ;
140
191
141
192
match i. inner {
142
193
_ if !i. def_id . is_local ( ) => {
@@ -187,7 +238,10 @@ impl fold::DocFolder for CoverageCalculator {
187
238
}
188
239
_ => {
189
240
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) ;
191
245
}
192
246
}
193
247
0 commit comments