diff options
Diffstat (limited to 'crates/ra_lsp_server/src')
-rw-r--r-- | crates/ra_lsp_server/src/caps.rs | 20 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/cargo_target_spec.rs | 5 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/conv.rs | 59 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main.rs | 26 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop.rs | 55 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/handlers.rs | 75 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/subscriptions.rs | 4 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/project_model/cargo_workspace.rs | 17 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/project_model/sysroot.rs | 9 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/server_world.rs | 28 |
10 files changed, 72 insertions, 226 deletions
diff --git a/crates/ra_lsp_server/src/caps.rs b/crates/ra_lsp_server/src/caps.rs index 39992788d..2af2b89fe 100644 --- a/crates/ra_lsp_server/src/caps.rs +++ b/crates/ra_lsp_server/src/caps.rs | |||
@@ -7,15 +7,13 @@ use lsp_types::{ | |||
7 | 7 | ||
8 | pub fn server_capabilities() -> ServerCapabilities { | 8 | pub fn server_capabilities() -> ServerCapabilities { |
9 | ServerCapabilities { | 9 | ServerCapabilities { |
10 | text_document_sync: Some(TextDocumentSyncCapability::Options( | 10 | text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions { |
11 | TextDocumentSyncOptions { | 11 | open_close: Some(true), |
12 | open_close: Some(true), | 12 | change: Some(TextDocumentSyncKind::Full), |
13 | change: Some(TextDocumentSyncKind::Full), | 13 | will_save: None, |
14 | will_save: None, | 14 | will_save_wait_until: None, |
15 | will_save_wait_until: None, | 15 | save: None, |
16 | save: None, | 16 | })), |
17 | }, | ||
18 | )), | ||
19 | hover_provider: Some(true), | 17 | hover_provider: Some(true), |
20 | completion_provider: Some(CompletionOptions { | 18 | completion_provider: Some(CompletionOptions { |
21 | resolve_provider: None, | 19 | resolve_provider: None, |
@@ -32,9 +30,7 @@ pub fn server_capabilities() -> ServerCapabilities { | |||
32 | document_symbol_provider: Some(true), | 30 | document_symbol_provider: Some(true), |
33 | workspace_symbol_provider: Some(true), | 31 | workspace_symbol_provider: Some(true), |
34 | code_action_provider: Some(CodeActionProviderCapability::Simple(true)), | 32 | code_action_provider: Some(CodeActionProviderCapability::Simple(true)), |
35 | code_lens_provider: Some(CodeLensOptions { | 33 | code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }), |
36 | resolve_provider: Some(true), | ||
37 | }), | ||
38 | document_formatting_provider: Some(true), | 34 | document_formatting_provider: Some(true), |
39 | document_range_formatting_provider: None, | 35 | document_range_formatting_provider: None, |
40 | document_on_type_formatting_provider: Some(DocumentOnTypeFormattingOptions { | 36 | document_on_type_formatting_provider: Some(DocumentOnTypeFormattingOptions { |
diff --git a/crates/ra_lsp_server/src/cargo_target_spec.rs b/crates/ra_lsp_server/src/cargo_target_spec.rs index db9496bbe..e011eab7c 100644 --- a/crates/ra_lsp_server/src/cargo_target_spec.rs +++ b/crates/ra_lsp_server/src/cargo_target_spec.rs | |||
@@ -64,10 +64,7 @@ impl CargoTargetSpec { | |||
64 | None => return Ok(None), | 64 | None => return Ok(None), |
65 | }; | 65 | }; |
66 | let file_id = world.analysis().crate_root(crate_id)?; | 66 | let file_id = world.analysis().crate_root(crate_id)?; |
67 | let path = world | 67 | let path = world.vfs.read().file2path(ra_vfs::VfsFile(file_id.0.into())); |
68 | .vfs | ||
69 | .read() | ||
70 | .file2path(ra_vfs::VfsFile(file_id.0.into())); | ||
71 | let res = world.workspaces.iter().find_map(|ws| { | 68 | let res = world.workspaces.iter().find_map(|ws| { |
72 | let tgt = ws.cargo.target_by_root(&path)?; | 69 | let tgt = ws.cargo.target_by_root(&path)?; |
73 | let res = CargoTargetSpec { | 70 | let res = CargoTargetSpec { |
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index 981385466..20077a48a 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs | |||
@@ -82,11 +82,8 @@ impl ConvWith for CompletionItem { | |||
82 | fn conv_with(mut self, ctx: &LineIndex) -> ::lsp_types::CompletionItem { | 82 | fn conv_with(mut self, ctx: &LineIndex) -> ::lsp_types::CompletionItem { |
83 | let atom_text_edit = AtomTextEdit::replace(self.source_range(), self.insert_text()); | 83 | let atom_text_edit = AtomTextEdit::replace(self.source_range(), self.insert_text()); |
84 | let text_edit = (&atom_text_edit).conv_with(ctx); | 84 | let text_edit = (&atom_text_edit).conv_with(ctx); |
85 | let additional_text_edits = if let Some(edit) = self.take_text_edit() { | 85 | let additional_text_edits = |
86 | Some(edit.conv_with(ctx)) | 86 | if let Some(edit) = self.take_text_edit() { Some(edit.conv_with(ctx)) } else { None }; |
87 | } else { | ||
88 | None | ||
89 | }; | ||
90 | 87 | ||
91 | let mut res = lsp_types::CompletionItem { | 88 | let mut res = lsp_types::CompletionItem { |
92 | label: self.label().to_string(), | 89 | label: self.label().to_string(), |
@@ -112,10 +109,7 @@ impl ConvWith for Position { | |||
112 | type Output = TextUnit; | 109 | type Output = TextUnit; |
113 | 110 | ||
114 | fn conv_with(self, line_index: &LineIndex) -> TextUnit { | 111 | fn conv_with(self, line_index: &LineIndex) -> TextUnit { |
115 | let line_col = LineCol { | 112 | let line_col = LineCol { line: self.line as u32, col_utf16: self.character as u32 }; |
116 | line: self.line as u32, | ||
117 | col_utf16: self.character as u32, | ||
118 | }; | ||
119 | line_index.offset(line_col) | 113 | line_index.offset(line_col) |
120 | } | 114 | } |
121 | } | 115 | } |
@@ -135,10 +129,7 @@ impl ConvWith for TextRange { | |||
135 | type Output = Range; | 129 | type Output = Range; |
136 | 130 | ||
137 | fn conv_with(self, line_index: &LineIndex) -> Range { | 131 | fn conv_with(self, line_index: &LineIndex) -> Range { |
138 | Range::new( | 132 | Range::new(self.start().conv_with(line_index), self.end().conv_with(line_index)) |
139 | self.start().conv_with(line_index), | ||
140 | self.end().conv_with(line_index), | ||
141 | ) | ||
142 | } | 133 | } |
143 | } | 134 | } |
144 | 135 | ||
@@ -147,10 +138,7 @@ impl ConvWith for Range { | |||
147 | type Output = TextRange; | 138 | type Output = TextRange; |
148 | 139 | ||
149 | fn conv_with(self, line_index: &LineIndex) -> TextRange { | 140 | fn conv_with(self, line_index: &LineIndex) -> TextRange { |
150 | TextRange::from_to( | 141 | TextRange::from_to(self.start.conv_with(line_index), self.end.conv_with(line_index)) |
151 | self.start.conv_with(line_index), | ||
152 | self.end.conv_with(line_index), | ||
153 | ) | ||
154 | } | 142 | } |
155 | } | 143 | } |
156 | 144 | ||
@@ -303,11 +291,7 @@ impl TryConvWith for SourceChange { | |||
303 | changes: None, | 291 | changes: None, |
304 | document_changes: Some(DocumentChanges::Operations(document_changes)), | 292 | document_changes: Some(DocumentChanges::Operations(document_changes)), |
305 | }; | 293 | }; |
306 | Ok(req::SourceChange { | 294 | Ok(req::SourceChange { label: self.label, workspace_edit, cursor_position }) |
307 | label: self.label, | ||
308 | workspace_edit, | ||
309 | cursor_position, | ||
310 | }) | ||
311 | } | 295 | } |
312 | } | 296 | } |
313 | 297 | ||
@@ -320,16 +304,8 @@ impl TryConvWith for SourceFileEdit { | |||
320 | version: None, | 304 | version: None, |
321 | }; | 305 | }; |
322 | let line_index = world.analysis().file_line_index(self.file_id); | 306 | let line_index = world.analysis().file_line_index(self.file_id); |
323 | let edits = self | 307 | let edits = self.edit.as_atoms().iter().map_conv_with(&line_index).collect(); |
324 | .edit | 308 | Ok(TextDocumentEdit { text_document, edits }) |
325 | .as_atoms() | ||
326 | .iter() | ||
327 | .map_conv_with(&line_index) | ||
328 | .collect(); | ||
329 | Ok(TextDocumentEdit { | ||
330 | text_document, | ||
331 | edits, | ||
332 | }) | ||
333 | } | 309 | } |
334 | } | 310 | } |
335 | 311 | ||
@@ -342,18 +318,10 @@ impl TryConvWith for FileSystemEdit { | |||
342 | let uri = world.path_to_uri(source_root, &path)?; | 318 | let uri = world.path_to_uri(source_root, &path)?; |
343 | ResourceOp::Create(CreateFile { uri, options: None }) | 319 | ResourceOp::Create(CreateFile { uri, options: None }) |
344 | } | 320 | } |
345 | FileSystemEdit::MoveFile { | 321 | FileSystemEdit::MoveFile { src, dst_source_root, dst_path } => { |
346 | src, | ||
347 | dst_source_root, | ||
348 | dst_path, | ||
349 | } => { | ||
350 | let old_uri = world.file_id_to_uri(src)?; | 322 | let old_uri = world.file_id_to_uri(src)?; |
351 | let new_uri = world.path_to_uri(dst_source_root, &dst_path)?; | 323 | let new_uri = world.path_to_uri(dst_source_root, &dst_path)?; |
352 | ResourceOp::Rename(RenameFile { | 324 | ResourceOp::Rename(RenameFile { old_uri, new_uri, options: None }) |
353 | old_uri, | ||
354 | new_uri, | ||
355 | options: None, | ||
356 | }) | ||
357 | } | 325 | } |
358 | }; | 326 | }; |
359 | Ok(res) | 327 | Ok(res) |
@@ -381,11 +349,8 @@ pub fn to_location_link( | |||
381 | 349 | ||
382 | let target_range = target.info.full_range().conv_with(&tgt_line_index); | 350 | let target_range = target.info.full_range().conv_with(&tgt_line_index); |
383 | 351 | ||
384 | let target_selection_range = target | 352 | let target_selection_range = |
385 | .info | 353 | target.info.focus_range().map(|it| it.conv_with(&tgt_line_index)).unwrap_or(target_range); |
386 | .focus_range() | ||
387 | .map(|it| it.conv_with(&tgt_line_index)) | ||
388 | .unwrap_or(target_range); | ||
389 | 354 | ||
390 | let res = LocationLink { | 355 | let res = LocationLink { |
391 | origin_selection_range: Some(target.range.conv_with(line_index)), | 356 | origin_selection_range: Some(target.range.conv_with(line_index)), |
diff --git a/crates/ra_lsp_server/src/main.rs b/crates/ra_lsp_server/src/main.rs index 33aa30d70..03f83c7be 100644 --- a/crates/ra_lsp_server/src/main.rs +++ b/crates/ra_lsp_server/src/main.rs | |||
@@ -36,23 +36,15 @@ struct InitializationOptions { | |||
36 | fn main_inner() -> Result<()> { | 36 | fn main_inner() -> Result<()> { |
37 | let (receiver, sender, threads) = stdio_transport(); | 37 | let (receiver, sender, threads) = stdio_transport(); |
38 | let cwd = ::std::env::current_dir()?; | 38 | let cwd = ::std::env::current_dir()?; |
39 | run_server( | 39 | run_server(ra_lsp_server::server_capabilities(), receiver, sender, |params, r, s| { |
40 | ra_lsp_server::server_capabilities(), | 40 | let root = params.root_uri.and_then(|it| it.to_file_path().ok()).unwrap_or(cwd); |
41 | receiver, | 41 | let supports_decorations = params |
42 | sender, | 42 | .initialization_options |
43 | |params, r, s| { | 43 | .and_then(|v| InitializationOptions::deserialize(v).ok()) |
44 | let root = params | 44 | .and_then(|it| it.publish_decorations) |
45 | .root_uri | 45 | == Some(true); |
46 | .and_then(|it| it.to_file_path().ok()) | 46 | ra_lsp_server::main_loop(false, root, supports_decorations, r, s) |
47 | .unwrap_or(cwd); | 47 | })?; |
48 | let supports_decorations = params | ||
49 | .initialization_options | ||
50 | .and_then(|v| InitializationOptions::deserialize(v).ok()) | ||
51 | .and_then(|it| it.publish_decorations) | ||
52 | == Some(true); | ||
53 | ra_lsp_server::main_loop(false, root, supports_decorations, r, s) | ||
54 | }, | ||
55 | )?; | ||
56 | log::info!("shutting down IO..."); | 48 | log::info!("shutting down IO..."); |
57 | threads.join()?; | 49 | threads.join()?; |
58 | log::info!("... IO is down"); | 50 | log::info!("... IO is down"); |
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 26b6fe54a..a51299851 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs | |||
@@ -25,10 +25,7 @@ use crate::{ | |||
25 | }; | 25 | }; |
26 | 26 | ||
27 | #[derive(Debug, Fail)] | 27 | #[derive(Debug, Fail)] |
28 | #[fail( | 28 | #[fail(display = "Language Server request failed with {}. ({})", code, message)] |
29 | display = "Language Server request failed with {}. ({})", | ||
30 | code, message | ||
31 | )] | ||
32 | pub struct LspError { | 29 | pub struct LspError { |
33 | pub code: i32, | 30 | pub code: i32, |
34 | pub message: String, | 31 | pub message: String, |
@@ -69,9 +66,7 @@ pub fn main_loop( | |||
69 | } | 66 | } |
70 | }; | 67 | }; |
71 | ws_worker.shutdown(); | 68 | ws_worker.shutdown(); |
72 | ws_watcher | 69 | ws_watcher.shutdown().map_err(|_| format_err!("ws watcher died"))?; |
73 | .shutdown() | ||
74 | .map_err(|_| format_err!("ws watcher died"))?; | ||
75 | let mut state = ServerWorldState::new(ws_root.clone(), workspaces); | 70 | let mut state = ServerWorldState::new(ws_root.clone(), workspaces); |
76 | 71 | ||
77 | log::info!("server initialized, serving requests"); | 72 | log::info!("server initialized, serving requests"); |
@@ -92,9 +87,7 @@ pub fn main_loop( | |||
92 | ); | 87 | ); |
93 | 88 | ||
94 | log::info!("waiting for tasks to finish..."); | 89 | log::info!("waiting for tasks to finish..."); |
95 | task_receiver | 90 | task_receiver.into_iter().for_each(|task| on_task(task, msg_sender, &mut pending_requests)); |
96 | .into_iter() | ||
97 | .for_each(|task| on_task(task, msg_sender, &mut pending_requests)); | ||
98 | log::info!("...tasks have finished"); | 91 | log::info!("...tasks have finished"); |
99 | log::info!("joining threadpool..."); | 92 | log::info!("joining threadpool..."); |
100 | drop(pool); | 93 | drop(pool); |
@@ -119,9 +112,7 @@ enum Event { | |||
119 | impl fmt::Debug for Event { | 112 | impl fmt::Debug for Event { |
120 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | 113 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
121 | let debug_verbose_not = |not: &RawNotification, f: &mut fmt::Formatter| { | 114 | let debug_verbose_not = |not: &RawNotification, f: &mut fmt::Formatter| { |
122 | f.debug_struct("RawNotification") | 115 | f.debug_struct("RawNotification").field("method", ¬.method).finish() |
123 | .field("method", ¬.method) | ||
124 | .finish() | ||
125 | }; | 116 | }; |
126 | 117 | ||
127 | match self { | 118 | match self { |
@@ -287,13 +278,7 @@ fn on_request( | |||
287 | sender: &Sender<Task>, | 278 | sender: &Sender<Task>, |
288 | req: RawRequest, | 279 | req: RawRequest, |
289 | ) -> Result<Option<RawRequest>> { | 280 | ) -> Result<Option<RawRequest>> { |
290 | let mut pool_dispatcher = PoolDispatcher { | 281 | let mut pool_dispatcher = PoolDispatcher { req: Some(req), res: None, pool, world, sender }; |
291 | req: Some(req), | ||
292 | res: None, | ||
293 | pool, | ||
294 | world, | ||
295 | sender, | ||
296 | }; | ||
297 | let req = pool_dispatcher | 282 | let req = pool_dispatcher |
298 | .on::<req::AnalyzerStatus>(handlers::handle_analyzer_status)? | 283 | .on::<req::AnalyzerStatus>(handlers::handle_analyzer_status)? |
299 | .on::<req::SyntaxTree>(handlers::handle_syntax_tree)? | 284 | .on::<req::SyntaxTree>(handlers::handle_syntax_tree)? |
@@ -362,13 +347,9 @@ fn on_notification( | |||
362 | let not = match not.cast::<req::DidOpenTextDocument>() { | 347 | let not = match not.cast::<req::DidOpenTextDocument>() { |
363 | Ok(params) => { | 348 | Ok(params) => { |
364 | let uri = params.text_document.uri; | 349 | let uri = params.text_document.uri; |
365 | let path = uri | 350 | let path = uri.to_file_path().map_err(|()| format_err!("invalid uri: {}", uri))?; |
366 | .to_file_path() | 351 | if let Some(file_id) = |
367 | .map_err(|()| format_err!("invalid uri: {}", uri))?; | 352 | state.vfs.write().add_file_overlay(&path, params.text_document.text) |
368 | if let Some(file_id) = state | ||
369 | .vfs | ||
370 | .write() | ||
371 | .add_file_overlay(&path, params.text_document.text) | ||
372 | { | 353 | { |
373 | subs.add_sub(FileId(file_id.0.into())); | 354 | subs.add_sub(FileId(file_id.0.into())); |
374 | } | 355 | } |
@@ -379,14 +360,9 @@ fn on_notification( | |||
379 | let not = match not.cast::<req::DidChangeTextDocument>() { | 360 | let not = match not.cast::<req::DidChangeTextDocument>() { |
380 | Ok(mut params) => { | 361 | Ok(mut params) => { |
381 | let uri = params.text_document.uri; | 362 | let uri = params.text_document.uri; |
382 | let path = uri | 363 | let path = uri.to_file_path().map_err(|()| format_err!("invalid uri: {}", uri))?; |
383 | .to_file_path() | 364 | let text = |
384 | .map_err(|()| format_err!("invalid uri: {}", uri))?; | 365 | params.content_changes.pop().ok_or_else(|| format_err!("empty changes"))?.text; |
385 | let text = params | ||
386 | .content_changes | ||
387 | .pop() | ||
388 | .ok_or_else(|| format_err!("empty changes"))? | ||
389 | .text; | ||
390 | state.vfs.write().change_file_overlay(path.as_path(), text); | 366 | state.vfs.write().change_file_overlay(path.as_path(), text); |
391 | return Ok(()); | 367 | return Ok(()); |
392 | } | 368 | } |
@@ -395,16 +371,11 @@ fn on_notification( | |||
395 | let not = match not.cast::<req::DidCloseTextDocument>() { | 371 | let not = match not.cast::<req::DidCloseTextDocument>() { |
396 | Ok(params) => { | 372 | Ok(params) => { |
397 | let uri = params.text_document.uri; | 373 | let uri = params.text_document.uri; |
398 | let path = uri | 374 | let path = uri.to_file_path().map_err(|()| format_err!("invalid uri: {}", uri))?; |
399 | .to_file_path() | ||
400 | .map_err(|()| format_err!("invalid uri: {}", uri))?; | ||
401 | if let Some(file_id) = state.vfs.write().remove_file_overlay(path.as_path()) { | 375 | if let Some(file_id) = state.vfs.write().remove_file_overlay(path.as_path()) { |
402 | subs.remove_sub(FileId(file_id.0.into())); | 376 | subs.remove_sub(FileId(file_id.0.into())); |
403 | } | 377 | } |
404 | let params = req::PublishDiagnosticsParams { | 378 | let params = req::PublishDiagnosticsParams { uri, diagnostics: Vec::new() }; |
405 | uri, | ||
406 | diagnostics: Vec::new(), | ||
407 | }; | ||
408 | let not = RawNotification::new::<req::PublishDiagnostics>(¶ms); | 379 | let not = RawNotification::new::<req::PublishDiagnostics>(¶ms); |
409 | msg_sender.send(RawMessage::Notification(not)).unwrap(); | 380 | msg_sender.send(RawMessage::Notification(not)).unwrap(); |
410 | return Ok(()); | 381 | return Ok(()); |
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index aa55d1255..0cdb39c32 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs | |||
@@ -46,12 +46,7 @@ pub fn handle_extend_selection( | |||
46 | .into_iter() | 46 | .into_iter() |
47 | .map_conv_with(&line_index) | 47 | .map_conv_with(&line_index) |
48 | .map(|range| FileRange { file_id, range }) | 48 | .map(|range| FileRange { file_id, range }) |
49 | .map(|frange| { | 49 | .map(|frange| world.analysis().extend_selection(frange).map(|it| it.conv_with(&line_index))) |
50 | world | ||
51 | .analysis() | ||
52 | .extend_selection(frange) | ||
53 | .map(|it| it.conv_with(&line_index)) | ||
54 | }) | ||
55 | .collect::<Cancelable<Vec<_>>>()?; | 50 | .collect::<Cancelable<Vec<_>>>()?; |
56 | Ok(req::ExtendSelectionResult { selections }) | 51 | Ok(req::ExtendSelectionResult { selections }) |
57 | } | 52 | } |
@@ -67,10 +62,7 @@ pub fn handle_find_matching_brace( | |||
67 | .into_iter() | 62 | .into_iter() |
68 | .map_conv_with(&line_index) | 63 | .map_conv_with(&line_index) |
69 | .map(|offset| { | 64 | .map(|offset| { |
70 | world | 65 | world.analysis().matching_brace(FilePosition { file_id, offset }).unwrap_or(offset) |
71 | .analysis() | ||
72 | .matching_brace(FilePosition { file_id, offset }) | ||
73 | .unwrap_or(offset) | ||
74 | }) | 66 | }) |
75 | .map_conv_with(&line_index) | 67 | .map_conv_with(&line_index) |
76 | .collect(); | 68 | .collect(); |
@@ -171,11 +163,7 @@ pub fn handle_workspace_symbol( | |||
171 | let all_symbols = params.query.contains('#'); | 163 | let all_symbols = params.query.contains('#'); |
172 | let libs = params.query.contains('*'); | 164 | let libs = params.query.contains('*'); |
173 | let query = { | 165 | let query = { |
174 | let query: String = params | 166 | let query: String = params.query.chars().filter(|&c| c != '#' && c != '*').collect(); |
175 | .query | ||
176 | .chars() | ||
177 | .filter(|&c| c != '#' && c != '*') | ||
178 | .collect(); | ||
179 | let mut q = Query::new(query); | 167 | let mut q = Query::new(query); |
180 | if !all_symbols { | 168 | if !all_symbols { |
181 | q.only_types(); | 169 | q.only_types(); |
@@ -367,10 +355,7 @@ pub fn handle_completion( | |||
367 | Some(items) => items, | 355 | Some(items) => items, |
368 | }; | 356 | }; |
369 | let line_index = world.analysis().file_line_index(position.file_id); | 357 | let line_index = world.analysis().file_line_index(position.file_id); |
370 | let items = items | 358 | let items = items.into_iter().map(|item| item.conv_with(&line_index)).collect(); |
371 | .into_iter() | ||
372 | .map(|item| item.conv_with(&line_index)) | ||
373 | .collect(); | ||
374 | 359 | ||
375 | Ok(Some(req::CompletionResponse::Array(items))) | 360 | Ok(Some(req::CompletionResponse::Array(items))) |
376 | } | 361 | } |
@@ -496,9 +481,8 @@ pub fn handle_rename(world: ServerWorld, params: RenameParams) -> Result<Option< | |||
496 | .into()); | 481 | .into()); |
497 | } | 482 | } |
498 | 483 | ||
499 | let optional_change = world | 484 | let optional_change = |
500 | .analysis() | 485 | world.analysis().rename(FilePosition { file_id, offset }, &*params.new_name)?; |
501 | .rename(FilePosition { file_id, offset }, &*params.new_name)?; | ||
502 | let change = match optional_change { | 486 | let change = match optional_change { |
503 | None => return Ok(None), | 487 | None => return Ok(None), |
504 | Some(it) => it, | 488 | Some(it) => it, |
@@ -517,14 +501,10 @@ pub fn handle_references( | |||
517 | let line_index = world.analysis().file_line_index(file_id); | 501 | let line_index = world.analysis().file_line_index(file_id); |
518 | let offset = params.position.conv_with(&line_index); | 502 | let offset = params.position.conv_with(&line_index); |
519 | 503 | ||
520 | let refs = world | 504 | let refs = world.analysis().find_all_refs(FilePosition { file_id, offset })?; |
521 | .analysis() | ||
522 | .find_all_refs(FilePosition { file_id, offset })?; | ||
523 | 505 | ||
524 | Ok(Some( | 506 | Ok(Some( |
525 | refs.into_iter() | 507 | refs.into_iter().filter_map(|r| to_location(r.0, r.1, &world, &line_index).ok()).collect(), |
526 | .filter_map(|r| to_location(r.0, r.1, &world, &line_index).ok()) | ||
527 | .collect(), | ||
528 | )) | 508 | )) |
529 | } | 509 | } |
530 | 510 | ||
@@ -540,9 +520,7 @@ pub fn handle_formatting( | |||
540 | 520 | ||
541 | use std::process; | 521 | use std::process; |
542 | let mut rustfmt = process::Command::new("rustfmt"); | 522 | let mut rustfmt = process::Command::new("rustfmt"); |
543 | rustfmt | 523 | rustfmt.stdin(process::Stdio::piped()).stdout(process::Stdio::piped()); |
544 | .stdin(process::Stdio::piped()) | ||
545 | .stdout(process::Stdio::piped()); | ||
546 | 524 | ||
547 | if let Ok(path) = params.text_document.uri.to_file_path() { | 525 | if let Ok(path) = params.text_document.uri.to_file_path() { |
548 | if let Some(parent) = path.parent() { | 526 | if let Some(parent) = path.parent() { |
@@ -582,10 +560,7 @@ pub fn handle_code_action( | |||
582 | let line_index = world.analysis().file_line_index(file_id); | 560 | let line_index = world.analysis().file_line_index(file_id); |
583 | let range = params.range.conv_with(&line_index); | 561 | let range = params.range.conv_with(&line_index); |
584 | 562 | ||
585 | let assists = world | 563 | let assists = world.analysis().assists(FileRange { file_id, range })?.into_iter(); |
586 | .analysis() | ||
587 | .assists(FileRange { file_id, range })? | ||
588 | .into_iter(); | ||
589 | let fixes = world | 564 | let fixes = world |
590 | .analysis() | 565 | .analysis() |
591 | .diagnostics(file_id)? | 566 | .diagnostics(file_id)? |
@@ -720,18 +695,11 @@ pub fn handle_code_lens_resolve(world: ServerWorld, code_lens: CodeLens) -> Resu | |||
720 | to_value(locations).unwrap(), | 695 | to_value(locations).unwrap(), |
721 | ]), | 696 | ]), |
722 | }; | 697 | }; |
723 | Ok(CodeLens { | 698 | Ok(CodeLens { range: code_lens.range, command: Some(cmd), data: None }) |
724 | range: code_lens.range, | ||
725 | command: Some(cmd), | ||
726 | data: None, | ||
727 | }) | ||
728 | } | 699 | } |
729 | None => Ok(CodeLens { | 700 | None => Ok(CodeLens { |
730 | range: code_lens.range, | 701 | range: code_lens.range, |
731 | command: Some(Command { | 702 | command: Some(Command { title: "Error".into(), ..Default::default() }), |
732 | title: "Error".into(), | ||
733 | ..Default::default() | ||
734 | }), | ||
735 | data: None, | 703 | data: None, |
736 | }), | 704 | }), |
737 | } | 705 | } |
@@ -744,16 +712,11 @@ pub fn handle_document_highlight( | |||
744 | let file_id = params.text_document.try_conv_with(&world)?; | 712 | let file_id = params.text_document.try_conv_with(&world)?; |
745 | let line_index = world.analysis().file_line_index(file_id); | 713 | let line_index = world.analysis().file_line_index(file_id); |
746 | 714 | ||
747 | let refs = world | 715 | let refs = world.analysis().find_all_refs(params.try_conv_with(&world)?)?; |
748 | .analysis() | ||
749 | .find_all_refs(params.try_conv_with(&world)?)?; | ||
750 | 716 | ||
751 | Ok(Some( | 717 | Ok(Some( |
752 | refs.into_iter() | 718 | refs.into_iter() |
753 | .map(|r| DocumentHighlight { | 719 | .map(|r| DocumentHighlight { range: r.1.conv_with(&line_index), kind: None }) |
754 | range: r.1.conv_with(&line_index), | ||
755 | kind: None, | ||
756 | }) | ||
757 | .collect(), | 720 | .collect(), |
758 | )) | 721 | )) |
759 | } | 722 | } |
@@ -785,10 +748,7 @@ pub fn publish_decorations( | |||
785 | file_id: FileId, | 748 | file_id: FileId, |
786 | ) -> Result<req::PublishDecorationsParams> { | 749 | ) -> Result<req::PublishDecorationsParams> { |
787 | let uri = world.file_id_to_uri(file_id)?; | 750 | let uri = world.file_id_to_uri(file_id)?; |
788 | Ok(req::PublishDecorationsParams { | 751 | Ok(req::PublishDecorationsParams { uri, decorations: highlight(&world, file_id)? }) |
789 | uri, | ||
790 | decorations: highlight(&world, file_id)?, | ||
791 | }) | ||
792 | } | 752 | } |
793 | 753 | ||
794 | fn highlight(world: &ServerWorld, file_id: FileId) -> Result<Vec<Decoration>> { | 754 | fn highlight(world: &ServerWorld, file_id: FileId) -> Result<Vec<Decoration>> { |
@@ -797,10 +757,7 @@ fn highlight(world: &ServerWorld, file_id: FileId) -> Result<Vec<Decoration>> { | |||
797 | .analysis() | 757 | .analysis() |
798 | .highlight(file_id)? | 758 | .highlight(file_id)? |
799 | .into_iter() | 759 | .into_iter() |
800 | .map(|h| Decoration { | 760 | .map(|h| Decoration { range: h.range.conv_with(&line_index), tag: h.tag }) |
801 | range: h.range.conv_with(&line_index), | ||
802 | tag: h.tag, | ||
803 | }) | ||
804 | .collect(); | 761 | .collect(); |
805 | Ok(res) | 762 | Ok(res) |
806 | } | 763 | } |
diff --git a/crates/ra_lsp_server/src/main_loop/subscriptions.rs b/crates/ra_lsp_server/src/main_loop/subscriptions.rs index a83e01557..11bd952d9 100644 --- a/crates/ra_lsp_server/src/main_loop/subscriptions.rs +++ b/crates/ra_lsp_server/src/main_loop/subscriptions.rs | |||
@@ -7,9 +7,7 @@ pub struct Subscriptions { | |||
7 | 7 | ||
8 | impl Subscriptions { | 8 | impl Subscriptions { |
9 | pub fn new() -> Subscriptions { | 9 | pub fn new() -> Subscriptions { |
10 | Subscriptions { | 10 | Subscriptions { subs: FxHashSet::default() } |
11 | subs: FxHashSet::default(), | ||
12 | } | ||
13 | } | 11 | } |
14 | pub fn add_sub(&mut self, file_id: FileId) { | 12 | pub fn add_sub(&mut self, file_id: FileId) { |
15 | self.subs.insert(file_id); | 13 | self.subs.insert(file_id); |
diff --git a/crates/ra_lsp_server/src/project_model/cargo_workspace.rs b/crates/ra_lsp_server/src/project_model/cargo_workspace.rs index 8cf99d586..3b76389d2 100644 --- a/crates/ra_lsp_server/src/project_model/cargo_workspace.rs +++ b/crates/ra_lsp_server/src/project_model/cargo_workspace.rs | |||
@@ -118,14 +118,11 @@ impl Target { | |||
118 | impl CargoWorkspace { | 118 | impl CargoWorkspace { |
119 | pub fn from_cargo_metadata(cargo_toml: &Path) -> Result<CargoWorkspace> { | 119 | pub fn from_cargo_metadata(cargo_toml: &Path) -> Result<CargoWorkspace> { |
120 | let mut meta = MetadataCommand::new(); | 120 | let mut meta = MetadataCommand::new(); |
121 | meta.manifest_path(cargo_toml) | 121 | meta.manifest_path(cargo_toml).features(CargoOpt::AllFeatures); |
122 | .features(CargoOpt::AllFeatures); | ||
123 | if let Some(parent) = cargo_toml.parent() { | 122 | if let Some(parent) = cargo_toml.parent() { |
124 | meta.current_dir(parent); | 123 | meta.current_dir(parent); |
125 | } | 124 | } |
126 | let meta = meta | 125 | let meta = meta.exec().map_err(|e| format_err!("cargo metadata failed: {}", e))?; |
127 | .exec() | ||
128 | .map_err(|e| format_err!("cargo metadata failed: {}", e))?; | ||
129 | let mut pkg_by_id = FxHashMap::default(); | 126 | let mut pkg_by_id = FxHashMap::default(); |
130 | let mut packages = Arena::default(); | 127 | let mut packages = Arena::default(); |
131 | let mut targets = Arena::default(); | 128 | let mut targets = Arena::default(); |
@@ -157,10 +154,8 @@ impl CargoWorkspace { | |||
157 | for node in resolve.nodes { | 154 | for node in resolve.nodes { |
158 | let source = pkg_by_id[&node.id]; | 155 | let source = pkg_by_id[&node.id]; |
159 | for dep_node in node.deps { | 156 | for dep_node in node.deps { |
160 | let dep = PackageDependency { | 157 | let dep = |
161 | name: dep_node.name.into(), | 158 | PackageDependency { name: dep_node.name.into(), pkg: pkg_by_id[&dep_node.pkg] }; |
162 | pkg: pkg_by_id[&dep_node.pkg], | ||
163 | }; | ||
164 | packages[source].dependencies.push(dep); | 159 | packages[source].dependencies.push(dep); |
165 | } | 160 | } |
166 | } | 161 | } |
@@ -171,8 +166,6 @@ impl CargoWorkspace { | |||
171 | self.packages.iter().map(|(id, _pkg)| id) | 166 | self.packages.iter().map(|(id, _pkg)| id) |
172 | } | 167 | } |
173 | pub fn target_by_root(&self, root: &Path) -> Option<Target> { | 168 | pub fn target_by_root(&self, root: &Path) -> Option<Target> { |
174 | self.packages() | 169 | self.packages().filter_map(|pkg| pkg.targets(self).find(|it| it.root(self) == root)).next() |
175 | .filter_map(|pkg| pkg.targets(self).find(|it| it.root(self) == root)) | ||
176 | .next() | ||
177 | } | 170 | } |
178 | } | 171 | } |
diff --git a/crates/ra_lsp_server/src/project_model/sysroot.rs b/crates/ra_lsp_server/src/project_model/sysroot.rs index fb4685671..49210ac7a 100644 --- a/crates/ra_lsp_server/src/project_model/sysroot.rs +++ b/crates/ra_lsp_server/src/project_model/sysroot.rs | |||
@@ -53,9 +53,7 @@ impl Sysroot { | |||
53 | ); | 53 | ); |
54 | } | 54 | } |
55 | 55 | ||
56 | let mut sysroot = Sysroot { | 56 | let mut sysroot = Sysroot { crates: Arena::default() }; |
57 | crates: Arena::default(), | ||
58 | }; | ||
59 | for name in SYSROOT_CRATES.trim().lines() { | 57 | for name in SYSROOT_CRATES.trim().lines() { |
60 | let root = src.join(format!("lib{}", name)).join("lib.rs"); | 58 | let root = src.join(format!("lib{}", name)).join("lib.rs"); |
61 | if root.exists() { | 59 | if root.exists() { |
@@ -77,10 +75,7 @@ impl Sysroot { | |||
77 | } | 75 | } |
78 | 76 | ||
79 | fn by_name(&self, name: &str) -> Option<SysrootCrate> { | 77 | fn by_name(&self, name: &str) -> Option<SysrootCrate> { |
80 | self.crates | 78 | self.crates.iter().find(|(_id, data)| data.name == name).map(|(id, _data)| id) |
81 | .iter() | ||
82 | .find(|(_id, data)| data.name == name) | ||
83 | .map(|(id, _data)| id) | ||
84 | } | 79 | } |
85 | } | 80 | } |
86 | 81 | ||
diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs index c2167c5d8..02f2a37a8 100644 --- a/crates/ra_lsp_server/src/server_world.rs +++ b/crates/ra_lsp_server/src/server_world.rs | |||
@@ -80,10 +80,7 @@ impl ServerWorldState { | |||
80 | } | 80 | } |
81 | } | 81 | } |
82 | 82 | ||
83 | let libstd = ws | 83 | let libstd = ws.sysroot.std().and_then(|it| sysroot_crates.get(&it).map(|&it| it)); |
84 | .sysroot | ||
85 | .std() | ||
86 | .and_then(|it| sysroot_crates.get(&it).map(|&it| it)); | ||
87 | 84 | ||
88 | let mut pkg_to_lib_crate = FxHashMap::default(); | 85 | let mut pkg_to_lib_crate = FxHashMap::default(); |
89 | let mut pkg_crates = FxHashMap::default(); | 86 | let mut pkg_crates = FxHashMap::default(); |
@@ -99,10 +96,7 @@ impl ServerWorldState { | |||
99 | lib_tgt = Some(crate_id); | 96 | lib_tgt = Some(crate_id); |
100 | pkg_to_lib_crate.insert(pkg, crate_id); | 97 | pkg_to_lib_crate.insert(pkg, crate_id); |
101 | } | 98 | } |
102 | pkg_crates | 99 | pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id); |
103 | .entry(pkg) | ||
104 | .or_insert_with(Vec::new) | ||
105 | .push(crate_id); | ||
106 | } | 100 | } |
107 | } | 101 | } |
108 | 102 | ||
@@ -192,18 +186,8 @@ impl ServerWorldState { | |||
192 | libs.push((SourceRootId(root.0.into()), files)); | 186 | libs.push((SourceRootId(root.0.into()), files)); |
193 | } | 187 | } |
194 | } | 188 | } |
195 | VfsChange::AddFile { | 189 | VfsChange::AddFile { root, file, path, text } => { |
196 | root, | 190 | change.add_file(SourceRootId(root.0.into()), FileId(file.0.into()), path, text); |
197 | file, | ||
198 | path, | ||
199 | text, | ||
200 | } => { | ||
201 | change.add_file( | ||
202 | SourceRootId(root.0.into()), | ||
203 | FileId(file.0.into()), | ||
204 | path, | ||
205 | text, | ||
206 | ); | ||
207 | } | 191 | } |
208 | VfsChange::RemoveFile { root, file, path } => { | 192 | VfsChange::RemoveFile { root, file, path } => { |
209 | change.remove_file(SourceRootId(root.0.into()), FileId(file.0.into()), path) | 193 | change.remove_file(SourceRootId(root.0.into()), FileId(file.0.into()), path) |
@@ -247,9 +231,7 @@ impl ServerWorld { | |||
247 | } | 231 | } |
248 | 232 | ||
249 | pub fn uri_to_file_id(&self, uri: &Url) -> Result<FileId> { | 233 | pub fn uri_to_file_id(&self, uri: &Url) -> Result<FileId> { |
250 | let path = uri | 234 | let path = uri.to_file_path().map_err(|()| format_err!("invalid uri: {}", uri))?; |
251 | .to_file_path() | ||
252 | .map_err(|()| format_err!("invalid uri: {}", uri))?; | ||
253 | let file = self | 235 | let file = self |
254 | .vfs | 236 | .vfs |
255 | .read() | 237 | .read() |