1 //! Conversion lsp_types types to rust-analyzer specific ones.
2 use std::convert::TryFrom;
4 use ide::{Annotation, AnnotationKind, AssistKind, LineCol, LineColUtf16};
5 use ide_db::base_db::{FileId, FilePosition, FileRange};
6 use syntax::{TextRange, TextSize};
11 global_state::GlobalStateSnapshot,
12 line_index::{LineIndex, OffsetEncoding},
16 pub(crate) fn abs_path(url: &lsp_types::Url) -> Result<AbsPathBuf> {
17 let path = url.to_file_path().map_err(|()| "url is not a file")?;
18 Ok(AbsPathBuf::try_from(path).unwrap())
21 pub(crate) fn vfs_path(url: &lsp_types::Url) -> Result<vfs::VfsPath> {
22 abs_path(url).map(vfs::VfsPath::from)
25 pub(crate) fn offset(line_index: &LineIndex, position: lsp_types::Position) -> TextSize {
26 let line_col = match line_index.encoding {
27 OffsetEncoding::Utf8 => {
28 LineCol { line: position.line as u32, col: position.character as u32 }
30 OffsetEncoding::Utf16 => {
32 LineColUtf16 { line: position.line as u32, col: position.character as u32 };
33 line_index.index.to_utf8(line_col)
36 line_index.index.offset(line_col)
39 pub(crate) fn text_range(line_index: &LineIndex, range: lsp_types::Range) -> TextRange {
40 let start = offset(line_index, range.start);
41 let end = offset(line_index, range.end);
42 TextRange::new(start, end)
45 pub(crate) fn file_id(world: &GlobalStateSnapshot, url: &lsp_types::Url) -> Result<FileId> {
46 world.url_to_file_id(url)
49 pub(crate) fn file_position(
50 world: &GlobalStateSnapshot,
51 tdpp: lsp_types::TextDocumentPositionParams,
52 ) -> Result<FilePosition> {
53 let file_id = file_id(world, &tdpp.text_document.uri)?;
54 let line_index = world.file_line_index(file_id)?;
55 let offset = offset(&line_index, tdpp.position);
56 Ok(FilePosition { file_id, offset })
59 pub(crate) fn file_range(
60 world: &GlobalStateSnapshot,
61 text_document_identifier: lsp_types::TextDocumentIdentifier,
62 range: lsp_types::Range,
63 ) -> Result<FileRange> {
64 let file_id = file_id(world, &text_document_identifier.uri)?;
65 let line_index = world.file_line_index(file_id)?;
66 let range = text_range(&line_index, range);
67 Ok(FileRange { file_id, range })
70 pub(crate) fn assist_kind(kind: lsp_types::CodeActionKind) -> Option<AssistKind> {
71 let assist_kind = match &kind {
72 k if k == &lsp_types::CodeActionKind::EMPTY => AssistKind::None,
73 k if k == &lsp_types::CodeActionKind::QUICKFIX => AssistKind::QuickFix,
74 k if k == &lsp_types::CodeActionKind::REFACTOR => AssistKind::Refactor,
75 k if k == &lsp_types::CodeActionKind::REFACTOR_EXTRACT => AssistKind::RefactorExtract,
76 k if k == &lsp_types::CodeActionKind::REFACTOR_INLINE => AssistKind::RefactorInline,
77 k if k == &lsp_types::CodeActionKind::REFACTOR_REWRITE => AssistKind::RefactorRewrite,
84 pub(crate) fn annotation(
85 world: &GlobalStateSnapshot,
86 code_lens: lsp_types::CodeLens,
87 ) -> Result<Annotation> {
88 let data = code_lens.data.unwrap();
89 let resolve = from_json::<lsp_ext::CodeLensResolveData>("CodeLensResolveData", data)?;
92 lsp_ext::CodeLensResolveData::Impls(params) => {
94 world.url_to_file_id(¶ms.text_document_position_params.text_document.uri)?;
95 let line_index = world.file_line_index(file_id)?;
98 range: text_range(&line_index, code_lens.range),
99 kind: AnnotationKind::HasImpls {
100 position: file_position(world, params.text_document_position_params)?,
105 lsp_ext::CodeLensResolveData::References(params) => {
106 let file_id = world.url_to_file_id(¶ms.text_document.uri)?;
107 let line_index = world.file_line_index(file_id)?;
110 range: text_range(&line_index, code_lens.range),
111 kind: AnnotationKind::HasReferences {
112 position: file_position(world, params)?,