4325: Fix column conversion for supplementary plane characters r=matklad a=lnicola

Fixes https://github.com/rust-analyzer/rust-analyzer/pull/4276#issuecomment-623079855.

Co-authored-by: Laurențiu Nicola <lnicola@dend.ro>
This commit is contained in:
bors[bot] 2020-05-05 18:10:39 +00:00 committed by GitHub
commit a4778ddb7a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -31,9 +31,19 @@ pub(crate) struct Utf16Char {
} }
impl Utf16Char { impl Utf16Char {
/// Returns the length in 8-bit UTF-8 code units.
fn len(&self) -> TextSize { fn len(&self) -> TextSize {
self.end - self.start self.end - self.start
} }
/// Returns the length in 16-bit UTF-16 code units.
fn len_utf16(&self) -> usize {
if self.len() == TextSize::from(4) {
2
} else {
1
}
}
} }
impl LineIndex { impl LineIndex {
@ -110,7 +120,7 @@ impl LineIndex {
if let Some(utf16_chars) = self.utf16_lines.get(&line) { if let Some(utf16_chars) = self.utf16_lines.get(&line) {
for c in utf16_chars { for c in utf16_chars {
if c.end <= col { if c.end <= col {
res -= usize::from(c.len()) - 1; res -= usize::from(c.len()) - c.len_utf16();
} else { } else {
// From here on, all utf16 characters come *after* the character we are mapping, // From here on, all utf16 characters come *after* the character we are mapping,
// so we don't need to take them into account // so we don't need to take them into account
@ -125,7 +135,7 @@ impl LineIndex {
if let Some(utf16_chars) = self.utf16_lines.get(&line) { if let Some(utf16_chars) = self.utf16_lines.get(&line) {
for c in utf16_chars { for c in utf16_chars {
if col > u32::from(c.start) { if col > u32::from(c.start) {
col += u32::from(c.len()) - 1; col += u32::from(c.len()) - c.len_utf16() as u32;
} else { } else {
// From here on, all utf16 characters come *after* the character we are mapping, // From here on, all utf16 characters come *after* the character we are mapping,
// so we don't need to take them into account // so we don't need to take them into account
@ -204,6 +214,9 @@ const C: char = 'メ';
// UTF-16 to UTF-8 // UTF-16 to UTF-8
assert_eq!(col_index.utf16_to_utf8_col(1, 19), TextSize::from(21)); assert_eq!(col_index.utf16_to_utf8_col(1, 19), TextSize::from(21));
let col_index = LineIndex::new("a𐐏b");
assert_eq!(col_index.utf16_to_utf8_col(0, 3), TextSize::from(5));
} }
#[test] #[test]