mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 14:21:24 +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
|
@ -1945,11 +1945,10 @@ fn range_end_only() {
|
||||||
def foo(arg1, arg2,):
|
def foo(arg1, arg2,):
|
||||||
print("Should format this" )
|
print("Should format this" )
|
||||||
|
|
||||||
"#), @r###"
|
"#), @r#"
|
||||||
success: true
|
success: true
|
||||||
exit_code: 0
|
exit_code: 0
|
||||||
----- stdout -----
|
----- stdout -----
|
||||||
|
|
||||||
def foo(
|
def foo(
|
||||||
arg1,
|
arg1,
|
||||||
arg2,
|
arg2,
|
||||||
|
@ -1958,7 +1957,7 @@ def foo(arg1, arg2,):
|
||||||
|
|
||||||
|
|
||||||
----- stderr -----
|
----- stderr -----
|
||||||
"###);
|
"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -222,6 +222,57 @@ impl LineIndex {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the [byte offset](TextSize) at `line` and `column`.
|
/// 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 {
|
pub fn offset(&self, line: OneIndexed, column: OneIndexed, contents: &str) -> TextSize {
|
||||||
// If start-of-line position after last line
|
// If start-of-line position after last line
|
||||||
if line.to_zero_indexed() > self.line_starts().len() {
|
if line.to_zero_indexed() > self.line_starts().len() {
|
||||||
|
@ -233,7 +284,7 @@ impl LineIndex {
|
||||||
match self.kind() {
|
match self.kind() {
|
||||||
IndexKind::Ascii => {
|
IndexKind::Ascii => {
|
||||||
line_range.start()
|
line_range.start()
|
||||||
+ TextSize::try_from(column.get())
|
+ TextSize::try_from(column.to_zero_indexed())
|
||||||
.unwrap_or(line_range.len())
|
.unwrap_or(line_range.len())
|
||||||
.clamp(TextSize::new(0), line_range.len())
|
.clamp(TextSize::new(0), line_range.len())
|
||||||
}
|
}
|
||||||
|
@ -241,7 +292,7 @@ impl LineIndex {
|
||||||
let rest = &contents[line_range];
|
let rest = &contents[line_range];
|
||||||
let column_offset: TextSize = rest
|
let column_offset: TextSize = rest
|
||||||
.chars()
|
.chars()
|
||||||
.take(column.get())
|
.take(column.to_zero_indexed())
|
||||||
.map(ruff_text_size::TextLen::text_len)
|
.map(ruff_text_size::TextLen::text_len)
|
||||||
.sum();
|
.sum();
|
||||||
line_range.start() + column_offset
|
line_range.start() + column_offset
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue