From 95209aa3f8e4b149da6adb374611ece76c2b82ca Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 12 Feb 2021 22:09:53 +0300 Subject: Make utf8 default, implement utf16 in terms of it --- crates/ide/src/lib.rs | 2 +- crates/ide_db/src/line_index.rs | 25 ++++++++++++++++++++----- crates/ide_db/src/line_index/tests.rs | 4 ++-- crates/rust-analyzer/src/cli/analysis_bench.rs | 4 ++-- crates/rust-analyzer/src/from_proto.rs | 1 + crates/rust-analyzer/src/to_proto.rs | 1 + 6 files changed, 27 insertions(+), 10 deletions(-) diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index 68756f78a..a2c8db505 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs @@ -95,7 +95,7 @@ pub use ide_db::{ }, call_info::CallInfo, label::Label, - line_index::{LineColUtf16, LineIndex}, + line_index::{LineCol, LineColUtf16, LineIndex}, search::{ReferenceAccess, SearchScope}, source_change::{FileSystemEdit, SourceChange}, symbol_index::Query, diff --git a/crates/ide_db/src/line_index.rs b/crates/ide_db/src/line_index.rs index 490c172e3..8e9d8cca2 100644 --- a/crates/ide_db/src/line_index.rs +++ b/crates/ide_db/src/line_index.rs @@ -22,6 +22,14 @@ pub struct LineColUtf16 { pub col: u32, } +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct LineCol { + /// Zero-based + pub line: u32, + /// Zero-based utf8 offset + pub col: u32, +} + #[derive(Clone, Debug, Hash, PartialEq, Eq)] pub(crate) struct Utf16Char { /// Start offset of a character inside a line, zero-based @@ -88,18 +96,25 @@ impl LineIndex { LineIndex { newlines, utf16_lines } } - pub fn line_col(&self, offset: TextSize) -> LineColUtf16 { + pub fn line_col(&self, offset: TextSize) -> LineCol { let line = partition_point(&self.newlines, |&it| it <= offset) - 1; let line_start_offset = self.newlines[line]; let col = offset - line_start_offset; + LineCol { line: line as u32, col: col.into() } + } + + pub fn offset(&self, line_col: LineCol) -> TextSize { + self.newlines[line_col.line as usize] + TextSize::from(line_col.col) + } - LineColUtf16 { line: line as u32, col: self.utf8_to_utf16_col(line as u32, col) as u32 } + pub fn to_utf16(&self, line_col: LineCol) -> LineColUtf16 { + let col = self.utf8_to_utf16_col(line_col.line, line_col.col.into()); + LineColUtf16 { line: line_col.line, col: col as u32 } } - pub fn offset(&self, line_col: LineColUtf16) -> TextSize { - //FIXME: return Result + pub fn to_utf8(&self, line_col: LineColUtf16) -> LineCol { let col = self.utf16_to_utf8_col(line_col.line, line_col.col); - self.newlines[line_col.line as usize] + col + LineCol { line: line_col.line, col: col.into() } } pub fn lines(&self, range: TextRange) -> impl Iterator + '_ { diff --git a/crates/ide_db/src/line_index/tests.rs b/crates/ide_db/src/line_index/tests.rs index af51d7348..09f3bca62 100644 --- a/crates/ide_db/src/line_index/tests.rs +++ b/crates/ide_db/src/line_index/tests.rs @@ -17,14 +17,14 @@ fn test_line_index() { let index = LineIndex::new(text); for &(offset, line, col) in &table { - assert_eq!(index.line_col(offset.into()), LineColUtf16 { line, col }); + assert_eq!(index.line_col(offset.into()), LineCol { line, col }); } let text = "\nhello\nworld"; let table = [(0, 0, 0), (1, 1, 0), (2, 1, 1), (6, 1, 5), (7, 2, 0)]; let index = LineIndex::new(text); for &(offset, line, col) in &table { - assert_eq!(index.line_col(offset.into()), LineColUtf16 { line, col }); + assert_eq!(index.line_col(offset.into()), LineCol { line, col }); } } diff --git a/crates/rust-analyzer/src/cli/analysis_bench.rs b/crates/rust-analyzer/src/cli/analysis_bench.rs index edf12faa4..877abd12b 100644 --- a/crates/rust-analyzer/src/cli/analysis_bench.rs +++ b/crates/rust-analyzer/src/cli/analysis_bench.rs @@ -5,7 +5,7 @@ use std::{env, path::PathBuf, str::FromStr, sync::Arc, time::Instant}; use anyhow::{bail, format_err, Result}; use hir::PrefixKind; use ide::{ - Analysis, AnalysisHost, Change, CompletionConfig, DiagnosticsConfig, FilePosition, LineColUtf16, + Analysis, AnalysisHost, Change, CompletionConfig, DiagnosticsConfig, FilePosition, LineCol, }; use ide_db::{ base_db::{ @@ -97,7 +97,7 @@ impl BenchCmd { let offset = host .analysis() .file_line_index(file_id)? - .offset(LineColUtf16 { line: pos.line - 1, col: pos.column }); + .offset(LineCol { line: pos.line - 1, col: pos.column }); let file_position = FilePosition { file_id, offset }; if is_completion { diff --git a/crates/rust-analyzer/src/from_proto.rs b/crates/rust-analyzer/src/from_proto.rs index 82e7cfa81..de995412c 100644 --- a/crates/rust-analyzer/src/from_proto.rs +++ b/crates/rust-analyzer/src/from_proto.rs @@ -19,6 +19,7 @@ pub(crate) fn vfs_path(url: &lsp_types::Url) -> Result { pub(crate) fn offset(line_index: &LineIndex, position: lsp_types::Position) -> TextSize { let line_col = LineColUtf16 { line: position.line as u32, col: position.character as u32 }; + let line_col = line_index.to_utf8(line_col); line_index.offset(line_col) } diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 599b5207c..ec5e8aa73 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -22,6 +22,7 @@ use crate::{ pub(crate) fn position(line_index: &LineIndex, offset: TextSize) -> lsp_types::Position { let line_col = line_index.line_col(offset); + let line_col = line_index.to_utf16(line_col); lsp_types::Position::new(line_col.line, line_col.col) } -- cgit v1.2.3