Handle multi-byte chars in SourceCodeLocator (#431)

This commit is contained in:
Charlie Marsh 2022-10-14 14:29:18 -04:00 committed by GitHub
parent 3c15c578a7
commit bbffdd57ff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -121,7 +121,7 @@ pub fn is_unpacking_assignment(stmt: &Stmt) -> bool {
/// Struct used to efficiently slice source code at (row, column) Locations. /// Struct used to efficiently slice source code at (row, column) Locations.
pub struct SourceCodeLocator<'a> { pub struct SourceCodeLocator<'a> {
content: &'a str, content: &'a str,
offsets: Vec<usize>, offsets: Vec<Vec<usize>>,
initialized: bool, initialized: bool,
} }
@ -137,26 +137,32 @@ impl<'a> SourceCodeLocator<'a> {
fn init(&mut self) { fn init(&mut self) {
if !self.initialized { if !self.initialized {
let mut offset = 0; let mut offset = 0;
for i in self.content.lines() { for line in self.content.lines() {
self.offsets.push(offset); let mut newline = 0;
offset += i.len(); let mut line_offsets: Vec<usize> = vec![];
offset += 1; for (i, _char) in line.char_indices() {
line_offsets.push(offset + i);
newline = i + 1;
}
line_offsets.push(offset + newline);
self.offsets.push(line_offsets);
offset += newline + 1;
} }
self.offsets.push(offset); self.offsets.push(vec![offset]);
self.initialized = true; self.initialized = true;
} }
} }
pub fn slice_source_code_at(&mut self, location: &Location) -> &'a str { pub fn slice_source_code_at(&mut self, location: &Location) -> &'a str {
self.init(); self.init();
let offset = self.offsets[location.row() - 1] + location.column() - 1; let offset = self.offsets[location.row() - 1][location.column() - 1];
&self.content[offset..] &self.content[offset..]
} }
pub fn slice_source_code_range(&mut self, range: &Range) -> &'a str { pub fn slice_source_code_range(&mut self, range: &Range) -> &'a str {
self.init(); self.init();
let start = self.offsets[range.location.row() - 1] + range.location.column() - 1; let start = self.offsets[range.location.row() - 1][range.location.column() - 1];
let end = self.offsets[range.end_location.row() - 1] + range.end_location.column() - 1; let end = self.offsets[range.end_location.row() - 1][range.end_location.column() - 1];
&self.content[start..end] &self.content[start..end]
} }
@ -166,12 +172,10 @@ impl<'a> SourceCodeLocator<'a> {
inner: &Range, inner: &Range,
) -> (&'a str, &'a str, &'a str) { ) -> (&'a str, &'a str, &'a str) {
self.init(); self.init();
let outer_start = self.offsets[outer.location.row() - 1] + outer.location.column() - 1; let outer_start = self.offsets[outer.location.row() - 1][outer.location.column() - 1];
let outer_end = let outer_end = self.offsets[outer.end_location.row() - 1][outer.end_location.column() - 1];
self.offsets[outer.end_location.row() - 1] + outer.end_location.column() - 1; let inner_start = self.offsets[inner.location.row() - 1][inner.location.column() - 1];
let inner_start = self.offsets[inner.location.row() - 1] + inner.location.column() - 1; let inner_end = self.offsets[inner.end_location.row() - 1][inner.end_location.column() - 1];
let inner_end =
self.offsets[inner.end_location.row() - 1] + inner.end_location.column() - 1;
( (
&self.content[outer_start..inner_start], &self.content[outer_start..inner_start],
&self.content[inner_start..inner_end], &self.content[inner_start..inner_end],