about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-12-07 16:27:31 +0000
committerbors <bors@rust-lang.org>2023-12-07 16:27:31 +0000
commit9975650b3e834818ffc9a0e653391c5a64f9f9fe (patch)
treea854c4e8c556d9b063801d306413bd51f3c85a4c
parent421a0a4ff4a0619a66aceded8f7040444723c78d (diff)
parenta011b6c84c19357d21cd418f011f4d62b320abf7 (diff)
downloadrust-9975650b3e834818ffc9a0e653391c5a64f9f9fe.tar.gz
rust-9975650b3e834818ffc9a0e653391c5a64f9f9fe.zip
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.
-rw-r--r--lib/line-index/src/lib.rs5
-rw-r--r--lib/line-index/src/tests.rs28
2 files changed, 30 insertions, 3 deletions
diff --git a/lib/line-index/src/lib.rs b/lib/line-index/src/lib.rs
index 03371c9c87a..58f266d67f6 100644
--- a/lib/line-index/src/lib.rs
+++ b/lib/line-index/src/lib.rs
@@ -363,7 +363,10 @@ fn analyze_source_file_generic(
             let c = src[i..].chars().next().unwrap();
             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 {
                 assert!((2..=4).contains(&char_len));
diff --git a/lib/line-index/src/tests.rs b/lib/line-index/src/tests.rs
index 8f3762d1910..981008e346b 100644
--- a/lib/line-index/src/tests.rs
+++ b/lib/line-index/src/tests.rs
@@ -1,4 +1,4 @@
-use crate::{LineIndex, TextSize, WideChar};
+use crate::{LineCol, LineIndex, TextSize, WideChar, WideEncoding, WideLineCol};
 
 macro_rules! test {
     (
@@ -102,7 +102,7 @@ test!(
     case: multi_byte_with_new_lines,
     text: "01\t345\n789abcΔf01234567\u{07}9\nbcΔf",
     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!(
@@ -118,3 +118,27 @@ test!(
     lines: vec![16],
     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 }));
+}