]> git.proxmox.com Git - rustc.git/blame - src/tools/rust-analyzer/crates/rust-analyzer/src/from_proto.rs
New upstream version 1.67.1+dfsg1
[rustc.git] / src / tools / rust-analyzer / crates / rust-analyzer / src / from_proto.rs
CommitLineData
064997fb
FG
1//! Conversion lsp_types types to rust-analyzer specific ones.
2use anyhow::format_err;
3use ide::{Annotation, AnnotationKind, AssistKind, LineCol, LineColUtf16};
4use ide_db::base_db::{FileId, FilePosition, FileRange};
5use syntax::{TextRange, TextSize};
6use vfs::AbsPathBuf;
7
8use crate::{
9 from_json,
10 global_state::GlobalStateSnapshot,
487cf647 11 line_index::{LineIndex, PositionEncoding},
064997fb
FG
12 lsp_ext,
13 lsp_utils::invalid_params_error,
14 Result,
15};
16
17pub(crate) fn abs_path(url: &lsp_types::Url) -> Result<AbsPathBuf> {
18 let path = url.to_file_path().map_err(|()| "url is not a file")?;
19 Ok(AbsPathBuf::try_from(path).unwrap())
20}
21
22pub(crate) fn vfs_path(url: &lsp_types::Url) -> Result<vfs::VfsPath> {
23 abs_path(url).map(vfs::VfsPath::from)
24}
25
26pub(crate) fn offset(line_index: &LineIndex, position: lsp_types::Position) -> Result<TextSize> {
27 let line_col = match line_index.encoding {
487cf647 28 PositionEncoding::Utf8 => {
064997fb
FG
29 LineCol { line: position.line as u32, col: position.character as u32 }
30 }
487cf647 31 PositionEncoding::Utf16 => {
064997fb
FG
32 let line_col =
33 LineColUtf16 { line: position.line as u32, col: position.character as u32 };
34 line_index.index.to_utf8(line_col)
35 }
36 };
37 let text_size =
38 line_index.index.offset(line_col).ok_or_else(|| format_err!("Invalid offset"))?;
39 Ok(text_size)
40}
41
42pub(crate) fn text_range(line_index: &LineIndex, range: lsp_types::Range) -> Result<TextRange> {
43 let start = offset(line_index, range.start)?;
44 let end = offset(line_index, range.end)?;
487cf647
FG
45 match end < start {
46 true => Err(format_err!("Invalid Range").into()),
47 false => Ok(TextRange::new(start, end)),
48 }
064997fb
FG
49}
50
51pub(crate) fn file_id(snap: &GlobalStateSnapshot, url: &lsp_types::Url) -> Result<FileId> {
52 snap.url_to_file_id(url)
53}
54
55pub(crate) fn file_position(
56 snap: &GlobalStateSnapshot,
57 tdpp: lsp_types::TextDocumentPositionParams,
58) -> Result<FilePosition> {
59 let file_id = file_id(snap, &tdpp.text_document.uri)?;
60 let line_index = snap.file_line_index(file_id)?;
61 let offset = offset(&line_index, tdpp.position)?;
62 Ok(FilePosition { file_id, offset })
63}
64
65pub(crate) fn file_range(
66 snap: &GlobalStateSnapshot,
67 text_document_identifier: lsp_types::TextDocumentIdentifier,
68 range: lsp_types::Range,
69) -> Result<FileRange> {
70 let file_id = file_id(snap, &text_document_identifier.uri)?;
71 let line_index = snap.file_line_index(file_id)?;
72 let range = text_range(&line_index, range)?;
73 Ok(FileRange { file_id, range })
74}
75
76pub(crate) fn assist_kind(kind: lsp_types::CodeActionKind) -> Option<AssistKind> {
77 let assist_kind = match &kind {
78 k if k == &lsp_types::CodeActionKind::EMPTY => AssistKind::None,
79 k if k == &lsp_types::CodeActionKind::QUICKFIX => AssistKind::QuickFix,
80 k if k == &lsp_types::CodeActionKind::REFACTOR => AssistKind::Refactor,
81 k if k == &lsp_types::CodeActionKind::REFACTOR_EXTRACT => AssistKind::RefactorExtract,
82 k if k == &lsp_types::CodeActionKind::REFACTOR_INLINE => AssistKind::RefactorInline,
83 k if k == &lsp_types::CodeActionKind::REFACTOR_REWRITE => AssistKind::RefactorRewrite,
84 _ => return None,
85 };
86
87 Some(assist_kind)
88}
89
90pub(crate) fn annotation(
91 snap: &GlobalStateSnapshot,
92 code_lens: lsp_types::CodeLens,
93) -> Result<Annotation> {
94 let data =
95 code_lens.data.ok_or_else(|| invalid_params_error("code lens without data".to_string()))?;
96 let resolve = from_json::<lsp_ext::CodeLensResolveData>("CodeLensResolveData", &data)?;
97
98 match resolve {
99 lsp_ext::CodeLensResolveData::Impls(params) => {
2b03887a
FG
100 let pos @ FilePosition { file_id, .. } =
101 file_position(snap, params.text_document_position_params)?;
064997fb
FG
102 let line_index = snap.file_line_index(file_id)?;
103
104 Ok(Annotation {
105 range: text_range(&line_index, code_lens.range)?,
2b03887a 106 kind: AnnotationKind::HasImpls { pos, data: None },
064997fb
FG
107 })
108 }
109 lsp_ext::CodeLensResolveData::References(params) => {
2b03887a 110 let pos @ FilePosition { file_id, .. } = file_position(snap, params)?;
064997fb
FG
111 let line_index = snap.file_line_index(file_id)?;
112
113 Ok(Annotation {
114 range: text_range(&line_index, code_lens.range)?,
2b03887a 115 kind: AnnotationKind::HasReferences { pos, data: None },
064997fb
FG
116 })
117 }
118 }
119}