Skip to content

Commit 31b14c3

Browse files
committed
Cache byte offsets computed from a char index
1 parent 0e15461 commit 31b14c3

File tree

1 file changed

+25
-4
lines changed

1 file changed

+25
-4
lines changed

src/fallback.rs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ use crate::parse::{self, Cursor};
44
use crate::rcvec::{RcVec, RcVecBuilder, RcVecIntoIter, RcVecMut};
55
use crate::{Delimiter, Spacing, TokenTree};
66
#[cfg(all(span_locations, not(fuzzing)))]
7+
use alloc::collections::BTreeMap;
8+
#[cfg(all(span_locations, not(fuzzing)))]
79
use core::cell::RefCell;
810
#[cfg(span_locations)]
911
use core::cmp;
@@ -327,6 +329,7 @@ thread_local! {
327329
source_text: String::new(),
328330
span: Span { lo: 0, hi: 0 },
329331
lines: vec![0],
332+
char_index_to_byte_offset: BTreeMap::new(),
330333
}],
331334
});
332335
}
@@ -336,6 +339,7 @@ struct FileInfo {
336339
source_text: String,
337340
span: Span,
338341
lines: Vec<usize>,
342+
char_index_to_byte_offset: BTreeMap<usize, usize>,
339343
}
340344

341345
#[cfg(all(span_locations, not(fuzzing)))]
@@ -363,11 +367,27 @@ impl FileInfo {
363367
}
364368

365369
fn source_text(&mut self, span: Span) -> String {
366-
let lo = (span.lo - self.span.lo) as usize;
367-
let trunc_lo = match self.source_text.char_indices().nth(lo) {
368-
Some((offset, _ch)) => &self.source_text[offset..],
369-
None => return String::new(),
370+
let lo_char = (span.lo - self.span.lo) as usize;
371+
let (&last_char_index, &last_byte_offset) = self
372+
.char_index_to_byte_offset
373+
.range(..=lo_char)
374+
.next_back()
375+
.unwrap_or((&0, &0));
376+
let lo_byte = if last_char_index == lo_char {
377+
last_byte_offset
378+
} else {
379+
let total_byte_offset = match self.source_text[last_byte_offset..]
380+
.char_indices()
381+
.nth(lo_char - last_char_index)
382+
{
383+
Some((additional_offset, _ch)) => last_byte_offset + additional_offset,
384+
None => self.source_text.len(),
385+
};
386+
self.char_index_to_byte_offset
387+
.insert(lo_char, total_byte_offset);
388+
total_byte_offset
370389
};
390+
let trunc_lo = &self.source_text[lo_byte..];
371391
let char_len = (span.hi - span.lo) as usize;
372392
let source_text = match trunc_lo.char_indices().nth(char_len) {
373393
Some((offset, _ch)) => &trunc_lo[..offset],
@@ -421,6 +441,7 @@ impl SourceMap {
421441
source_text: src.to_owned(),
422442
span,
423443
lines,
444+
char_index_to_byte_offset: BTreeMap::new(),
424445
});
425446

426447
span

0 commit comments

Comments
 (0)