@@ -380,6 +380,20 @@ impl CodeMap {
380
380
a = m;
381
381
}
382
382
}
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
+ }
383
397
if a >= len {
384
398
fail ! ( "position {} does not resolve to a source location" , pos. to_uint( ) )
385
399
}
@@ -406,10 +420,10 @@ impl CodeMap {
406
420
fn lookup_pos ( & self , pos : BytePos ) -> Loc {
407
421
let FileMapAndLine { fm : f, line : a} = self . lookup_line ( pos) ;
408
422
let line = a + 1 u; // 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 ( ) ;
411
425
let linebpos = lines. get ( ) [ a] ;
412
- let linechpos = self . bytepos_to_local_charpos ( linebpos) ;
426
+ let linechpos = self . bytepos_to_charpos ( linebpos) ;
413
427
debug ! ( "codemap: byte pos {:?} is on the line at byte pos {:?}" ,
414
428
pos, linebpos) ;
415
429
debug ! ( "codemap: char pos {:?} is on the line at char pos {:?}" ,
@@ -432,9 +446,8 @@ impl CodeMap {
432
446
return FileMapAndBytePos { fm : fm, pos : offset} ;
433
447
}
434
448
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 {
438
451
debug ! ( "codemap: converting {:?} to char pos" , bpos) ;
439
452
let idx = self . lookup_filemap_idx ( bpos) ;
440
453
let files = self . files . borrow ( ) ;
@@ -450,8 +463,8 @@ impl CodeMap {
450
463
total_extra_bytes += mbc. bytes ;
451
464
// We should never see a byte position in the middle of a
452
465
// 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) ;
455
468
} else {
456
469
break ;
457
470
}
@@ -486,4 +499,61 @@ mod test {
486
499
fm.next_line(BytePos(10));
487
500
fm.next_line(BytePos(2));
488
501
}
502
+
503
+ fn init_code_map() ->CodeMap {
504
+ let cm = CodeMap::new();
505
+ let fm1 = cm.new_filemap(~" blork. rs",~" first line. \n second line");
506
+ let fm2 = cm.new_filemap(~" empty. rs",~" ");
507
+ let fm3 = cm.new_filemap(~" blork2. rs",~" first line. \n second 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
+ }
489
559
}
0 commit comments