@@ -629,26 +629,41 @@ impl SourceMap {
629
629
}
630
630
631
631
/// Extends the given `Span` to just after the previous occurrence of `pat` when surrounded by
632
- /// whitespace. Returns the same span if no character could be found or if an error occurred
633
- /// while retrieving the code snippet.
634
- pub fn span_extend_to_prev_str ( & self , sp : Span , pat : & str , accept_newlines : bool ) -> Span {
632
+ /// whitespace. Returns None if the pattern could not be found or if an error occurred while
633
+ /// retrieving the code snippet.
634
+ pub fn span_extend_to_prev_str (
635
+ & self ,
636
+ sp : Span ,
637
+ pat : & str ,
638
+ accept_newlines : bool ,
639
+ include_whitespace : bool ,
640
+ ) -> Option < Span > {
635
641
// assure that the pattern is delimited, to avoid the following
636
642
// fn my_fn()
637
643
// ^^^^ returned span without the check
638
644
// ---------- correct span
645
+ let prev_source = self . span_to_prev_source ( sp) . ok ( ) ?;
639
646
for ws in & [ " " , "\t " , "\n " ] {
640
647
let pat = pat. to_owned ( ) + ws;
641
- if let Ok ( prev_source) = self . span_to_prev_source ( sp) {
642
- let prev_source = prev_source. rsplit ( & pat) . next ( ) . unwrap_or ( "" ) . trim_start ( ) ;
643
- if prev_source. is_empty ( ) && sp. lo ( ) . 0 != 0 {
644
- return sp. with_lo ( BytePos ( sp. lo ( ) . 0 - 1 ) ) ;
645
- } else if accept_newlines || !prev_source. contains ( '\n' ) {
646
- return sp. with_lo ( BytePos ( sp. lo ( ) . 0 - prev_source. len ( ) as u32 ) ) ;
648
+ if let Some ( pat_pos) = prev_source. rfind ( & pat) {
649
+ let just_after_pat_pos = pat_pos + pat. len ( ) - 1 ;
650
+ let just_after_pat_plus_ws = if include_whitespace {
651
+ just_after_pat_pos
652
+ + prev_source[ just_after_pat_pos..]
653
+ . find ( |c : char | !c. is_whitespace ( ) )
654
+ . unwrap_or ( 0 )
655
+ } else {
656
+ just_after_pat_pos
657
+ } ;
658
+ let len = prev_source. len ( ) - just_after_pat_plus_ws;
659
+ let prev_source = & prev_source[ just_after_pat_plus_ws..] ;
660
+ if accept_newlines || !prev_source. trim_start ( ) . contains ( '\n' ) {
661
+ return Some ( sp. with_lo ( BytePos ( sp. lo ( ) . 0 - len as u32 ) ) ) ;
647
662
}
648
663
}
649
664
}
650
665
651
- sp
666
+ None
652
667
}
653
668
654
669
/// Returns the source snippet as `String` after the given `Span`.
@@ -927,7 +942,7 @@ impl SourceMap {
927
942
}
928
943
929
944
pub fn generate_fn_name_span ( & self , span : Span ) -> Option < Span > {
930
- let prev_span = self . span_extend_to_prev_str ( span, "fn" , true ) ;
945
+ let prev_span = self . span_extend_to_prev_str ( span, "fn" , true , true ) . unwrap_or ( span ) ;
931
946
if let Ok ( snippet) = self . span_to_snippet ( prev_span) {
932
947
debug ! (
933
948
"generate_fn_name_span: span={:?}, prev_span={:?}, snippet={:?}" ,
@@ -968,8 +983,7 @@ impl SourceMap {
968
983
pub fn generate_local_type_param_snippet ( & self , span : Span ) -> Option < ( Span , String ) > {
969
984
// Try to extend the span to the previous "fn" keyword to retrieve the function
970
985
// signature.
971
- let sugg_span = self . span_extend_to_prev_str ( span, "fn" , false ) ;
972
- if sugg_span != span {
986
+ if let Some ( sugg_span) = self . span_extend_to_prev_str ( span, "fn" , false , true ) {
973
987
if let Ok ( snippet) = self . span_to_snippet ( sugg_span) {
974
988
// Consume the function name.
975
989
let mut offset = snippet
0 commit comments