diff options
| -rw-r--r-- | lib/line-index/src/lib.rs | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/lib/line-index/src/lib.rs b/lib/line-index/src/lib.rs index 214fc215f66..6318cbde50b 100644 --- a/lib/line-index/src/lib.rs +++ b/lib/line-index/src/lib.rs @@ -84,6 +84,8 @@ impl WideChar { #[derive(Debug, Clone, PartialEq, Eq)] pub struct LineIndex { /// Offset the beginning of each line (except the first, which always has offset 0). + /// + /// Invariant: Always non-empty and the last element holds the length of the original text. newlines: Box<[TextSize]>, /// List of non-ASCII characters on each line. line_wide_chars: IntMap<u32, Box<[WideChar]>>, @@ -125,6 +127,8 @@ impl LineIndex { cur_col += c_len; } + newlines.push(TextSize::of(text)); + // Save any wide characters seen in the last line if !wide_chars.is_empty() { line_wide_chars.insert(line, wide_chars.into_boxed_slice()); @@ -143,8 +147,12 @@ impl LineIndex { } /// Transforms the `TextSize` into a `LineCol`, or returns `None` if the `offset` was invalid, - /// e.g. if it points to the middle of a multi-byte character. + /// e.g. if it extends past the end of the text or points to the middle of a multi-byte + /// character. pub fn try_line_col(&self, offset: TextSize) -> Option<LineCol> { + if offset > *self.newlines.last().unwrap() { + return None; + } let line = self.newlines.partition_point(|&it| it <= offset); let start = self.start_offset(line)?; let col = offset - start; |
