@@ -4,6 +4,7 @@ use pulldown_cmark;
4
4
use rustc:: lint:: { EarlyContext , EarlyLintPass , LintArray , LintPass } ;
5
5
use rustc:: { declare_tool_lint, impl_lint_pass} ;
6
6
use rustc_data_structures:: fx:: FxHashSet ;
7
+ use std:: ops:: Range ;
7
8
use syntax:: ast;
8
9
use syntax:: source_map:: { BytePos , Span } ;
9
10
use syntax_pos:: Pos ;
@@ -57,25 +58,6 @@ impl EarlyLintPass for DocMarkdown {
57
58
}
58
59
}
59
60
60
- struct Parser < ' a > {
61
- parser : pulldown_cmark:: Parser < ' a > ,
62
- }
63
-
64
- impl < ' a > Parser < ' a > {
65
- fn new ( parser : pulldown_cmark:: Parser < ' a > ) -> Self {
66
- Self { parser }
67
- }
68
- }
69
-
70
- impl < ' a > Iterator for Parser < ' a > {
71
- type Item = ( usize , pulldown_cmark:: Event < ' a > ) ;
72
-
73
- fn next ( & mut self ) -> Option < Self :: Item > {
74
- let offset = self . parser . get_offset ( ) ;
75
- self . parser . next ( ) . map ( |event| ( offset, event) )
76
- }
77
- }
78
-
79
61
/// Cleanup documentation decoration (`///` and such).
80
62
///
81
63
/// We can't use `syntax::attr::AttributeMethods::with_desugared_doc` or
@@ -159,30 +141,31 @@ pub fn check_attrs<'a>(cx: &EarlyContext<'_>, valid_idents: &FxHashSet<String>,
159
141
}
160
142
161
143
if !doc. is_empty ( ) {
162
- let parser = Parser :: new ( pulldown_cmark:: Parser :: new ( & doc) ) ;
163
- let parser = parser. coalesce ( |x, y| {
144
+ let parser = pulldown_cmark:: Parser :: new ( & doc) . into_offset_iter ( ) ;
145
+ // Iterate over all `Events` and combine consecutive events into one
146
+ let events = parser. coalesce ( |previous, current| {
164
147
use pulldown_cmark:: Event :: * ;
165
148
166
- let x_offset = x . 0 ;
167
- let y_offset = y . 0 ;
149
+ let previous_range = previous . 1 ;
150
+ let current_range = current . 1 ;
168
151
169
- match ( x . 1 , y . 1 ) {
170
- ( Text ( x ) , Text ( y ) ) => {
171
- let mut x = x . into_owned ( ) ;
172
- x . push_str ( & y ) ;
173
- Ok ( ( x_offset , Text ( x . into ( ) ) ) )
152
+ match ( previous . 0 , current . 0 ) {
153
+ ( Text ( previous ) , Text ( current ) ) => {
154
+ let mut previous = previous . to_string ( ) ;
155
+ previous . push_str ( & current ) ;
156
+ Ok ( ( Text ( previous . into ( ) ) , previous_range ) )
174
157
} ,
175
- ( x , y ) => Err ( ( ( x_offset , x ) , ( y_offset , y ) ) ) ,
158
+ ( previous , current ) => Err ( ( ( previous , previous_range ) , ( current , current_range ) ) ) ,
176
159
}
177
160
} ) ;
178
- check_doc ( cx, valid_idents, parser , & spans) ;
161
+ check_doc ( cx, valid_idents, events , & spans) ;
179
162
}
180
163
}
181
164
182
- fn check_doc < ' a , Events : Iterator < Item = ( usize , pulldown_cmark:: Event < ' a > ) > > (
165
+ fn check_doc < ' a , Events : Iterator < Item = ( pulldown_cmark:: Event < ' a > , Range < usize > ) > > (
183
166
cx : & EarlyContext < ' _ > ,
184
167
valid_idents : & FxHashSet < String > ,
185
- docs : Events ,
168
+ events : Events ,
186
169
spans : & [ ( usize , Span ) ] ,
187
170
) {
188
171
use pulldown_cmark:: Event :: * ;
@@ -191,15 +174,15 @@ fn check_doc<'a, Events: Iterator<Item = (usize, pulldown_cmark::Event<'a>)>>(
191
174
let mut in_code = false ;
192
175
let mut in_link = None ;
193
176
194
- for ( offset , event ) in docs {
177
+ for ( event , range ) in events {
195
178
match event {
196
- Start ( CodeBlock ( _) ) | Start ( Code ) => in_code = true ,
197
- End ( CodeBlock ( _) ) | End ( Code ) => in_code = false ,
198
- Start ( Link ( link , _) ) => in_link = Some ( link ) ,
199
- End ( Link ( _ , _ ) ) => in_link = None ,
179
+ Start ( CodeBlock ( _) ) => in_code = true ,
180
+ End ( CodeBlock ( _) ) => in_code = false ,
181
+ Start ( Link ( _ , url , _) ) => in_link = Some ( url ) ,
182
+ End ( Link ( .. ) ) => in_link = None ,
200
183
Start ( _tag) | End ( _tag) => ( ) , // We don't care about other tags
201
184
Html ( _html) | InlineHtml ( _html) => ( ) , // HTML is weird, just ignore it
202
- SoftBreak | HardBreak => ( ) ,
185
+ SoftBreak | HardBreak | TaskListMarker ( _ ) | Code ( _ ) => ( ) ,
203
186
FootnoteReference ( text) | Text ( text) => {
204
187
if Some ( & text) == in_link. as_ref ( ) {
205
188
// Probably a link of the form `<http://example.com>`
@@ -209,15 +192,15 @@ fn check_doc<'a, Events: Iterator<Item = (usize, pulldown_cmark::Event<'a>)>>(
209
192
}
210
193
211
194
if !in_code {
212
- let index = match spans. binary_search_by ( |c| c. 0 . cmp ( & offset ) ) {
195
+ let index = match spans. binary_search_by ( |c| c. 0 . cmp ( & range . start ) ) {
213
196
Ok ( o) => o,
214
197
Err ( e) => e - 1 ,
215
198
} ;
216
199
217
200
let ( begin, span) = spans[ index] ;
218
201
219
202
// Adjust for the beginning of the current `Event`
220
- let span = span. with_lo ( span. lo ( ) + BytePos :: from_usize ( offset - begin) ) ;
203
+ let span = span. with_lo ( span. lo ( ) + BytePos :: from_usize ( range . start - begin) ) ;
221
204
222
205
check_text ( cx, valid_idents, & text, span) ;
223
206
}
0 commit comments