aboutsummaryrefslogtreecommitdiff
path: root/crates/rust-analyzer
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2021-02-12 21:55:27 +0000
committerAleksey Kladov <[email protected]>2021-02-16 16:17:32 +0000
commitc8b9ec8e62d9f560a6557496bc4b579019ccb509 (patch)
treee3fdf968a8fcfb018319c94f524b0cb1b9ba3e67 /crates/rust-analyzer
parent0025836f262ee410050ba79b6ea09d75f76449ac (diff)
Implement utf8 offsets
Diffstat (limited to 'crates/rust-analyzer')
-rw-r--r--crates/rust-analyzer/src/from_proto.rs19
-rw-r--r--crates/rust-analyzer/src/global_state.rs4
-rw-r--r--crates/rust-analyzer/src/line_endings.rs7
-rw-r--r--crates/rust-analyzer/src/lsp_utils.rs5
-rw-r--r--crates/rust-analyzer/src/to_proto.rs25
5 files changed, 45 insertions, 15 deletions
diff --git a/crates/rust-analyzer/src/from_proto.rs b/crates/rust-analyzer/src/from_proto.rs
index c671b5f64..4f3ae8cc3 100644
--- a/crates/rust-analyzer/src/from_proto.rs
+++ b/crates/rust-analyzer/src/from_proto.rs
@@ -1,13 +1,16 @@
1//! Conversion lsp_types types to rust-analyzer specific ones. 1//! Conversion lsp_types types to rust-analyzer specific ones.
2use std::convert::TryFrom; 2use std::convert::TryFrom;
3 3
4use ide::{Annotation, AnnotationKind, AssistKind, LineColUtf16}; 4use ide::{Annotation, AnnotationKind, AssistKind, LineCol, LineColUtf16};
5use ide_db::base_db::{FileId, FilePosition, FileRange}; 5use ide_db::base_db::{FileId, FilePosition, FileRange};
6use syntax::{TextRange, TextSize}; 6use syntax::{TextRange, TextSize};
7use vfs::AbsPathBuf; 7use vfs::AbsPathBuf;
8 8
9use crate::{ 9use crate::{
10 from_json, global_state::GlobalStateSnapshot, line_endings::LineIndex, lsp_ext, Result, 10 from_json,
11 global_state::GlobalStateSnapshot,
12 line_endings::{LineIndex, OffsetEncoding},
13 lsp_ext, Result,
11}; 14};
12 15
13pub(crate) fn abs_path(url: &lsp_types::Url) -> Result<AbsPathBuf> { 16pub(crate) fn abs_path(url: &lsp_types::Url) -> Result<AbsPathBuf> {
@@ -20,8 +23,16 @@ pub(crate) fn vfs_path(url: &lsp_types::Url) -> Result<vfs::VfsPath> {
20} 23}
21 24
22pub(crate) fn offset(line_index: &LineIndex, position: lsp_types::Position) -> TextSize { 25pub(crate) fn offset(line_index: &LineIndex, position: lsp_types::Position) -> TextSize {
23 let line_col = LineColUtf16 { line: position.line as u32, col: position.character as u32 }; 26 let line_col = match line_index.encoding {
24 let line_col = line_index.index.to_utf8(line_col); 27 OffsetEncoding::Utf8 => {
28 LineCol { line: position.line as u32, col: position.character as u32 }
29 }
30 OffsetEncoding::Utf16 => {
31 let line_col =
32 LineColUtf16 { line: position.line as u32, col: position.character as u32 };
33 line_index.index.to_utf8(line_col)
34 }
35 };
25 line_index.index.offset(line_col) 36 line_index.index.offset(line_col)
26} 37}
27 38
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs
index ffef33430..d26e5ef48 100644
--- a/crates/rust-analyzer/src/global_state.rs
+++ b/crates/rust-analyzer/src/global_state.rs
@@ -22,7 +22,7 @@ use crate::{
22 diagnostics::{CheckFixes, DiagnosticCollection}, 22 diagnostics::{CheckFixes, DiagnosticCollection},
23 document::DocumentData, 23 document::DocumentData,
24 from_proto, 24 from_proto,
25 line_endings::{LineEndings, LineIndex}, 25 line_endings::{LineEndings, LineIndex, OffsetEncoding},
26 main_loop::Task, 26 main_loop::Task,
27 op_queue::OpQueue, 27 op_queue::OpQueue,
28 reload::SourceRootConfig, 28 reload::SourceRootConfig,
@@ -274,7 +274,7 @@ impl GlobalStateSnapshot {
274 pub(crate) fn file_line_index(&self, file_id: FileId) -> Cancelable<LineIndex> { 274 pub(crate) fn file_line_index(&self, file_id: FileId) -> Cancelable<LineIndex> {
275 let endings = self.vfs.read().1[&file_id]; 275 let endings = self.vfs.read().1[&file_id];
276 let index = self.analysis.file_line_index(file_id)?; 276 let index = self.analysis.file_line_index(file_id)?;
277 let res = LineIndex { index, endings }; 277 let res = LineIndex { index, endings, encoding: OffsetEncoding::Utf16 };
278 Ok(res) 278 Ok(res)
279 } 279 }
280 280
diff --git a/crates/rust-analyzer/src/line_endings.rs b/crates/rust-analyzer/src/line_endings.rs
index cc152c529..7b6cba43e 100644
--- a/crates/rust-analyzer/src/line_endings.rs
+++ b/crates/rust-analyzer/src/line_endings.rs
@@ -4,9 +4,16 @@
4 4
5use std::sync::Arc; 5use std::sync::Arc;
6 6
7pub(crate) enum OffsetEncoding {
8 #[allow(unused)]
9 Utf8,
10 Utf16,
11}
12
7pub(crate) struct LineIndex { 13pub(crate) struct LineIndex {
8 pub(crate) index: Arc<ide::LineIndex>, 14 pub(crate) index: Arc<ide::LineIndex>,
9 pub(crate) endings: LineEndings, 15 pub(crate) endings: LineEndings,
16 pub(crate) encoding: OffsetEncoding,
10} 17}
11 18
12#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 19#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
diff --git a/crates/rust-analyzer/src/lsp_utils.rs b/crates/rust-analyzer/src/lsp_utils.rs
index 25162185e..6b8e347b9 100644
--- a/crates/rust-analyzer/src/lsp_utils.rs
+++ b/crates/rust-analyzer/src/lsp_utils.rs
@@ -7,7 +7,7 @@ use lsp_server::Notification;
7use crate::{ 7use crate::{
8 from_proto, 8 from_proto,
9 global_state::GlobalState, 9 global_state::GlobalState,
10 line_endings::{LineEndings, LineIndex}, 10 line_endings::{LineEndings, LineIndex, OffsetEncoding},
11}; 11};
12 12
13pub(crate) fn is_canceled(e: &(dyn Error + 'static)) -> bool { 13pub(crate) fn is_canceled(e: &(dyn Error + 'static)) -> bool {
@@ -95,8 +95,9 @@ pub(crate) fn apply_document_changes(
95) { 95) {
96 let mut line_index = LineIndex { 96 let mut line_index = LineIndex {
97 index: Arc::new(ide::LineIndex::new(old_text)), 97 index: Arc::new(ide::LineIndex::new(old_text)),
98 // We don't care about line endings here. 98 // We don't care about line endings or offset encoding here.
99 endings: LineEndings::Unix, 99 endings: LineEndings::Unix,
100 encoding: OffsetEncoding::Utf16,
100 }; 101 };
101 102
102 // The changes we got must be applied sequentially, but can cross lines so we 103 // The changes we got must be applied sequentially, but can cross lines so we
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index 43e29ef04..368d916e7 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -17,14 +17,19 @@ use serde_json::to_value;
17use crate::{ 17use crate::{
18 cargo_target_spec::CargoTargetSpec, 18 cargo_target_spec::CargoTargetSpec,
19 global_state::GlobalStateSnapshot, 19 global_state::GlobalStateSnapshot,
20 line_endings::{LineEndings, LineIndex}, 20 line_endings::{LineEndings, LineIndex, OffsetEncoding},
21 lsp_ext, semantic_tokens, Result, 21 lsp_ext, semantic_tokens, Result,
22}; 22};
23 23
24pub(crate) fn position(line_index: &LineIndex, offset: TextSize) -> lsp_types::Position { 24pub(crate) fn position(line_index: &LineIndex, offset: TextSize) -> lsp_types::Position {
25 let line_col = line_index.index.line_col(offset); 25 let line_col = line_index.index.line_col(offset);
26 let line_col = line_index.index.to_utf16(line_col); 26 match line_index.encoding {
27 lsp_types::Position::new(line_col.line, line_col.col) 27 OffsetEncoding::Utf8 => lsp_types::Position::new(line_col.line, line_col.col),
28 OffsetEncoding::Utf16 => {
29 let line_col = line_index.index.to_utf16(line_col);
30 lsp_types::Position::new(line_col.line, line_col.col)
31 }
32 }
28} 33}
29 34
30pub(crate) fn range(line_index: &LineIndex, range: TextRange) -> lsp_types::Range { 35pub(crate) fn range(line_index: &LineIndex, range: TextRange) -> lsp_types::Range {
@@ -1068,8 +1073,11 @@ mod tests {
1068 }"#; 1073 }"#;
1069 1074
1070 let (offset, text) = test_utils::extract_offset(fixture); 1075 let (offset, text) = test_utils::extract_offset(fixture);
1071 let line_index = 1076 let line_index = LineIndex {
1072 LineIndex { index: Arc::new(ide::LineIndex::new(&text)), endings: LineEndings::Unix }; 1077 index: Arc::new(ide::LineIndex::new(&text)),
1078 endings: LineEndings::Unix,
1079 encoding: OffsetEncoding::Utf16,
1080 };
1073 let (analysis, file_id) = Analysis::from_single_file(text); 1081 let (analysis, file_id) = Analysis::from_single_file(text);
1074 let completions: Vec<(String, Option<String>)> = analysis 1082 let completions: Vec<(String, Option<String>)> = analysis
1075 .completions( 1083 .completions(
@@ -1125,8 +1133,11 @@ fn main() {
1125 let folds = analysis.folding_ranges(file_id).unwrap(); 1133 let folds = analysis.folding_ranges(file_id).unwrap();
1126 assert_eq!(folds.len(), 4); 1134 assert_eq!(folds.len(), 4);
1127 1135
1128 let line_index = 1136 let line_index = LineIndex {
1129 LineIndex { index: Arc::new(ide::LineIndex::new(&text)), endings: LineEndings::Unix }; 1137 index: Arc::new(ide::LineIndex::new(&text)),
1138 endings: LineEndings::Unix,
1139 encoding: OffsetEncoding::Utf16,
1140 };
1130 let converted: Vec<lsp_types::FoldingRange> = 1141 let converted: Vec<lsp_types::FoldingRange> =
1131 folds.into_iter().map(|it| folding_range(&text, &line_index, true, it)).collect(); 1142 folds.into_iter().map(|it| folding_range(&text, &line_index, true, it)).collect();
1132 1143