@@ -25,6 +25,7 @@ pub use self::ExpnFormat::*;
2525use rustc_data_structures:: fx:: FxHashMap ;
2626use rustc_data_structures:: stable_hasher:: StableHasher ;
2727use std:: cell:: { RefCell , Ref } ;
28+ use std:: cmp;
2829use std:: hash:: Hash ;
2930use std:: path:: { Path , PathBuf } ;
3031use std:: rc:: Rc ;
@@ -607,6 +608,42 @@ impl CodeMap {
607608 self . span_until_char ( sp, '{' )
608609 }
609610
611+ /// Returns a new span representing just the end-point of this span
612+ pub fn end_point ( & self , sp : Span ) -> Span {
613+ let hi = sp. hi ( ) . 0 . checked_sub ( 1 ) . unwrap_or ( sp. hi ( ) . 0 ) ;
614+ let hi = self . get_start_of_char_bytepos ( BytePos ( hi) ) ;
615+ let lo = cmp:: max ( hi. 0 , sp. lo ( ) . 0 ) ;
616+ sp. with_lo ( BytePos ( lo) )
617+ }
618+
619+ /// Returns a new span representing the next character after the end-point of this span
620+ pub fn next_point ( & self , sp : Span ) -> Span {
621+ let hi = sp. lo ( ) . 0 . checked_add ( 1 ) . unwrap_or ( sp. lo ( ) . 0 ) ;
622+ let hi = self . get_start_of_char_bytepos ( BytePos ( hi) ) ;
623+ let lo = cmp:: max ( sp. hi ( ) . 0 , hi. 0 ) ;
624+ Span :: new ( BytePos ( lo) , BytePos ( lo) , sp. ctxt ( ) )
625+ }
626+
627+ fn get_start_of_char_bytepos ( & self , bpos : BytePos ) -> BytePos {
628+ let idx = self . lookup_filemap_idx ( bpos) ;
629+ let files = self . files . borrow ( ) ;
630+ let map = & ( * files) [ idx] ;
631+
632+ for mbc in map. multibyte_chars . borrow ( ) . iter ( ) {
633+ if mbc. pos < bpos {
634+ if bpos. to_usize ( ) >= mbc. pos . to_usize ( ) + mbc. bytes {
635+ // If we do, then return the start of the character.
636+ return mbc. pos ;
637+ }
638+ } else {
639+ break ;
640+ }
641+ }
642+
643+ // If this isn't a multibyte character, return the original position.
644+ return bpos;
645+ }
646+
610647 pub fn get_filemap ( & self , filename : & FileName ) -> Option < Rc < FileMap > > {
611648 for fm in self . files . borrow ( ) . iter ( ) {
612649 if * filename == fm. name {
0 commit comments