Skip to content

Commit a8d57a2

Browse files
nrcalexcrichton
authored andcommitted
Fix bytepos_to_file_charpos.
Make bytepos_to_charpos relative to the start of the filemap rather than its previous behaviour which was to be realtive to the start of the codemap, but ignoring multi-byte chars in earlier filemaps. Rename to bytepos_to_file_charpos. Add tests for multi-byte chars.
1 parent 53a3f28 commit a8d57a2

File tree

1 file changed

+52
-10
lines changed

1 file changed

+52
-10
lines changed

src/libsyntax/codemap.rs

+52-10
Original file line numberDiff line numberDiff line change
@@ -420,10 +420,10 @@ impl CodeMap {
420420
fn lookup_pos(&self, pos: BytePos) -> Loc {
421421
let FileMapAndLine {fm: f, line: a} = self.lookup_line(pos);
422422
let line = a + 1u; // Line numbers start at 1
423-
let chpos = self.bytepos_to_charpos(pos);
423+
let chpos = self.bytepos_to_file_charpos(pos);
424424
let lines = f.lines.borrow();
425425
let linebpos = lines.get()[a];
426-
let linechpos = self.bytepos_to_charpos(linebpos);
426+
let linechpos = self.bytepos_to_file_charpos(linebpos);
427427
debug!("codemap: byte pos {:?} is on the line at byte pos {:?}",
428428
pos, linebpos);
429429
debug!("codemap: char pos {:?} is on the line at char pos {:?}",
@@ -446,8 +446,8 @@ impl CodeMap {
446446
return FileMapAndBytePos {fm: fm, pos: offset};
447447
}
448448

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 {
451451
debug!("codemap: converting {:?} to char pos", bpos);
452452
let idx = self.lookup_filemap_idx(bpos);
453453
let files = self.files.borrow();
@@ -471,7 +471,8 @@ impl CodeMap {
471471
}
472472
}
473473

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)
475476
}
476477
}
477478

@@ -501,7 +502,7 @@ mod test {
501502
fm.next_line(BytePos(2));
502503
}
503504
504-
fn init_code_map() ->CodeMap {
505+
fn init_code_map() -> CodeMap {
505506
let cm = CodeMap::new();
506507
let fm1 = cm.new_filemap(~"blork.rs",~"first line.\nsecond line");
507508
let fm2 = cm.new_filemap(~"empty.rs",~"");
@@ -532,14 +533,14 @@ mod test {
532533
533534
#[test]
534535
fn t4() {
535-
// Test bytepos_to_charpos
536+
// Test bytepos_to_file_charpos
536537
let cm = init_code_map();
537538
538-
let cp1 = cm.bytepos_to_charpos(BytePos(22));
539+
let cp1 = cm.bytepos_to_file_charpos(BytePos(22));
539540
assert_eq!(cp1, CharPos(22));
540541
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));
543544
}
544545
545546
#[test]
@@ -557,4 +558,45 @@ mod test {
557558
assert_eq!(loc2.line, 1);
558559
assert_eq!(loc2.col, CharPos(0));
559560
}
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.\nsecond 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+
}
560602
}

0 commit comments

Comments
 (0)