diff options
Diffstat (limited to 'crates/server/src/conv.rs')
-rw-r--r-- | crates/server/src/conv.rs | 80 |
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 @@ | |||
1 | use languageserver_types::{ | 1 | use 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 | }; |
5 | use libeditor::{LineIndex, LineCol, Edit, AtomEdit}; | 6 | use libeditor::{LineIndex, LineCol, Edit, AtomEdit}; |
6 | use libsyntax2::{SyntaxKind, TextUnit, TextRange}; | 7 | use libsyntax2::{SyntaxKind, TextUnit, TextRange}; |
7 | use libanalysis::FileId; | 8 | use libanalysis::{FileId, SourceChange, SourceFileEdit, FileSystemEdit}; |
8 | 9 | ||
9 | use { | 10 | use { |
10 | Result, | 11 | Result, |
11 | server_world::ServerWorld, | 12 | server_world::ServerWorld, |
13 | req, | ||
12 | }; | 14 | }; |
13 | 15 | ||
14 | pub trait Conv { | 16 | pub trait Conv { |
@@ -168,6 +170,82 @@ impl<'a> TryConvWith for &'a TextDocumentIdentifier { | |||
168 | } | 170 | } |
169 | } | 171 | } |
170 | 172 | ||
173 | impl<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 | |||
185 | impl 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 | |||
210 | impl 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 | |||
227 | impl 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 | |||
171 | pub fn to_location( | 249 | pub fn to_location( |
172 | file_id: FileId, | 250 | file_id: FileId, |
173 | range: TextRange, | 251 | range: TextRange, |