@@ -420,10 +420,10 @@ impl CodeMap {
420
420
fn lookup_pos ( & self , pos : BytePos ) -> Loc {
421
421
let FileMapAndLine { fm : f, line : a} = self . lookup_line ( pos) ;
422
422
let line = a + 1 u; // Line numbers start at 1
423
- let chpos = self . bytepos_to_charpos ( pos) ;
423
+ let chpos = self . bytepos_to_file_charpos ( pos) ;
424
424
let lines = f. lines . borrow ( ) ;
425
425
let linebpos = lines. get ( ) [ a] ;
426
- let linechpos = self . bytepos_to_charpos ( linebpos) ;
426
+ let linechpos = self . bytepos_to_file_charpos ( linebpos) ;
427
427
debug ! ( "codemap: byte pos {:?} is on the line at byte pos {:?}" ,
428
428
pos, linebpos) ;
429
429
debug ! ( "codemap: char pos {:?} is on the line at char pos {:?}" ,
@@ -446,8 +446,8 @@ impl CodeMap {
446
446
return FileMapAndBytePos { fm : fm, pos : offset} ;
447
447
}
448
448
449
- // Converts an absolute BytePos to a CharPos relative to the codemap .
450
- fn bytepos_to_charpos ( & self , bpos : BytePos ) -> CharPos {
449
+ // Converts an absolute BytePos to a CharPos relative to the filemap .
450
+ fn bytepos_to_file_charpos ( & self , bpos : BytePos ) -> CharPos {
451
451
debug ! ( "codemap: converting {:?} to char pos" , bpos) ;
452
452
let idx = self . lookup_filemap_idx ( bpos) ;
453
453
let files = self . files . borrow ( ) ;
@@ -471,7 +471,8 @@ impl CodeMap {
471
471
}
472
472
}
473
473
474
- CharPos ( bpos. to_uint ( ) - total_extra_bytes)
474
+ assert ! ( map. start_pos. to_uint( ) + total_extra_bytes <= bpos. to_uint( ) ) ;
475
+ CharPos ( bpos. to_uint ( ) - map. start_pos . to_uint ( ) - total_extra_bytes)
475
476
}
476
477
}
477
478
@@ -501,7 +502,7 @@ mod test {
501
502
fm.next_line(BytePos(2));
502
503
}
503
504
504
- fn init_code_map() ->CodeMap {
505
+ fn init_code_map() -> CodeMap {
505
506
let cm = CodeMap::new();
506
507
let fm1 = cm.new_filemap(~" blork. rs",~" first line. \n second line");
507
508
let fm2 = cm.new_filemap(~" empty. rs",~" ");
@@ -532,14 +533,14 @@ mod test {
532
533
533
534
#[test]
534
535
fn t4() {
535
- // Test bytepos_to_charpos
536
+ // Test bytepos_to_file_charpos
536
537
let cm = init_code_map();
537
538
538
- let cp1 = cm.bytepos_to_charpos (BytePos(22));
539
+ let cp1 = cm.bytepos_to_file_charpos (BytePos(22));
539
540
assert_eq!(cp1, CharPos(22));
540
541
541
- let cp2 = cm.bytepos_to_charpos (BytePos(23));
542
- assert_eq!(cp2, CharPos(23 ));
542
+ let cp2 = cm.bytepos_to_file_charpos (BytePos(23));
543
+ assert_eq!(cp2, CharPos(0 ));
543
544
}
544
545
545
546
#[test]
@@ -557,4 +558,45 @@ mod test {
557
558
assert_eq!(loc2.line, 1);
558
559
assert_eq!(loc2.col, CharPos(0));
559
560
}
561
+
562
+ fn init_code_map_mbc() -> CodeMap {
563
+ let cm = CodeMap::new();
564
+ // € is a three byte utf8 char.
565
+ let fm1 = cm.new_filemap(~" blork. rs",~" fir€st €€€€ line. \n second line");
566
+ let fm2 = cm.new_filemap(~" blork2. rs",~" first line€€. \n € second line" ) ;
567
+
568
+ fm1. next_line ( BytePos ( 0 ) ) ;
569
+ fm1. next_line ( BytePos ( 22 ) ) ;
570
+ fm2. next_line ( BytePos ( 39 ) ) ;
571
+ fm2. next_line ( BytePos ( 57 ) ) ;
572
+
573
+ fm1. record_multibyte_char ( BytePos ( 3 ) , 3 ) ;
574
+ fm1. record_multibyte_char ( BytePos ( 9 ) , 3 ) ;
575
+ fm1. record_multibyte_char ( BytePos ( 12 ) , 3 ) ;
576
+ fm1. record_multibyte_char ( BytePos ( 15 ) , 3 ) ;
577
+ fm1. record_multibyte_char ( BytePos ( 18 ) , 3 ) ;
578
+ fm2. record_multibyte_char ( BytePos ( 49 ) , 3 ) ;
579
+ fm2. record_multibyte_char ( BytePos ( 52 ) , 3 ) ;
580
+ fm2. record_multibyte_char ( BytePos ( 57 ) , 3 ) ;
581
+
582
+ cm
583
+ }
584
+
585
+ #[ test]
586
+ fn t6 ( ) {
587
+ // Test bytepos_to_file_charpos in the presence of multi-byte chars
588
+ let cm = init_code_map_mbc ( ) ;
589
+
590
+ let cp1 = cm. bytepos_to_file_charpos ( BytePos ( 3 ) ) ;
591
+ assert_eq ! ( cp1, CharPos ( 3 ) ) ;
592
+
593
+ let cp2 = cm. bytepos_to_file_charpos ( BytePos ( 6 ) ) ;
594
+ assert_eq ! ( cp2, CharPos ( 4 ) ) ;
595
+
596
+ let cp3 = cm. bytepos_to_file_charpos ( BytePos ( 55 ) ) ;
597
+ assert_eq ! ( cp3, CharPos ( 12 ) ) ;
598
+
599
+ let cp4 = cm. bytepos_to_file_charpos ( BytePos ( 60 ) ) ;
600
+ assert_eq ! ( cp4, CharPos ( 15 ) ) ;
601
+ }
560
602
}
0 commit comments