@@ -464,7 +464,7 @@ impl FindUncommented for str {
464
464
return Some ( i - pat. len ( ) ) ;
465
465
}
466
466
Some ( c) => match kind {
467
- FullCodeCharKind :: Normal if b == c => { }
467
+ FullCodeCharKind :: Normal | FullCodeCharKind :: InString if b == c => { }
468
468
_ => {
469
469
needle_iter = pat. chars ( ) ;
470
470
}
@@ -487,7 +487,7 @@ impl FindUncommented for str {
487
487
pub fn find_comment_end ( s : & str ) -> Option < usize > {
488
488
let mut iter = CharClasses :: new ( s. char_indices ( ) ) ;
489
489
for ( kind, ( i, _c) ) in & mut iter {
490
- if kind == FullCodeCharKind :: Normal {
490
+ if kind == FullCodeCharKind :: Normal || kind == FullCodeCharKind :: InString {
491
491
return Some ( i) ;
492
492
}
493
493
}
@@ -505,6 +505,35 @@ pub fn contains_comment(text: &str) -> bool {
505
505
CharClasses :: new ( text. chars ( ) ) . any ( |( kind, _) | kind. is_comment ( ) )
506
506
}
507
507
508
+ /// Remove trailing spaces from the specified snippet. We do not remove spaces
509
+ /// inside strings or comments.
510
+ pub fn remove_trailing_white_spaces ( text : & str ) -> String {
511
+ let mut buffer = String :: with_capacity ( text. len ( ) ) ;
512
+ let mut space_buffer = String :: with_capacity ( 128 ) ;
513
+ for ( char_kind, c) in CharClasses :: new ( text. chars ( ) ) {
514
+ match c {
515
+ '\n' => {
516
+ if char_kind == FullCodeCharKind :: InString {
517
+ buffer. push_str ( & space_buffer) ;
518
+ }
519
+ space_buffer. clear ( ) ;
520
+ buffer. push ( '\n' ) ;
521
+ }
522
+ _ if c. is_whitespace ( ) => {
523
+ space_buffer. push ( c) ;
524
+ }
525
+ _ => {
526
+ if !space_buffer. is_empty ( ) {
527
+ buffer. push_str ( & space_buffer) ;
528
+ space_buffer. clear ( ) ;
529
+ }
530
+ buffer. push ( c) ;
531
+ }
532
+ }
533
+ }
534
+ buffer
535
+ }
536
+
508
537
struct CharClasses < T >
509
538
where
510
539
T : Iterator ,
@@ -568,15 +597,17 @@ enum FullCodeCharKind {
568
597
InComment ,
569
598
/// Last character of a comment, '\n' for a line comment, '/' for a block comment.
570
599
EndComment ,
600
+ /// Inside a string.
601
+ InString ,
571
602
}
572
603
573
604
impl FullCodeCharKind {
574
605
fn is_comment ( & self ) -> bool {
575
606
match * self {
576
- FullCodeCharKind :: Normal => false ,
577
607
FullCodeCharKind :: StartComment |
578
608
FullCodeCharKind :: InComment |
579
609
FullCodeCharKind :: EndComment => true ,
610
+ _ => false ,
580
611
}
581
612
}
582
613
@@ -612,21 +643,34 @@ where
612
643
fn next ( & mut self ) -> Option < ( FullCodeCharKind , T :: Item ) > {
613
644
let item = try_opt ! ( self . base. next( ) ) ;
614
645
let chr = item. get_char ( ) ;
646
+ let mut char_kind = FullCodeCharKind :: Normal ;
615
647
self . status = match self . status {
616
648
CharClassesStatus :: LitString => match chr {
617
649
'"' => CharClassesStatus :: Normal ,
618
- '\\' => CharClassesStatus :: LitStringEscape ,
619
- _ => CharClassesStatus :: LitString ,
650
+ '\\' => {
651
+ char_kind = FullCodeCharKind :: InString ;
652
+ CharClassesStatus :: LitStringEscape
653
+ }
654
+ _ => {
655
+ char_kind = FullCodeCharKind :: InString ;
656
+ CharClassesStatus :: LitString
657
+ }
620
658
} ,
621
- CharClassesStatus :: LitStringEscape => CharClassesStatus :: LitString ,
659
+ CharClassesStatus :: LitStringEscape => {
660
+ char_kind = FullCodeCharKind :: InString ;
661
+ CharClassesStatus :: LitString
662
+ }
622
663
CharClassesStatus :: LitChar => match chr {
623
664
'\\' => CharClassesStatus :: LitCharEscape ,
624
665
'\'' => CharClassesStatus :: Normal ,
625
666
_ => CharClassesStatus :: LitChar ,
626
667
} ,
627
668
CharClassesStatus :: LitCharEscape => CharClassesStatus :: LitChar ,
628
669
CharClassesStatus :: Normal => match chr {
629
- '"' => CharClassesStatus :: LitString ,
670
+ '"' => {
671
+ char_kind = FullCodeCharKind :: InString ;
672
+ CharClassesStatus :: LitString
673
+ }
630
674
'\'' => CharClassesStatus :: LitChar ,
631
675
'/' => match self . base . peek ( ) {
632
676
Some ( next) if next. get_char ( ) == '*' => {
@@ -680,7 +724,7 @@ where
680
724
}
681
725
} ,
682
726
} ;
683
- Some ( ( FullCodeCharKind :: Normal , item) )
727
+ Some ( ( char_kind , item) )
684
728
}
685
729
}
686
730
@@ -707,9 +751,12 @@ impl<'a> Iterator for UngroupedCommentCodeSlices<'a> {
707
751
fn next ( & mut self ) -> Option < Self :: Item > {
708
752
let ( kind, ( start_idx, _) ) = try_opt ! ( self . iter. next( ) ) ;
709
753
match kind {
710
- FullCodeCharKind :: Normal => {
754
+ FullCodeCharKind :: Normal | FullCodeCharKind :: InString => {
711
755
// Consume all the Normal code
712
- while let Some ( & ( FullCodeCharKind :: Normal , ( _, _) ) ) = self . iter . peek ( ) {
756
+ while let Some ( & ( char_kind, _) ) = self . iter . peek ( ) {
757
+ if char_kind. is_comment ( ) {
758
+ break ;
759
+ }
713
760
let _ = self . iter . next ( ) ;
714
761
}
715
762
}
@@ -1032,7 +1079,7 @@ mod test {
1032
1079
fn uncommented ( text : & str ) -> String {
1033
1080
CharClasses :: new ( text. chars ( ) )
1034
1081
. filter_map ( |( s, c) | match s {
1035
- FullCodeCharKind :: Normal => Some ( c) ,
1082
+ FullCodeCharKind :: Normal | FullCodeCharKind :: InString => Some ( c) ,
1036
1083
_ => None ,
1037
1084
} )
1038
1085
. collect ( )
0 commit comments