aboutsummaryrefslogtreecommitdiff
path: root/crates/rust-analyzer/src/to_proto.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2021-02-12 21:44:28 +0000
committerAleksey Kladov <[email protected]>2021-02-16 16:17:32 +0000
commit0025836f262ee410050ba79b6ea09d75f76449ac (patch)
tree7559a66efac8a3b988f1e65341d54fca42378721 /crates/rust-analyzer/src/to_proto.rs
parent95209aa3f8e4b149da6adb374611ece76c2b82ca (diff)
Make it easy to add additional context for offset conversion
Diffstat (limited to 'crates/rust-analyzer/src/to_proto.rs')
-rw-r--r--crates/rust-analyzer/src/to_proto.rs78
1 files changed, 35 insertions, 43 deletions
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index ec5e8aa73..43e29ef04 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -7,22 +7,23 @@ use std::{
7use ide::{ 7use ide::{
8 Annotation, AnnotationKind, Assist, AssistKind, CallInfo, CompletionItem, CompletionItemKind, 8 Annotation, AnnotationKind, Assist, AssistKind, CallInfo, CompletionItem, CompletionItemKind,
9 Documentation, FileId, FileRange, FileSystemEdit, Fold, FoldKind, Highlight, HlMod, HlPunct, 9 Documentation, FileId, FileRange, FileSystemEdit, Fold, FoldKind, Highlight, HlMod, HlPunct,
10 HlRange, HlTag, Indel, InlayHint, InlayKind, InsertTextFormat, LineIndex, Markup, 10 HlRange, HlTag, Indel, InlayHint, InlayKind, InsertTextFormat, Markup, NavigationTarget,
11 NavigationTarget, ReferenceAccess, RenameError, Runnable, Severity, SourceChange, TextEdit, 11 ReferenceAccess, RenameError, Runnable, Severity, SourceChange, TextEdit, TextRange, TextSize,
12 TextRange, TextSize,
13}; 12};
14use ide_db::SymbolKind; 13use ide_db::SymbolKind;
15use itertools::Itertools; 14use itertools::Itertools;
16use serde_json::to_value; 15use serde_json::to_value;
17 16
18use crate::{ 17use crate::{
19 cargo_target_spec::CargoTargetSpec, global_state::GlobalStateSnapshot, 18 cargo_target_spec::CargoTargetSpec,
20 line_endings::LineEndings, lsp_ext, semantic_tokens, Result, 19 global_state::GlobalStateSnapshot,
20 line_endings::{LineEndings, LineIndex},
21 lsp_ext, semantic_tokens, Result,
21}; 22};
22 23
23pub(crate) fn position(line_index: &LineIndex, offset: TextSize) -> lsp_types::Position { 24pub(crate) fn position(line_index: &LineIndex, offset: TextSize) -> lsp_types::Position {
24 let line_col = line_index.line_col(offset); 25 let line_col = line_index.index.line_col(offset);
25 let line_col = line_index.to_utf16(line_col); 26 let line_col = line_index.index.to_utf16(line_col);
26 lsp_types::Position::new(line_col.line, line_col.col) 27 lsp_types::Position::new(line_col.line, line_col.col)
27} 28}
28 29
@@ -123,13 +124,9 @@ pub(crate) fn completion_item_kind(
123 } 124 }
124} 125}
125 126
126pub(crate) fn text_edit( 127pub(crate) fn text_edit(line_index: &LineIndex, indel: Indel) -> lsp_types::TextEdit {
127 line_index: &LineIndex,
128 line_endings: LineEndings,
129 indel: Indel,
130) -> lsp_types::TextEdit {
131 let range = range(line_index, indel.delete); 128 let range = range(line_index, indel.delete);
132 let new_text = match line_endings { 129 let new_text = match line_index.endings {
133 LineEndings::Unix => indel.insert, 130 LineEndings::Unix => indel.insert,
134 LineEndings::Dos => indel.insert.replace('\n', "\r\n"), 131 LineEndings::Dos => indel.insert.replace('\n', "\r\n"),
135 }; 132 };
@@ -138,11 +135,10 @@ pub(crate) fn text_edit(
138 135
139pub(crate) fn snippet_text_edit( 136pub(crate) fn snippet_text_edit(
140 line_index: &LineIndex, 137 line_index: &LineIndex,
141 line_endings: LineEndings,
142 is_snippet: bool, 138 is_snippet: bool,
143 indel: Indel, 139 indel: Indel,
144) -> lsp_ext::SnippetTextEdit { 140) -> lsp_ext::SnippetTextEdit {
145 let text_edit = text_edit(line_index, line_endings, indel); 141 let text_edit = text_edit(line_index, indel);
146 let insert_text_format = 142 let insert_text_format =
147 if is_snippet { Some(lsp_types::InsertTextFormat::Snippet) } else { None }; 143 if is_snippet { Some(lsp_types::InsertTextFormat::Snippet) } else { None };
148 lsp_ext::SnippetTextEdit { 144 lsp_ext::SnippetTextEdit {
@@ -154,27 +150,24 @@ pub(crate) fn snippet_text_edit(
154 150
155pub(crate) fn text_edit_vec( 151pub(crate) fn text_edit_vec(
156 line_index: &LineIndex, 152 line_index: &LineIndex,
157 line_endings: LineEndings,
158 text_edit: TextEdit, 153 text_edit: TextEdit,
159) -> Vec<lsp_types::TextEdit> { 154) -> Vec<lsp_types::TextEdit> {
160 text_edit.into_iter().map(|indel| self::text_edit(line_index, line_endings, indel)).collect() 155 text_edit.into_iter().map(|indel| self::text_edit(line_index, indel)).collect()
161} 156}
162 157
163pub(crate) fn snippet_text_edit_vec( 158pub(crate) fn snippet_text_edit_vec(
164 line_index: &LineIndex, 159 line_index: &LineIndex,
165 line_endings: LineEndings,
166 is_snippet: bool, 160 is_snippet: bool,
167 text_edit: TextEdit, 161 text_edit: TextEdit,
168) -> Vec<lsp_ext::SnippetTextEdit> { 162) -> Vec<lsp_ext::SnippetTextEdit> {
169 text_edit 163 text_edit
170 .into_iter() 164 .into_iter()
171 .map(|indel| self::snippet_text_edit(line_index, line_endings, is_snippet, indel)) 165 .map(|indel| self::snippet_text_edit(line_index, is_snippet, indel))
172 .collect() 166 .collect()
173} 167}
174 168
175pub(crate) fn completion_item( 169pub(crate) fn completion_item(
176 line_index: &LineIndex, 170 line_index: &LineIndex,
177 line_endings: LineEndings,
178 completion_item: CompletionItem, 171 completion_item: CompletionItem,
179) -> Vec<lsp_types::CompletionItem> { 172) -> Vec<lsp_types::CompletionItem> {
180 fn set_score(res: &mut lsp_types::CompletionItem, label: &str) { 173 fn set_score(res: &mut lsp_types::CompletionItem, label: &str) {
@@ -191,19 +184,19 @@ pub(crate) fn completion_item(
191 for indel in completion_item.text_edit().iter() { 184 for indel in completion_item.text_edit().iter() {
192 if indel.delete.contains_range(source_range) { 185 if indel.delete.contains_range(source_range) {
193 text_edit = Some(if indel.delete == source_range { 186 text_edit = Some(if indel.delete == source_range {
194 self::text_edit(line_index, line_endings, indel.clone()) 187 self::text_edit(line_index, indel.clone())
195 } else { 188 } else {
196 assert!(source_range.end() == indel.delete.end()); 189 assert!(source_range.end() == indel.delete.end());
197 let range1 = TextRange::new(indel.delete.start(), source_range.start()); 190 let range1 = TextRange::new(indel.delete.start(), source_range.start());
198 let range2 = source_range; 191 let range2 = source_range;
199 let indel1 = Indel::replace(range1, String::new()); 192 let indel1 = Indel::replace(range1, String::new());
200 let indel2 = Indel::replace(range2, indel.insert.clone()); 193 let indel2 = Indel::replace(range2, indel.insert.clone());
201 additional_text_edits.push(self::text_edit(line_index, line_endings, indel1)); 194 additional_text_edits.push(self::text_edit(line_index, indel1));
202 self::text_edit(line_index, line_endings, indel2) 195 self::text_edit(line_index, indel2)
203 }) 196 })
204 } else { 197 } else {
205 assert!(source_range.intersect(indel.delete).is_none()); 198 assert!(source_range.intersect(indel.delete).is_none());
206 let text_edit = self::text_edit(line_index, line_endings, indel.clone()); 199 let text_edit = self::text_edit(line_index, indel.clone());
207 additional_text_edits.push(text_edit); 200 additional_text_edits.push(text_edit);
208 } 201 }
209 } 202 }
@@ -359,7 +352,7 @@ pub(crate) fn semantic_tokens(
359 let token_index = semantic_tokens::type_index(type_); 352 let token_index = semantic_tokens::type_index(type_);
360 let modifier_bitset = mods.0; 353 let modifier_bitset = mods.0;
361 354
362 for mut text_range in line_index.lines(highlight_range.range) { 355 for mut text_range in line_index.index.lines(highlight_range.range) {
363 if text[text_range].ends_with('\n') { 356 if text[text_range].ends_with('\n') {
364 text_range = 357 text_range =
365 TextRange::new(text_range.start(), text_range.end() - TextSize::of('\n')); 358 TextRange::new(text_range.start(), text_range.end() - TextSize::of('\n'));
@@ -566,7 +559,7 @@ pub(crate) fn location(
566 frange: FileRange, 559 frange: FileRange,
567) -> Result<lsp_types::Location> { 560) -> Result<lsp_types::Location> {
568 let url = url(snap, frange.file_id); 561 let url = url(snap, frange.file_id);
569 let line_index = snap.analysis.file_line_index(frange.file_id)?; 562 let line_index = snap.file_line_index(frange.file_id)?;
570 let range = range(&line_index, frange.range); 563 let range = range(&line_index, frange.range);
571 let loc = lsp_types::Location::new(url, range); 564 let loc = lsp_types::Location::new(url, range);
572 Ok(loc) 565 Ok(loc)
@@ -578,7 +571,7 @@ pub(crate) fn location_from_nav(
578 nav: NavigationTarget, 571 nav: NavigationTarget,
579) -> Result<lsp_types::Location> { 572) -> Result<lsp_types::Location> {
580 let url = url(snap, nav.file_id); 573 let url = url(snap, nav.file_id);
581 let line_index = snap.analysis.file_line_index(nav.file_id)?; 574 let line_index = snap.file_line_index(nav.file_id)?;
582 let range = range(&line_index, nav.full_range); 575 let range = range(&line_index, nav.full_range);
583 let loc = lsp_types::Location::new(url, range); 576 let loc = lsp_types::Location::new(url, range);
584 Ok(loc) 577 Ok(loc)
@@ -591,7 +584,7 @@ pub(crate) fn location_link(
591) -> Result<lsp_types::LocationLink> { 584) -> Result<lsp_types::LocationLink> {
592 let origin_selection_range = match src { 585 let origin_selection_range = match src {
593 Some(src) => { 586 Some(src) => {
594 let line_index = snap.analysis.file_line_index(src.file_id)?; 587 let line_index = snap.file_line_index(src.file_id)?;
595 let range = range(&line_index, src.range); 588 let range = range(&line_index, src.range);
596 Some(range) 589 Some(range)
597 } 590 }
@@ -611,7 +604,7 @@ fn location_info(
611 snap: &GlobalStateSnapshot, 604 snap: &GlobalStateSnapshot,
612 target: NavigationTarget, 605 target: NavigationTarget,
613) -> Result<(lsp_types::Url, lsp_types::Range, lsp_types::Range)> { 606) -> Result<(lsp_types::Url, lsp_types::Range, lsp_types::Range)> {
614 let line_index = snap.analysis.file_line_index(target.file_id)?; 607 let line_index = snap.file_line_index(target.file_id)?;
615 608
616 let target_uri = url(snap, target.file_id); 609 let target_uri = url(snap, target.file_id);
617 let target_range = range(&line_index, target.full_range); 610 let target_range = range(&line_index, target.full_range);
@@ -649,12 +642,8 @@ pub(crate) fn snippet_text_document_edit(
649 edit: TextEdit, 642 edit: TextEdit,
650) -> Result<lsp_ext::SnippetTextDocumentEdit> { 643) -> Result<lsp_ext::SnippetTextDocumentEdit> {
651 let text_document = optional_versioned_text_document_identifier(snap, file_id); 644 let text_document = optional_versioned_text_document_identifier(snap, file_id);
652 let line_index = snap.analysis.file_line_index(file_id)?; 645 let line_index = snap.file_line_index(file_id)?;
653 let line_endings = snap.file_line_endings(file_id); 646 let edits = edit.into_iter().map(|it| snippet_text_edit(&line_index, is_snippet, it)).collect();
654 let edits = edit
655 .into_iter()
656 .map(|it| snippet_text_edit(&line_index, line_endings, is_snippet, it))
657 .collect();
658 Ok(lsp_ext::SnippetTextDocumentEdit { text_document, edits }) 647 Ok(lsp_ext::SnippetTextDocumentEdit { text_document, edits })
659} 648}
660 649
@@ -675,9 +664,8 @@ pub(crate) fn snippet_text_document_ops(
675 if !initial_contents.is_empty() { 664 if !initial_contents.is_empty() {
676 let text_document = 665 let text_document =
677 lsp_types::OptionalVersionedTextDocumentIdentifier { uri, version: None }; 666 lsp_types::OptionalVersionedTextDocumentIdentifier { uri, version: None };
678 let range = range(&LineIndex::new(""), TextRange::empty(TextSize::from(0)));
679 let text_edit = lsp_ext::SnippetTextEdit { 667 let text_edit = lsp_ext::SnippetTextEdit {
680 range, 668 range: lsp_types::Range::default(),
681 new_text: initial_contents, 669 new_text: initial_contents,
682 insert_text_format: Some(lsp_types::InsertTextFormat::PlainText), 670 insert_text_format: Some(lsp_types::InsertTextFormat::PlainText),
683 }; 671 };
@@ -868,7 +856,7 @@ pub(crate) fn code_lens(
868) -> Result<lsp_types::CodeLens> { 856) -> Result<lsp_types::CodeLens> {
869 match annotation.kind { 857 match annotation.kind {
870 AnnotationKind::Runnable { debug, runnable: run } => { 858 AnnotationKind::Runnable { debug, runnable: run } => {
871 let line_index = snap.analysis.file_line_index(run.nav.file_id)?; 859 let line_index = snap.file_line_index(run.nav.file_id)?;
872 let annotation_range = range(&line_index, annotation.range); 860 let annotation_range = range(&line_index, annotation.range);
873 861
874 let action = run.action(); 862 let action = run.action();
@@ -884,7 +872,7 @@ pub(crate) fn code_lens(
884 Ok(lsp_types::CodeLens { range: annotation_range, command: Some(command), data: None }) 872 Ok(lsp_types::CodeLens { range: annotation_range, command: Some(command), data: None })
885 } 873 }
886 AnnotationKind::HasImpls { position: file_position, data } => { 874 AnnotationKind::HasImpls { position: file_position, data } => {
887 let line_index = snap.analysis.file_line_index(file_position.file_id)?; 875 let line_index = snap.file_line_index(file_position.file_id)?;
888 let annotation_range = range(&line_index, annotation.range); 876 let annotation_range = range(&line_index, annotation.range);
889 let url = url(snap, file_position.file_id); 877 let url = url(snap, file_position.file_id);
890 878
@@ -927,7 +915,7 @@ pub(crate) fn code_lens(
927 }) 915 })
928 } 916 }
929 AnnotationKind::HasReferences { position: file_position, data } => { 917 AnnotationKind::HasReferences { position: file_position, data } => {
930 let line_index = snap.analysis.file_line_index(file_position.file_id)?; 918 let line_index = snap.file_line_index(file_position.file_id)?;
931 let annotation_range = range(&line_index, annotation.range); 919 let annotation_range = range(&line_index, annotation.range);
932 let url = url(snap, file_position.file_id); 920 let url = url(snap, file_position.file_id);
933 921
@@ -1061,6 +1049,8 @@ pub(crate) fn rename_error(err: RenameError) -> crate::LspError {
1061 1049
1062#[cfg(test)] 1050#[cfg(test)]
1063mod tests { 1051mod tests {
1052 use std::sync::Arc;
1053
1064 use hir::PrefixKind; 1054 use hir::PrefixKind;
1065 use ide::Analysis; 1055 use ide::Analysis;
1066 use ide_db::helpers::{insert_use::InsertUseConfig, SnippetCap}; 1056 use ide_db::helpers::{insert_use::InsertUseConfig, SnippetCap};
@@ -1078,7 +1068,8 @@ mod tests {
1078 }"#; 1068 }"#;
1079 1069
1080 let (offset, text) = test_utils::extract_offset(fixture); 1070 let (offset, text) = test_utils::extract_offset(fixture);
1081 let line_index = LineIndex::new(&text); 1071 let line_index =
1072 LineIndex { index: Arc::new(ide::LineIndex::new(&text)), endings: LineEndings::Unix };
1082 let (analysis, file_id) = Analysis::from_single_file(text); 1073 let (analysis, file_id) = Analysis::from_single_file(text);
1083 let completions: Vec<(String, Option<String>)> = analysis 1074 let completions: Vec<(String, Option<String>)> = analysis
1084 .completions( 1075 .completions(
@@ -1096,7 +1087,7 @@ mod tests {
1096 .unwrap() 1087 .unwrap()
1097 .into_iter() 1088 .into_iter()
1098 .filter(|c| c.label().ends_with("arg")) 1089 .filter(|c| c.label().ends_with("arg"))
1099 .map(|c| completion_item(&line_index, LineEndings::Unix, c)) 1090 .map(|c| completion_item(&line_index, c))
1100 .flat_map(|comps| comps.into_iter().map(|c| (c.label, c.sort_text))) 1091 .flat_map(|comps| comps.into_iter().map(|c| (c.label, c.sort_text)))
1101 .collect(); 1092 .collect();
1102 expect_test::expect![[r#" 1093 expect_test::expect![[r#"
@@ -1134,7 +1125,8 @@ fn main() {
1134 let folds = analysis.folding_ranges(file_id).unwrap(); 1125 let folds = analysis.folding_ranges(file_id).unwrap();
1135 assert_eq!(folds.len(), 4); 1126 assert_eq!(folds.len(), 4);
1136 1127
1137 let line_index = LineIndex::new(&text); 1128 let line_index =
1129 LineIndex { index: Arc::new(ide::LineIndex::new(&text)), endings: LineEndings::Unix };
1138 let converted: Vec<lsp_types::FoldingRange> = 1130 let converted: Vec<lsp_types::FoldingRange> =
1139 folds.into_iter().map(|it| folding_range(&text, &line_index, true, it)).collect(); 1131 folds.into_iter().map(|it| folding_range(&text, &line_index, true, it)).collect();
1140 1132