mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-22 03:15:44 +00:00
Fix off-by one error in the LineIndex::offset
calculation (#13407)
This commit is contained in:
parent
a8d9104fa3
commit
afdb659111
2 changed files with 55 additions and 5 deletions
|
@ -222,6 +222,57 @@ impl LineIndex {
|
|||
}
|
||||
|
||||
/// Returns the [byte offset](TextSize) at `line` and `column`.
|
||||
///
|
||||
/// ## Examples
|
||||
///
|
||||
/// ### ASCII
|
||||
///
|
||||
/// ```
|
||||
/// use ruff_source_file::{LineIndex, OneIndexed};
|
||||
/// use ruff_text_size::TextSize;
|
||||
/// let source = r#"a = 4
|
||||
/// c = "some string"
|
||||
/// x = b"#;
|
||||
///
|
||||
/// let index = LineIndex::from_source_text(source);
|
||||
///
|
||||
/// // First line, first column
|
||||
/// assert_eq!(index.offset(OneIndexed::from_zero_indexed(0), OneIndexed::from_zero_indexed(0), source), TextSize::new(0));
|
||||
///
|
||||
/// // Second line, 4th column
|
||||
/// assert_eq!(index.offset(OneIndexed::from_zero_indexed(1), OneIndexed::from_zero_indexed(4), source), TextSize::new(10));
|
||||
///
|
||||
/// // Offset past the end of the first line
|
||||
/// assert_eq!(index.offset(OneIndexed::from_zero_indexed(0), OneIndexed::from_zero_indexed(10), source), TextSize::new(6));
|
||||
///
|
||||
/// // Offset past the end of the file
|
||||
/// assert_eq!(index.offset(OneIndexed::from_zero_indexed(3), OneIndexed::from_zero_indexed(0), source), TextSize::new(29));
|
||||
/// ```
|
||||
///
|
||||
/// ### UTF8
|
||||
///
|
||||
/// ```
|
||||
/// use ruff_source_file::{LineIndex, OneIndexed};
|
||||
/// use ruff_text_size::TextSize;
|
||||
/// let source = r#"a = 4
|
||||
/// c = "❤️"
|
||||
/// x = b"#;
|
||||
///
|
||||
/// let index = LineIndex::from_source_text(source);
|
||||
///
|
||||
/// // First line, first column
|
||||
/// assert_eq!(index.offset(OneIndexed::from_zero_indexed(0), OneIndexed::from_zero_indexed(0), source), TextSize::new(0));
|
||||
///
|
||||
/// // Third line, 2nd column, after emoji
|
||||
/// assert_eq!(index.offset(OneIndexed::from_zero_indexed(2), OneIndexed::from_zero_indexed(1), source), TextSize::new(20));
|
||||
///
|
||||
/// // Offset past the end of the second line
|
||||
/// assert_eq!(index.offset(OneIndexed::from_zero_indexed(1), OneIndexed::from_zero_indexed(10), source), TextSize::new(19));
|
||||
///
|
||||
/// // Offset past the end of the file
|
||||
/// assert_eq!(index.offset(OneIndexed::from_zero_indexed(3), OneIndexed::from_zero_indexed(0), source), TextSize::new(24));
|
||||
/// ```
|
||||
///
|
||||
pub fn offset(&self, line: OneIndexed, column: OneIndexed, contents: &str) -> TextSize {
|
||||
// If start-of-line position after last line
|
||||
if line.to_zero_indexed() > self.line_starts().len() {
|
||||
|
@ -233,7 +284,7 @@ impl LineIndex {
|
|||
match self.kind() {
|
||||
IndexKind::Ascii => {
|
||||
line_range.start()
|
||||
+ TextSize::try_from(column.get())
|
||||
+ TextSize::try_from(column.to_zero_indexed())
|
||||
.unwrap_or(line_range.len())
|
||||
.clamp(TextSize::new(0), line_range.len())
|
||||
}
|
||||
|
@ -241,7 +292,7 @@ impl LineIndex {
|
|||
let rest = &contents[line_range];
|
||||
let column_offset: TextSize = rest
|
||||
.chars()
|
||||
.take(column.get())
|
||||
.take(column.to_zero_indexed())
|
||||
.map(ruff_text_size::TextLen::text_len)
|
||||
.sum();
|
||||
line_range.start() + column_offset
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue