aboutsummaryrefslogtreecommitdiff
path: root/crates/server/src/conv.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/server/src/conv.rs')
-rw-r--r--crates/server/src/conv.rs80
1 files changed, 79 insertions, 1 deletions
diff --git a/crates/server/src/conv.rs b/crates/server/src/conv.rs
index fc9056914..a59308c3f 100644
--- a/crates/server/src/conv.rs
+++ b/crates/server/src/conv.rs
@@ -1,14 +1,16 @@
1use languageserver_types::{ 1use languageserver_types::{
2 Range, SymbolKind, Position, TextEdit, Location, Url, 2 Range, SymbolKind, Position, TextEdit, Location, Url,
3 TextDocumentIdentifier, VersionedTextDocumentIdentifier, TextDocumentItem, 3 TextDocumentIdentifier, VersionedTextDocumentIdentifier, TextDocumentItem,
4 TextDocumentPositionParams, TextDocumentEdit,
4}; 5};
5use libeditor::{LineIndex, LineCol, Edit, AtomEdit}; 6use libeditor::{LineIndex, LineCol, Edit, AtomEdit};
6use libsyntax2::{SyntaxKind, TextUnit, TextRange}; 7use libsyntax2::{SyntaxKind, TextUnit, TextRange};
7use libanalysis::FileId; 8use libanalysis::{FileId, SourceChange, SourceFileEdit, FileSystemEdit};
8 9
9use { 10use {
10 Result, 11 Result,
11 server_world::ServerWorld, 12 server_world::ServerWorld,
13 req,
12}; 14};
13 15
14pub trait Conv { 16pub trait Conv {
@@ -168,6 +170,82 @@ impl<'a> TryConvWith for &'a TextDocumentIdentifier {
168 } 170 }
169} 171}
170 172
173impl<T: TryConvWith> TryConvWith for Vec<T> {
174 type Ctx = <T as TryConvWith>::Ctx;
175 type Output = Vec<<T as TryConvWith>::Output>;
176 fn try_conv_with(self, ctx: &Self::Ctx) -> Result<Self::Output> {
177 let mut res = Vec::with_capacity(self.len());
178 for item in self {
179 res.push(item.try_conv_with(ctx)?);
180 }
181 Ok(res)
182 }
183}
184
185impl TryConvWith for SourceChange {
186 type Ctx = ServerWorld;
187 type Output = req::SourceChange;
188 fn try_conv_with(self, world: &ServerWorld) -> Result<req::SourceChange> {
189 let cursor_position = match self.cursor_position {
190 None => None,
191 Some(pos) => {
192 let line_index = world.analysis().file_line_index(pos.file_id);
193 Some(TextDocumentPositionParams {
194 text_document: TextDocumentIdentifier::new(pos.file_id.try_conv_with(world)?),
195 position: pos.offset.conv_with(&line_index),
196 })
197 }
198 };
199 let source_file_edits = self.source_file_edits.try_conv_with(world)?;
200 let file_system_edits = self.file_system_edits.try_conv_with(world)?;
201 Ok(req::SourceChange {
202 label: self.label,
203 source_file_edits,
204 file_system_edits,
205 cursor_position,
206 })
207 }
208}
209
210impl TryConvWith for SourceFileEdit {
211 type Ctx = ServerWorld;
212 type Output = TextDocumentEdit;
213 fn try_conv_with(self, world: &ServerWorld) -> Result<TextDocumentEdit> {
214 let text_document = VersionedTextDocumentIdentifier {
215 uri: self.file_id.try_conv_with(world)?,
216 version: None,
217 };
218 let line_index = world.analysis().file_line_index(self.file_id);
219 let edits = self.edits
220 .into_iter()
221 .map_conv_with(&line_index)
222 .collect();
223 Ok(TextDocumentEdit { text_document, edits })
224 }
225}
226
227impl TryConvWith for FileSystemEdit {
228 type Ctx = ServerWorld;
229 type Output = req::FileSystemEdit;
230 fn try_conv_with(self, world: &ServerWorld) -> Result<req::FileSystemEdit> {
231 let res = match self {
232 FileSystemEdit::CreateFile { anchor, path } => {
233 let uri = world.file_id_to_uri(anchor)?;
234 let path = &path.as_str()[3..]; // strip `../` b/c url is weird
235 let uri = uri.join(path)?;
236 req::FileSystemEdit::CreateFile { uri }
237 },
238 FileSystemEdit::MoveFile { file, path } => {
239 let src = world.file_id_to_uri(file)?;
240 let path = &path.as_str()[3..]; // strip `../` b/c url is weird
241 let dst = src.join(path)?;
242 req::FileSystemEdit::MoveFile { src, dst }
243 },
244 };
245 Ok(res)
246 }
247}
248
171pub fn to_location( 249pub fn to_location(
172 file_id: FileId, 250 file_id: FileId,
173 range: TextRange, 251 range: TextRange,