Make WideEncoding non-exhaustive

This commit is contained in:
Ariel Davis 2023-05-05 17:35:20 -07:00
parent 59b4916294
commit 1ad0779a00
4 changed files with 24 additions and 19 deletions

View file

@ -28,16 +28,11 @@ fn test_every_chars() {
let got_lin_col = line_index.line_col(got_offset);
assert_eq!(got_lin_col, lin_col);
for enc in [WideEncoding::Utf16, WideEncoding::Utf32] {
for (enc, col) in [(WideEncoding::Utf16, col_utf16), (WideEncoding::Utf32, col_utf32)] {
let wide_lin_col = line_index.to_wide(enc, lin_col);
let got_lin_col = line_index.to_utf8(enc, wide_lin_col);
assert_eq!(got_lin_col, lin_col);
let want_col = match enc {
WideEncoding::Utf16 => col_utf16,
WideEncoding::Utf32 => col_utf32,
};
assert_eq!(wide_lin_col.col, want_col)
assert_eq!(wide_lin_col.col, col)
}
if c == '\n' {

View file

@ -23,13 +23,14 @@ use crate::semantic_tokens;
pub fn server_capabilities(config: &Config) -> ServerCapabilities {
ServerCapabilities {
position_encoding: Some(match negotiated_encoding(config.caps()) {
PositionEncoding::Utf8 => PositionEncodingKind::UTF8,
position_encoding: match negotiated_encoding(config.caps()) {
PositionEncoding::Utf8 => Some(PositionEncodingKind::UTF8),
PositionEncoding::Wide(wide) => match wide {
WideEncoding::Utf16 => PositionEncodingKind::UTF16,
WideEncoding::Utf32 => PositionEncodingKind::UTF32,
WideEncoding::Utf16 => Some(PositionEncodingKind::UTF16),
WideEncoding::Utf32 => Some(PositionEncodingKind::UTF32),
_ => None,
},
}),
},
text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions {
open_close: Some(true),
change: Some(TextDocumentSyncKind::INCREMENTAL),

View file

@ -3,7 +3,6 @@
use std::collections::HashMap;
use flycheck::{Applicability, DiagnosticLevel, DiagnosticSpan};
use ide_db::line_index::WideEncoding;
use itertools::Itertools;
use stdx::format_to;
use vfs::{AbsPath, AbsPathBuf};
@ -94,17 +93,16 @@ fn position(
};
}
let mut char_offset = 0;
let len_func = match position_encoding {
PositionEncoding::Utf8 => char::len_utf8,
PositionEncoding::Wide(WideEncoding::Utf16) => char::len_utf16,
PositionEncoding::Wide(WideEncoding::Utf32) => |_| 1,
};
for c in line.text.chars() {
char_offset += 1;
if char_offset > column_offset {
break;
}
true_column_offset += len_func(c) - 1;
let len = match position_encoding {
PositionEncoding::Utf8 => c.len_utf8(),
PositionEncoding::Wide(w) => w.measure(&c.to_string()),
};
true_column_offset += len - 1;
}
}

View file

@ -20,6 +20,7 @@ pub struct LineCol {
/// A kind of wide character encoding.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum WideEncoding {
/// UTF-16.
Utf16,
@ -27,6 +28,16 @@ pub enum WideEncoding {
Utf32,
}
impl WideEncoding {
/// Returns the number of units it takes to encode `text` in this encoding.
pub fn measure(&self, text: &str) -> usize {
match self {
WideEncoding::Utf16 => text.encode_utf16().count(),
WideEncoding::Utf32 => text.chars().count(),
}
}
}
/// Line/Column information in legacy encodings.
//
// Deliberately not a generic type and different from `LineCol`.