Auto merge of #16041 - roife:fix-line-index-widechar, r=Veykril

Fix WideChar offsets calculation in `line-index`

Fix #15981. This PR addresses the issue with the WideChar's offset calculation, ensuring accurate line-specific positions during text analysis in the `lib/line-index` module.

## Changes Made

- Corrected the calculation for `WideChar` offsets, ensuring they reflect positions within respective lines.
- Added tests to verify the accuracy of `WideChar` offset calculations, and correct existing tests.
This commit is contained in:
bors 2023-12-07 16:27:31 +00:00
commit 9975650b3e
2 changed files with 30 additions and 3 deletions

View File

@ -363,7 +363,10 @@ fn analyze_source_file_generic(
let c = src[i..].chars().next().unwrap(); let c = src[i..].chars().next().unwrap();
char_len = c.len_utf8(); char_len = c.len_utf8();
let pos = TextSize::from(i as u32) + output_offset; // The last element of `lines` represents the offset of the start of
// current line. To get the offset inside the line, we subtract it.
let pos = TextSize::from(i as u32) + output_offset
- lines.last().unwrap_or(&TextSize::default());
if char_len > 1 { if char_len > 1 {
assert!((2..=4).contains(&char_len)); assert!((2..=4).contains(&char_len));

View File

@ -1,4 +1,4 @@
use crate::{LineIndex, TextSize, WideChar}; use crate::{LineCol, LineIndex, TextSize, WideChar, WideEncoding, WideLineCol};
macro_rules! test { macro_rules! test {
( (
@ -102,7 +102,7 @@ fn $test_name() {
case: multi_byte_with_new_lines, case: multi_byte_with_new_lines,
text: "01\t345\n789abcΔf01234567\u{07}9\nbcΔf", text: "01\t345\n789abcΔf01234567\u{07}9\nbcΔf",
lines: vec![7, 27], lines: vec![7, 27],
multi_byte_chars: vec![(1, (13, 15)), (2, (29, 31))], multi_byte_chars: vec![(1, (6, 8)), (2, (2, 4))],
); );
test!( test!(
@ -118,3 +118,27 @@ fn $test_name() {
lines: vec![16], lines: vec![16],
multi_byte_chars: vec![], multi_byte_chars: vec![],
); );
#[test]
fn test_try_line_col() {
let text = "\n\n\n\n\n宽3456";
assert_eq!(&text[5..8], "");
assert_eq!(&text[11..12], "6");
let line_index = LineIndex::new(text);
let before_6 = TextSize::from(11);
let line_col = line_index.try_line_col(before_6);
assert_eq!(line_col, Some(LineCol { line: 5, col: 6 }));
}
#[test]
fn test_to_wide() {
let text = "\n\n\n\n\n宽3456";
assert_eq!(&text[5..8], "");
assert_eq!(&text[11..12], "6");
let line_index = LineIndex::new(text);
let before_6 = TextSize::from(11);
let line_col = line_index.try_line_col(before_6);
assert_eq!(line_col, Some(LineCol { line: 5, col: 6 }));
let wide_line_col = line_index.to_wide(WideEncoding::Utf16, line_col.unwrap());
assert_eq!(wide_line_col, Some(WideLineCol { line: 5, col: 4 }));
}