65
65
//! .qux
66
66
//! ```
67
67
68
- use comment:: rewrite_comment;
68
+ use comment:: { rewrite_comment, CharClasses , FullCodeCharKind , RichChar } ;
69
69
use config:: IndentStyle ;
70
70
use expr:: rewrite_call;
71
- use lists:: { extract_post_comment , extract_pre_comment, get_comment_end } ;
71
+ use lists:: extract_pre_comment;
72
72
use macros:: convert_try_mac;
73
73
use rewrite:: { Rewrite , RewriteContext } ;
74
74
use shape:: Shape ;
@@ -275,6 +275,20 @@ impl Chain {
275
275
s. chars ( ) . all ( |c| c == '?' )
276
276
}
277
277
278
+ fn is_post_comment ( s : & str ) -> bool {
279
+ let comment_start_index = s. chars ( ) . position ( |c| c == '/' ) ;
280
+ if comment_start_index. is_none ( ) {
281
+ return false ;
282
+ }
283
+
284
+ let newline_index = s. chars ( ) . position ( |c| c == '\n' ) ;
285
+ if newline_index. is_none ( ) {
286
+ return true ;
287
+ }
288
+
289
+ comment_start_index. unwrap ( ) < newline_index. unwrap ( )
290
+ }
291
+
278
292
fn handle_post_comment (
279
293
post_comment_span : Span ,
280
294
post_comment_snippet : & str ,
@@ -289,25 +303,14 @@ impl Chain {
289
303
// No post comment.
290
304
return ;
291
305
}
292
- // HACK: Treat `?`s as separators.
293
- let trimmed_snippet = post_comment_snippet. trim_matches ( '?' ) ;
294
- let comment_end = get_comment_end ( trimmed_snippet, "?" , "" , false ) ;
295
- let maybe_post_comment = extract_post_comment ( trimmed_snippet, comment_end, "?" )
296
- . and_then ( |comment| {
297
- if comment. is_empty ( ) {
298
- None
299
- } else {
300
- Some ( ( comment, comment_end) )
301
- }
302
- } ) ;
303
-
304
- if let Some ( ( post_comment, comment_end) ) = maybe_post_comment {
306
+ let trimmed_snippet = trim_tries ( post_comment_snippet) ;
307
+ if is_post_comment ( & trimmed_snippet) {
305
308
children. push ( ChainItem :: comment (
306
309
post_comment_span,
307
- post_comment ,
310
+ trimmed_snippet . trim ( ) . to_owned ( ) ,
308
311
CommentPosition :: Back ,
309
312
) ) ;
310
- * prev_span_end = * prev_span_end + BytePos ( comment_end as u32 ) ;
313
+ * prev_span_end = post_comment_span . hi ( ) ;
311
314
}
312
315
}
313
316
@@ -336,9 +339,8 @@ impl Chain {
336
339
// Pre-comment
337
340
if handle_comment {
338
341
let pre_comment_span = mk_sp ( prev_span_end, chain_item. span . lo ( ) ) ;
339
- let pre_comment_snippet = context. snippet ( pre_comment_span) ;
340
- let pre_comment_snippet = pre_comment_snippet. trim ( ) . trim_matches ( '?' ) ;
341
- let ( pre_comment, _) = extract_pre_comment ( pre_comment_snippet) ;
342
+ let pre_comment_snippet = trim_tries ( context. snippet ( pre_comment_span) ) ;
343
+ let ( pre_comment, _) = extract_pre_comment ( & pre_comment_snippet) ;
342
344
match pre_comment {
343
345
Some ( ref comment) if !comment. is_empty ( ) => {
344
346
children. push ( ChainItem :: comment (
@@ -872,3 +874,28 @@ fn is_block_expr(context: &RewriteContext, expr: &ast::Expr, repr: &str) -> bool
872
874
_ => false ,
873
875
}
874
876
}
877
+
878
+ /// Remove try operators (`?`s) that appear in the given string. If removing
879
+ /// them leaves an empty line, remove that line as well unless it is the first
880
+ /// line (we need the first newline for detecting pre/post comment).
881
+ fn trim_tries ( s : & str ) -> String {
882
+ let mut result = String :: with_capacity ( s. len ( ) ) ;
883
+ let mut line_buffer = String :: with_capacity ( s. len ( ) ) ;
884
+ for ( kind, rich_char) in CharClasses :: new ( s. chars ( ) ) {
885
+ match rich_char. get_char ( ) {
886
+ '\n' => {
887
+ if result. is_empty ( ) || !line_buffer. trim ( ) . is_empty ( ) {
888
+ result. push_str ( & line_buffer) ;
889
+ result. push ( '\n' )
890
+ }
891
+ line_buffer. clear ( ) ;
892
+ }
893
+ '?' if kind == FullCodeCharKind :: Normal => continue ,
894
+ c => line_buffer. push ( c) ,
895
+ }
896
+ }
897
+ if !line_buffer. trim ( ) . is_empty ( ) {
898
+ result. push_str ( & line_buffer) ;
899
+ }
900
+ result
901
+ }
0 commit comments