Skip to content

Commit 418eea1

Browse files
committed
Fix bug with zero-length filemaps and rename bytepos_to_local_charpos to bytepos_to_charpos.
1 parent 93a2ee8 commit 418eea1

File tree

1 file changed

+78
-8
lines changed

1 file changed

+78
-8
lines changed

src/libsyntax/codemap.rs

Lines changed: 78 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,20 @@ impl CodeMap {
380380
a = m;
381381
}
382382
}
383+
// There can be filemaps with length 0. These have the same start_pos as the previous
384+
// filemap, but are not the filemaps we want (because they are length 0, they cannot
385+
// contain what we are looking for). So, rewind until we find a useful filemap.
386+
loop {
387+
let lines = files[a].lines.borrow();
388+
let lines = lines.get();
389+
if lines.len() > 0 {
390+
break;
391+
}
392+
if a == 0 {
393+
fail!("position {} does not resolve to a source location", pos.to_uint());
394+
}
395+
a -= 1;
396+
}
383397
if a >= len {
384398
fail!("position {} does not resolve to a source location", pos.to_uint())
385399
}
@@ -406,10 +420,10 @@ impl CodeMap {
406420
fn lookup_pos(&self, pos: BytePos) -> Loc {
407421
let FileMapAndLine {fm: f, line: a} = self.lookup_line(pos);
408422
let line = a + 1u; // Line numbers start at 1
409-
let chpos = self.bytepos_to_local_charpos(pos);
410-
let mut lines = f.lines.borrow_mut();
423+
let chpos = self.bytepos_to_charpos(pos);
424+
let lines = f.lines.borrow();
411425
let linebpos = lines.get()[a];
412-
let linechpos = self.bytepos_to_local_charpos(linebpos);
426+
let linechpos = self.bytepos_to_charpos(linebpos);
413427
debug!("codemap: byte pos {:?} is on the line at byte pos {:?}",
414428
pos, linebpos);
415429
debug!("codemap: char pos {:?} is on the line at char pos {:?}",
@@ -432,9 +446,8 @@ impl CodeMap {
432446
return FileMapAndBytePos {fm: fm, pos: offset};
433447
}
434448

435-
// Converts an absolute BytePos to a CharPos relative to the file it is
436-
// located in
437-
fn bytepos_to_local_charpos(&self, bpos: BytePos) -> CharPos {
449+
// Converts an absolute BytePos to a CharPos relative to the codemap.
450+
fn bytepos_to_charpos(&self, bpos: BytePos) -> CharPos {
438451
debug!("codemap: converting {:?} to char pos", bpos);
439452
let idx = self.lookup_filemap_idx(bpos);
440453
let files = self.files.borrow();
@@ -450,8 +463,8 @@ impl CodeMap {
450463
total_extra_bytes += mbc.bytes;
451464
// We should never see a byte position in the middle of a
452465
// character
453-
assert!(bpos == mbc.pos
454-
|| bpos.to_uint() >= mbc.pos.to_uint() + mbc.bytes);
466+
assert!(bpos == mbc.pos ||
467+
bpos.to_uint() >= mbc.pos.to_uint() + mbc.bytes);
455468
} else {
456469
break;
457470
}
@@ -486,4 +499,61 @@ mod test {
486499
fm.next_line(BytePos(10));
487500
fm.next_line(BytePos(2));
488501
}
502+
503+
fn init_code_map() ->CodeMap {
504+
let cm = CodeMap::new();
505+
let fm1 = cm.new_filemap(~"blork.rs",~"first line.\nsecond line");
506+
let fm2 = cm.new_filemap(~"empty.rs",~"");
507+
let fm3 = cm.new_filemap(~"blork2.rs",~"first line.\nsecond line");
508+
509+
fm1.next_line(BytePos(0));
510+
fm1.next_line(BytePos(12));
511+
fm2.next_line(BytePos(23));
512+
fm3.next_line(BytePos(23));
513+
fm3.next_line(BytePos(33));
514+
515+
cm
516+
}
517+
518+
#[test]
519+
fn t3() {
520+
// Test lookup_byte_offset
521+
let cm = init_code_map();
522+
523+
let fmabp1 = cm.lookup_byte_offset(BytePos(22));
524+
assert_eq!(fmabp1.fm.name, ~"blork.rs");
525+
assert_eq!(fmabp1.pos, BytePos(22));
526+
527+
let fmabp2 = cm.lookup_byte_offset(BytePos(23));
528+
assert_eq!(fmabp2.fm.name, ~"blork2.rs");
529+
assert_eq!(fmabp2.pos, BytePos(0));
530+
}
531+
532+
#[test]
533+
fn t4() {
534+
// Test bytepos_to_charpos
535+
let cm = init_code_map();
536+
537+
let cp1 = cm.bytepos_to_charpos(BytePos(22));
538+
assert_eq!(cp1, CharPos(22));
539+
540+
let cp2 = cm.bytepos_to_charpos(BytePos(23));
541+
assert_eq!(cp2, CharPos(23));
542+
}
543+
544+
#[test]
545+
fn t5() {
546+
// Test zero-length filemaps.
547+
let cm = init_code_map();
548+
549+
let loc1 = cm.lookup_char_pos(BytePos(22));
550+
assert_eq!(loc1.file.name, ~"blork.rs");
551+
assert_eq!(loc1.line, 2);
552+
assert_eq!(loc1.col, CharPos(10));
553+
554+
let loc2 = cm.lookup_char_pos(BytePos(23));
555+
assert_eq!(loc2.file.name, ~"blork2.rs");
556+
assert_eq!(loc2.line, 1);
557+
assert_eq!(loc2.col, CharPos(0));
558+
}
489559
}

0 commit comments

Comments
 (0)