diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2018-10-16 14:44:24 +0100 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2018-10-16 14:44:24 +0100 |
commit | 1216878f7be20dd0e652fb8cdc395009fdcfae07 (patch) | |
tree | 6551967cc8c6e921b66071453ad7888a9121d326 /crates/ra_lsp_server/src | |
parent | 39cb6c6d3f78b193f5873c3492e530bbd24d5dd2 (diff) | |
parent | 61f3a438d3a729a6be941bca1ff4c6a97a33f221 (diff) |
Merge #134
134: Cargo Format run r=kjeremy a=kjeremy
I'm not sure how appreciated this is but I figured I would run `cargo fmt` and see what came up.
I made sure that `cargo test` still passes.
Co-authored-by: Jeremy A. Kolb <[email protected]>
Diffstat (limited to 'crates/ra_lsp_server/src')
-rw-r--r-- | crates/ra_lsp_server/src/caps.rs | 16 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/conv.rs | 66 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/lib.rs | 21 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main.rs | 6 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/handlers.rs | 206 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/mod.rs | 161 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/subscriptions.rs | 6 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/path_map.rs | 28 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/project_model.rs | 32 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/req.rs | 27 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/server_world.rs | 76 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/thread_watcher.rs | 19 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/vfs.rs | 12 |
13 files changed, 350 insertions, 326 deletions
diff --git a/crates/ra_lsp_server/src/caps.rs b/crates/ra_lsp_server/src/caps.rs index 5598ec75f..1dd495791 100644 --- a/crates/ra_lsp_server/src/caps.rs +++ b/crates/ra_lsp_server/src/caps.rs | |||
@@ -1,14 +1,8 @@ | |||
1 | use languageserver_types::{ | 1 | use languageserver_types::{ |
2 | ServerCapabilities, | 2 | CodeActionProviderCapability, CompletionOptions, DocumentOnTypeFormattingOptions, |
3 | CodeActionProviderCapability, | 3 | ExecuteCommandOptions, FoldingRangeProviderCapability, ServerCapabilities, |
4 | FoldingRangeProviderCapability, | 4 | SignatureHelpOptions, TextDocumentSyncCapability, TextDocumentSyncKind, |
5 | TextDocumentSyncCapability, | ||
6 | TextDocumentSyncOptions, | 5 | TextDocumentSyncOptions, |
7 | TextDocumentSyncKind, | ||
8 | ExecuteCommandOptions, | ||
9 | CompletionOptions, | ||
10 | SignatureHelpOptions, | ||
11 | DocumentOnTypeFormattingOptions, | ||
12 | }; | 6 | }; |
13 | 7 | ||
14 | pub fn server_capabilities() -> ServerCapabilities { | 8 | pub fn server_capabilities() -> ServerCapabilities { |
@@ -20,7 +14,7 @@ pub fn server_capabilities() -> ServerCapabilities { | |||
20 | will_save: None, | 14 | will_save: None, |
21 | will_save_wait_until: None, | 15 | will_save_wait_until: None, |
22 | save: None, | 16 | save: None, |
23 | } | 17 | }, |
24 | )), | 18 | )), |
25 | hover_provider: None, | 19 | hover_provider: None, |
26 | completion_provider: Some(CompletionOptions { | 20 | completion_provider: Some(CompletionOptions { |
@@ -28,7 +22,7 @@ pub fn server_capabilities() -> ServerCapabilities { | |||
28 | trigger_characters: None, | 22 | trigger_characters: None, |
29 | }), | 23 | }), |
30 | signature_help_provider: Some(SignatureHelpOptions { | 24 | signature_help_provider: Some(SignatureHelpOptions { |
31 | trigger_characters: Some(vec!["(".to_string(), ",".to_string()]) | 25 | trigger_characters: Some(vec!["(".to_string(), ",".to_string()]), |
32 | }), | 26 | }), |
33 | definition_provider: Some(true), | 27 | definition_provider: Some(true), |
34 | type_definition_provider: None, | 28 | type_definition_provider: None, |
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index a75b160c5..8325e8c1e 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs | |||
@@ -1,17 +1,12 @@ | |||
1 | use languageserver_types::{ | 1 | use languageserver_types::{ |
2 | Range, SymbolKind, Position, TextEdit, Location, Url, | 2 | Location, Position, Range, SymbolKind, TextDocumentEdit, TextDocumentIdentifier, |
3 | TextDocumentIdentifier, VersionedTextDocumentIdentifier, TextDocumentItem, | 3 | TextDocumentItem, TextDocumentPositionParams, TextEdit, Url, VersionedTextDocumentIdentifier, |
4 | TextDocumentPositionParams, TextDocumentEdit, | ||
5 | }; | ||
6 | use ra_editor::{LineIndex, LineCol, Edit, AtomEdit}; | ||
7 | use ra_syntax::{SyntaxKind, TextUnit, TextRange}; | ||
8 | use ra_analysis::{FileId, SourceChange, SourceFileEdit, FileSystemEdit}; | ||
9 | |||
10 | use crate::{ | ||
11 | Result, | ||
12 | server_world::ServerWorld, | ||
13 | req, | ||
14 | }; | 4 | }; |
5 | use ra_analysis::{FileId, FileSystemEdit, SourceChange, SourceFileEdit}; | ||
6 | use ra_editor::{AtomEdit, Edit, LineCol, LineIndex}; | ||
7 | use ra_syntax::{SyntaxKind, TextRange, TextUnit}; | ||
8 | |||
9 | use crate::{req, server_world::ServerWorld, Result}; | ||
15 | 10 | ||
16 | pub trait Conv { | 11 | pub trait Conv { |
17 | type Output; | 12 | type Output; |
@@ -190,8 +185,12 @@ impl TryConvWith for SourceChange { | |||
190 | None => None, | 185 | None => None, |
191 | Some(pos) => { | 186 | Some(pos) => { |
192 | let line_index = world.analysis().file_line_index(pos.file_id); | 187 | let line_index = world.analysis().file_line_index(pos.file_id); |
193 | let edits = self.source_file_edits.iter().find(|it| it.file_id == pos.file_id) | 188 | let edits = self |
194 | .map(|it| it.edits.as_slice()).unwrap_or(&[]); | 189 | .source_file_edits |
190 | .iter() | ||
191 | .find(|it| it.file_id == pos.file_id) | ||
192 | .map(|it| it.edits.as_slice()) | ||
193 | .unwrap_or(&[]); | ||
195 | let line_col = translate_offset_with_edit(&*line_index, pos.offset, edits); | 194 | let line_col = translate_offset_with_edit(&*line_index, pos.offset, edits); |
196 | let position = Position::new(line_col.line as u64, u32::from(line_col.col) as u64); | 195 | let position = Position::new(line_col.line as u64, u32::from(line_col.col) as u64); |
197 | Some(TextDocumentPositionParams { | 196 | Some(TextDocumentPositionParams { |
@@ -224,11 +223,11 @@ fn translate_offset_with_edit( | |||
224 | let fallback = pre_edit_index.line_col(offset); | 223 | let fallback = pre_edit_index.line_col(offset); |
225 | let edit = match edits.first() { | 224 | let edit = match edits.first() { |
226 | None => return fallback, | 225 | None => return fallback, |
227 | Some(edit) => edit | 226 | Some(edit) => edit, |
228 | }; | 227 | }; |
229 | let end_offset = edit.delete.start() + TextUnit::of_str(&edit.insert); | 228 | let end_offset = edit.delete.start() + TextUnit::of_str(&edit.insert); |
230 | if !(edit.delete.start() <= offset && offset <= end_offset) { | 229 | if !(edit.delete.start() <= offset && offset <= end_offset) { |
231 | return fallback | 230 | return fallback; |
232 | } | 231 | } |
233 | let rel_offset = offset - edit.delete.start(); | 232 | let rel_offset = offset - edit.delete.start(); |
234 | let in_edit_line_col = LineIndex::new(&edit.insert).line_col(rel_offset); | 233 | let in_edit_line_col = LineIndex::new(&edit.insert).line_col(rel_offset); |
@@ -255,11 +254,11 @@ impl TryConvWith for SourceFileEdit { | |||
255 | version: None, | 254 | version: None, |
256 | }; | 255 | }; |
257 | let line_index = world.analysis().file_line_index(self.file_id); | 256 | let line_index = world.analysis().file_line_index(self.file_id); |
258 | let edits = self.edits | 257 | let edits = self.edits.into_iter().map_conv_with(&line_index).collect(); |
259 | .into_iter() | 258 | Ok(TextDocumentEdit { |
260 | .map_conv_with(&line_index) | 259 | text_document, |
261 | .collect(); | 260 | edits, |
262 | Ok(TextDocumentEdit { text_document, edits }) | 261 | }) |
263 | } | 262 | } |
264 | } | 263 | } |
265 | 264 | ||
@@ -273,13 +272,13 @@ impl TryConvWith for FileSystemEdit { | |||
273 | let path = &path.as_str()[3..]; // strip `../` b/c url is weird | 272 | let path = &path.as_str()[3..]; // strip `../` b/c url is weird |
274 | let uri = uri.join(path)?; | 273 | let uri = uri.join(path)?; |
275 | req::FileSystemEdit::CreateFile { uri } | 274 | req::FileSystemEdit::CreateFile { uri } |
276 | }, | 275 | } |
277 | FileSystemEdit::MoveFile { file, path } => { | 276 | FileSystemEdit::MoveFile { file, path } => { |
278 | let src = world.file_id_to_uri(file)?; | 277 | let src = world.file_id_to_uri(file)?; |
279 | let path = &path.as_str()[3..]; // strip `../` b/c url is weird | 278 | let path = &path.as_str()[3..]; // strip `../` b/c url is weird |
280 | let dst = src.join(path)?; | 279 | let dst = src.join(path)?; |
281 | req::FileSystemEdit::MoveFile { src, dst } | 280 | req::FileSystemEdit::MoveFile { src, dst } |
282 | }, | 281 | } |
283 | }; | 282 | }; |
284 | Ok(res) | 283 | Ok(res) |
285 | } | 284 | } |
@@ -291,12 +290,9 @@ pub fn to_location( | |||
291 | world: &ServerWorld, | 290 | world: &ServerWorld, |
292 | line_index: &LineIndex, | 291 | line_index: &LineIndex, |
293 | ) -> Result<Location> { | 292 | ) -> Result<Location> { |
294 | let url = file_id.try_conv_with(world)?; | 293 | let url = file_id.try_conv_with(world)?; |
295 | let loc = Location::new( | 294 | let loc = Location::new(url, range.conv_with(line_index)); |
296 | url, | 295 | Ok(loc) |
297 | range.conv_with(line_index), | ||
298 | ); | ||
299 | Ok(loc) | ||
300 | } | 296 | } |
301 | 297 | ||
302 | pub trait MapConvWith<'a>: Sized + 'a { | 298 | pub trait MapConvWith<'a>: Sized + 'a { |
@@ -309,8 +305,9 @@ pub trait MapConvWith<'a>: Sized + 'a { | |||
309 | } | 305 | } |
310 | 306 | ||
311 | impl<'a, I> MapConvWith<'a> for I | 307 | impl<'a, I> MapConvWith<'a> for I |
312 | where I: Iterator + 'a, | 308 | where |
313 | I::Item: ConvWith | 309 | I: Iterator + 'a, |
310 | I::Item: ConvWith, | ||
314 | { | 311 | { |
315 | type Ctx = <I::Item as ConvWith>::Ctx; | 312 | type Ctx = <I::Item as ConvWith>::Ctx; |
316 | type Output = <I::Item as ConvWith>::Output; | 313 | type Output = <I::Item as ConvWith>::Output; |
@@ -322,9 +319,9 @@ pub struct ConvWithIter<'a, I, Ctx: 'a> { | |||
322 | } | 319 | } |
323 | 320 | ||
324 | impl<'a, I, Ctx> Iterator for ConvWithIter<'a, I, Ctx> | 321 | impl<'a, I, Ctx> Iterator for ConvWithIter<'a, I, Ctx> |
325 | where | 322 | where |
326 | I: Iterator, | 323 | I: Iterator, |
327 | I::Item: ConvWith<Ctx=Ctx>, | 324 | I::Item: ConvWith<Ctx = Ctx>, |
328 | { | 325 | { |
329 | type Item = <I::Item as ConvWith>::Output; | 326 | type Item = <I::Item as ConvWith>::Output; |
330 | 327 | ||
@@ -332,4 +329,3 @@ impl<'a, I, Ctx> Iterator for ConvWithIter<'a, I, Ctx> | |||
332 | self.iter.next().map(|item| item.conv_with(self.ctx)) | 329 | self.iter.next().map(|item| item.conv_with(self.ctx)) |
333 | } | 330 | } |
334 | } | 331 | } |
335 | |||
diff --git a/crates/ra_lsp_server/src/lib.rs b/crates/ra_lsp_server/src/lib.rs index 7224b1476..f1b17f282 100644 --- a/crates/ra_lsp_server/src/lib.rs +++ b/crates/ra_lsp_server/src/lib.rs | |||
@@ -2,39 +2,36 @@ | |||
2 | extern crate failure; | 2 | extern crate failure; |
3 | #[macro_use] | 3 | #[macro_use] |
4 | extern crate serde_derive; | 4 | extern crate serde_derive; |
5 | extern crate languageserver_types; | ||
5 | extern crate serde; | 6 | extern crate serde; |
6 | extern crate serde_json; | 7 | extern crate serde_json; |
7 | extern crate languageserver_types; | ||
8 | #[macro_use] | 8 | #[macro_use] |
9 | extern crate crossbeam_channel; | 9 | extern crate crossbeam_channel; |
10 | extern crate rayon; | 10 | extern crate rayon; |
11 | #[macro_use] | 11 | #[macro_use] |
12 | extern crate log; | 12 | extern crate log; |
13 | extern crate cargo_metadata; | ||
13 | extern crate drop_bomb; | 14 | extern crate drop_bomb; |
14 | extern crate url_serde; | ||
15 | extern crate walkdir; | ||
16 | extern crate im; | 15 | extern crate im; |
17 | extern crate relative_path; | 16 | extern crate relative_path; |
18 | extern crate cargo_metadata; | ||
19 | extern crate rustc_hash; | 17 | extern crate rustc_hash; |
18 | extern crate url_serde; | ||
19 | extern crate walkdir; | ||
20 | 20 | ||
21 | extern crate gen_lsp_server; | 21 | extern crate gen_lsp_server; |
22 | extern crate ra_editor; | ||
23 | extern crate ra_analysis; | 22 | extern crate ra_analysis; |
23 | extern crate ra_editor; | ||
24 | extern crate ra_syntax; | 24 | extern crate ra_syntax; |
25 | 25 | ||
26 | mod caps; | 26 | mod caps; |
27 | pub mod req; | ||
28 | mod conv; | 27 | mod conv; |
29 | mod main_loop; | 28 | mod main_loop; |
30 | mod vfs; | ||
31 | mod path_map; | 29 | mod path_map; |
32 | mod server_world; | ||
33 | mod project_model; | 30 | mod project_model; |
31 | pub mod req; | ||
32 | mod server_world; | ||
34 | pub mod thread_watcher; | 33 | pub mod thread_watcher; |
34 | mod vfs; | ||
35 | 35 | ||
36 | pub type Result<T> = ::std::result::Result<T, ::failure::Error>; | 36 | pub type Result<T> = ::std::result::Result<T, ::failure::Error>; |
37 | pub use crate::{ | 37 | pub use crate::{caps::server_capabilities, main_loop::main_loop}; |
38 | main_loop::main_loop, | ||
39 | caps::server_capabilities, | ||
40 | }; | ||
diff --git a/crates/ra_lsp_server/src/main.rs b/crates/ra_lsp_server/src/main.rs index e5d1792b7..9f62347f1 100644 --- a/crates/ra_lsp_server/src/main.rs +++ b/crates/ra_lsp_server/src/main.rs | |||
@@ -6,7 +6,7 @@ extern crate flexi_logger; | |||
6 | extern crate gen_lsp_server; | 6 | extern crate gen_lsp_server; |
7 | extern crate ra_lsp_server; | 7 | extern crate ra_lsp_server; |
8 | 8 | ||
9 | use flexi_logger::{Logger, Duplicate}; | 9 | use flexi_logger::{Duplicate, Logger}; |
10 | use gen_lsp_server::{run_server, stdio_transport}; | 10 | use gen_lsp_server::{run_server, stdio_transport}; |
11 | use ra_lsp_server::Result; | 11 | use ra_lsp_server::Result; |
12 | 12 | ||
@@ -38,7 +38,8 @@ fn main_inner() -> Result<()> { | |||
38 | receiver, | 38 | receiver, |
39 | sender, | 39 | sender, |
40 | |params, r, s| { | 40 | |params, r, s| { |
41 | let root = params.root_uri | 41 | let root = params |
42 | .root_uri | ||
42 | .and_then(|it| it.to_file_path().ok()) | 43 | .and_then(|it| it.to_file_path().ok()) |
43 | .unwrap_or(cwd); | 44 | .unwrap_or(cwd); |
44 | ra_lsp_server::main_loop(false, root, r, s) | 45 | ra_lsp_server::main_loop(false, root, r, s) |
@@ -49,4 +50,3 @@ fn main_inner() -> Result<()> { | |||
49 | info!("... IO is down"); | 50 | info!("... IO is down"); |
50 | Ok(()) | 51 | Ok(()) |
51 | } | 52 | } |
52 | |||
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 5acb39b60..c25b63852 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs | |||
@@ -1,23 +1,20 @@ | |||
1 | use rustc_hash::FxHashMap; | 1 | use rustc_hash::FxHashMap; |
2 | 2 | ||
3 | use languageserver_types::{ | 3 | use languageserver_types::{ |
4 | Diagnostic, DiagnosticSeverity, DocumentSymbol, | 4 | CodeActionResponse, Command, CompletionItem, CompletionItemKind, Diagnostic, |
5 | CodeActionResponse, Command, TextDocumentIdentifier, | 5 | DiagnosticSeverity, DocumentSymbol, FoldingRange, FoldingRangeKind, FoldingRangeParams, |
6 | SymbolInformation, Position, Location, TextEdit, | 6 | InsertTextFormat, Location, Position, SymbolInformation, TextDocumentIdentifier, TextEdit, |
7 | CompletionItem, InsertTextFormat, CompletionItemKind, | ||
8 | FoldingRange, FoldingRangeParams, FoldingRangeKind | ||
9 | }; | 7 | }; |
8 | use ra_analysis::{FileId, FoldKind, JobToken, Query, RunnableKind}; | ||
9 | use ra_syntax::text_utils::contains_offset_nonstrict; | ||
10 | use serde_json::to_value; | 10 | use serde_json::to_value; |
11 | use ra_analysis::{Query, FileId, RunnableKind, JobToken, FoldKind}; | ||
12 | use ra_syntax::{ | ||
13 | text_utils::contains_offset_nonstrict | ||
14 | }; | ||
15 | 11 | ||
16 | use crate::{ | 12 | use crate::{ |
17 | req::{self, Decoration}, Result, | 13 | conv::{to_location, Conv, ConvWith, MapConvWith, TryConvWith}, |
18 | conv::{Conv, ConvWith, TryConvWith, MapConvWith, to_location}, | ||
19 | server_world::ServerWorld, | ||
20 | project_model::TargetKind, | 14 | project_model::TargetKind, |
15 | req::{self, Decoration}, | ||
16 | server_world::ServerWorld, | ||
17 | Result, | ||
21 | }; | 18 | }; |
22 | 19 | ||
23 | pub fn handle_syntax_tree( | 20 | pub fn handle_syntax_tree( |
@@ -38,7 +35,9 @@ pub fn handle_extend_selection( | |||
38 | let file_id = params.text_document.try_conv_with(&world)?; | 35 | let file_id = params.text_document.try_conv_with(&world)?; |
39 | let file = world.analysis().file_syntax(file_id); | 36 | let file = world.analysis().file_syntax(file_id); |
40 | let line_index = world.analysis().file_line_index(file_id); | 37 | let line_index = world.analysis().file_line_index(file_id); |
41 | let selections = params.selections.into_iter() | 38 | let selections = params |
39 | .selections | ||
40 | .into_iter() | ||
42 | .map_conv_with(&line_index) | 41 | .map_conv_with(&line_index) |
43 | .map(|r| world.analysis().extend_selection(&file, r)) | 42 | .map(|r| world.analysis().extend_selection(&file, r)) |
44 | .map_conv_with(&line_index) | 43 | .map_conv_with(&line_index) |
@@ -54,11 +53,15 @@ pub fn handle_find_matching_brace( | |||
54 | let file_id = params.text_document.try_conv_with(&world)?; | 53 | let file_id = params.text_document.try_conv_with(&world)?; |
55 | let file = world.analysis().file_syntax(file_id); | 54 | let file = world.analysis().file_syntax(file_id); |
56 | let line_index = world.analysis().file_line_index(file_id); | 55 | let line_index = world.analysis().file_line_index(file_id); |
57 | let res = params.offsets | 56 | let res = params |
57 | .offsets | ||
58 | .into_iter() | 58 | .into_iter() |
59 | .map_conv_with(&line_index) | 59 | .map_conv_with(&line_index) |
60 | .map(|offset| { | 60 | .map(|offset| { |
61 | world.analysis().matching_brace(&file, offset).unwrap_or(offset) | 61 | world |
62 | .analysis() | ||
63 | .matching_brace(&file, offset) | ||
64 | .unwrap_or(offset) | ||
62 | }) | 65 | }) |
63 | .map_conv_with(&line_index) | 66 | .map_conv_with(&line_index) |
64 | .collect(); | 67 | .collect(); |
@@ -73,7 +76,9 @@ pub fn handle_join_lines( | |||
73 | let file_id = params.text_document.try_conv_with(&world)?; | 76 | let file_id = params.text_document.try_conv_with(&world)?; |
74 | let line_index = world.analysis().file_line_index(file_id); | 77 | let line_index = world.analysis().file_line_index(file_id); |
75 | let range = params.range.conv_with(&line_index); | 78 | let range = params.range.conv_with(&line_index); |
76 | world.analysis().join_lines(file_id, range) | 79 | world |
80 | .analysis() | ||
81 | .join_lines(file_id, range) | ||
77 | .try_conv_with(&world) | 82 | .try_conv_with(&world) |
78 | } | 83 | } |
79 | 84 | ||
@@ -87,7 +92,7 @@ pub fn handle_on_enter( | |||
87 | let offset = params.position.conv_with(&line_index); | 92 | let offset = params.position.conv_with(&line_index); |
88 | match world.analysis().on_enter(file_id, offset) { | 93 | match world.analysis().on_enter(file_id, offset) { |
89 | None => Ok(None), | 94 | None => Ok(None), |
90 | Some(edit) => Ok(Some(edit.try_conv_with(&world)?)) | 95 | Some(edit) => Ok(Some(edit.try_conv_with(&world)?)), |
91 | } | 96 | } |
92 | } | 97 | } |
93 | 98 | ||
@@ -158,7 +163,9 @@ pub fn handle_workspace_symbol( | |||
158 | let all_symbols = params.query.contains("#"); | 163 | let all_symbols = params.query.contains("#"); |
159 | let libs = params.query.contains("*"); | 164 | let libs = params.query.contains("*"); |
160 | let query = { | 165 | let query = { |
161 | let query: String = params.query.chars() | 166 | let query: String = params |
167 | .query | ||
168 | .chars() | ||
162 | .filter(|&c| c != '#' && c != '*') | 169 | .filter(|&c| c != '#' && c != '*') |
163 | .collect(); | 170 | .collect(); |
164 | let mut q = Query::new(query); | 171 | let mut q = Query::new(query); |
@@ -180,22 +187,23 @@ pub fn handle_workspace_symbol( | |||
180 | 187 | ||
181 | return Ok(Some(res)); | 188 | return Ok(Some(res)); |
182 | 189 | ||
183 | fn exec_query(world: &ServerWorld, query: Query, token: &JobToken) -> Result<Vec<SymbolInformation>> { | 190 | fn exec_query( |
191 | world: &ServerWorld, | ||
192 | query: Query, | ||
193 | token: &JobToken, | ||
194 | ) -> Result<Vec<SymbolInformation>> { | ||
184 | let mut res = Vec::new(); | 195 | let mut res = Vec::new(); |
185 | for (file_id, symbol) in world.analysis().symbol_search(query, token) { | 196 | for (file_id, symbol) in world.analysis().symbol_search(query, token) { |
186 | let line_index = world.analysis().file_line_index(file_id); | 197 | let line_index = world.analysis().file_line_index(file_id); |
187 | let info = SymbolInformation { | 198 | let info = SymbolInformation { |
188 | name: symbol.name.to_string(), | 199 | name: symbol.name.to_string(), |
189 | kind: symbol.kind.conv(), | 200 | kind: symbol.kind.conv(), |
190 | location: to_location( | 201 | location: to_location(file_id, symbol.node_range, world, &line_index)?, |
191 | file_id, symbol.node_range, | ||
192 | world, &line_index | ||
193 | )?, | ||
194 | container_name: None, | 202 | container_name: None, |
195 | deprecated: None, | 203 | deprecated: None, |
196 | }; | 204 | }; |
197 | res.push(info); | 205 | res.push(info); |
198 | }; | 206 | } |
199 | Ok(res) | 207 | Ok(res) |
200 | } | 208 | } |
201 | } | 209 | } |
@@ -209,12 +217,12 @@ pub fn handle_goto_definition( | |||
209 | let line_index = world.analysis().file_line_index(file_id); | 217 | let line_index = world.analysis().file_line_index(file_id); |
210 | let offset = params.position.conv_with(&line_index); | 218 | let offset = params.position.conv_with(&line_index); |
211 | let mut res = Vec::new(); | 219 | let mut res = Vec::new(); |
212 | for (file_id, symbol) in world.analysis().approximately_resolve_symbol(file_id, offset, &token) { | 220 | for (file_id, symbol) in world |
221 | .analysis() | ||
222 | .approximately_resolve_symbol(file_id, offset, &token) | ||
223 | { | ||
213 | let line_index = world.analysis().file_line_index(file_id); | 224 | let line_index = world.analysis().file_line_index(file_id); |
214 | let location = to_location( | 225 | let location = to_location(file_id, symbol.node_range, &world, &line_index)?; |
215 | file_id, symbol.node_range, | ||
216 | &world, &line_index, | ||
217 | )?; | ||
218 | res.push(location) | 226 | res.push(location) |
219 | } | 227 | } |
220 | Ok(Some(req::GotoDefinitionResponse::Array(res))) | 228 | Ok(Some(req::GotoDefinitionResponse::Array(res))) |
@@ -229,10 +237,7 @@ pub fn handle_parent_module( | |||
229 | let mut res = Vec::new(); | 237 | let mut res = Vec::new(); |
230 | for (file_id, symbol) in world.analysis().parent_module(file_id) { | 238 | for (file_id, symbol) in world.analysis().parent_module(file_id) { |
231 | let line_index = world.analysis().file_line_index(file_id); | 239 | let line_index = world.analysis().file_line_index(file_id); |
232 | let location = to_location( | 240 | let location = to_location(file_id, symbol.node_range, &world, &line_index)?; |
233 | file_id, symbol.node_range, | ||
234 | &world, &line_index | ||
235 | )?; | ||
236 | res.push(location); | 241 | res.push(location); |
237 | } | 242 | } |
238 | Ok(res) | 243 | Ok(res) |
@@ -259,21 +264,16 @@ pub fn handle_runnables( | |||
259 | let r = req::Runnable { | 264 | let r = req::Runnable { |
260 | range: runnable.range.conv_with(&line_index), | 265 | range: runnable.range.conv_with(&line_index), |
261 | label: match &runnable.kind { | 266 | label: match &runnable.kind { |
262 | RunnableKind::Test { name } => | 267 | RunnableKind::Test { name } => format!("test {}", name), |
263 | format!("test {}", name), | 268 | RunnableKind::Bin => "run binary".to_string(), |
264 | RunnableKind::Bin => | ||
265 | "run binary".to_string(), | ||
266 | }, | 269 | }, |
267 | bin: "cargo".to_string(), | 270 | bin: "cargo".to_string(), |
268 | args, | 271 | args, |
269 | env: { | 272 | env: { |
270 | let mut m = FxHashMap::default(); | 273 | let mut m = FxHashMap::default(); |
271 | m.insert( | 274 | m.insert("RUST_BACKTRACE".to_string(), "short".to_string()); |
272 | "RUST_BACKTRACE".to_string(), | ||
273 | "short".to_string(), | ||
274 | ); | ||
275 | m | 275 | m |
276 | } | 276 | }, |
277 | }; | 277 | }; |
278 | res.push(r); | 278 | res.push(r); |
279 | } | 279 | } |
@@ -283,10 +283,16 @@ pub fn handle_runnables( | |||
283 | let spec = if let Some(&crate_id) = world.analysis().crate_for(file_id).first() { | 283 | let spec = if let Some(&crate_id) = world.analysis().crate_for(file_id).first() { |
284 | let file_id = world.analysis().crate_root(crate_id); | 284 | let file_id = world.analysis().crate_root(crate_id); |
285 | let path = world.path_map.get_path(file_id); | 285 | let path = world.path_map.get_path(file_id); |
286 | world.workspaces.iter() | 286 | world |
287 | .workspaces | ||
288 | .iter() | ||
287 | .filter_map(|ws| { | 289 | .filter_map(|ws| { |
288 | let tgt = ws.target_by_root(path)?; | 290 | let tgt = ws.target_by_root(path)?; |
289 | Some((tgt.package(ws).name(ws).clone(), tgt.name(ws).clone(), tgt.kind(ws))) | 291 | Some(( |
292 | tgt.package(ws).name(ws).clone(), | ||
293 | tgt.name(ws).clone(), | ||
294 | tgt.kind(ws), | ||
295 | )) | ||
290 | }) | 296 | }) |
291 | .next() | 297 | .next() |
292 | } else { | 298 | } else { |
@@ -294,22 +300,22 @@ pub fn handle_runnables( | |||
294 | }; | 300 | }; |
295 | let mut res = Vec::new(); | 301 | let mut res = Vec::new(); |
296 | match kind { | 302 | match kind { |
297 | RunnableKind::Test { name } => { | 303 | RunnableKind::Test { name } => { |
298 | res.push("test".to_string()); | 304 | res.push("test".to_string()); |
299 | if let Some((pkg_name, tgt_name, tgt_kind)) = spec { | 305 | if let Some((pkg_name, tgt_name, tgt_kind)) = spec { |
300 | spec_args(pkg_name, tgt_name, tgt_kind, &mut res); | 306 | spec_args(pkg_name, tgt_name, tgt_kind, &mut res); |
301 | } | ||
302 | res.push("--".to_string()); | ||
303 | res.push(name.to_string()); | ||
304 | res.push("--nocapture".to_string()); | ||
305 | } | 307 | } |
306 | RunnableKind::Bin => { | 308 | res.push("--".to_string()); |
307 | res.push("run".to_string()); | 309 | res.push(name.to_string()); |
308 | if let Some((pkg_name, tgt_name, tgt_kind)) = spec { | 310 | res.push("--nocapture".to_string()); |
309 | spec_args(pkg_name, tgt_name, tgt_kind, &mut res); | 311 | } |
310 | } | 312 | RunnableKind::Bin => { |
313 | res.push("run".to_string()); | ||
314 | if let Some((pkg_name, tgt_name, tgt_kind)) = spec { | ||
315 | spec_args(pkg_name, tgt_name, tgt_kind, &mut res); | ||
311 | } | 316 | } |
312 | } | 317 | } |
318 | } | ||
313 | res | 319 | res |
314 | } | 320 | } |
315 | 321 | ||
@@ -362,12 +368,13 @@ pub fn handle_completion( | |||
362 | None => return Ok(None), | 368 | None => return Ok(None), |
363 | Some(items) => items, | 369 | Some(items) => items, |
364 | }; | 370 | }; |
365 | let items = items.into_iter() | 371 | let items = items |
372 | .into_iter() | ||
366 | .map(|item| { | 373 | .map(|item| { |
367 | let mut res = CompletionItem { | 374 | let mut res = CompletionItem { |
368 | label: item.label, | 375 | label: item.label, |
369 | filter_text: item.lookup, | 376 | filter_text: item.lookup, |
370 | .. Default::default() | 377 | ..Default::default() |
371 | }; | 378 | }; |
372 | if let Some(snip) = item.snippet { | 379 | if let Some(snip) = item.snippet { |
373 | res.insert_text = Some(snip); | 380 | res.insert_text = Some(snip); |
@@ -389,24 +396,27 @@ pub fn handle_folding_range( | |||
389 | let file_id = params.text_document.try_conv_with(&world)?; | 396 | let file_id = params.text_document.try_conv_with(&world)?; |
390 | let line_index = world.analysis().file_line_index(file_id); | 397 | let line_index = world.analysis().file_line_index(file_id); |
391 | 398 | ||
392 | let res = Some(world.analysis() | 399 | let res = Some( |
393 | .folding_ranges(file_id) | 400 | world |
394 | .into_iter() | 401 | .analysis() |
395 | .map(|fold| { | 402 | .folding_ranges(file_id) |
396 | let kind = match fold.kind { | 403 | .into_iter() |
397 | FoldKind::Comment => FoldingRangeKind::Comment, | 404 | .map(|fold| { |
398 | FoldKind::Imports => FoldingRangeKind::Imports | 405 | let kind = match fold.kind { |
399 | }; | 406 | FoldKind::Comment => FoldingRangeKind::Comment, |
400 | let range = fold.range.conv_with(&line_index); | 407 | FoldKind::Imports => FoldingRangeKind::Imports, |
401 | FoldingRange { | 408 | }; |
402 | start_line: range.start.line, | 409 | let range = fold.range.conv_with(&line_index); |
403 | start_character: Some(range.start.character), | 410 | FoldingRange { |
404 | end_line: range.end.line, | 411 | start_line: range.start.line, |
405 | end_character: Some(range.start.character), | 412 | start_character: Some(range.start.character), |
406 | kind: Some(kind) | 413 | end_line: range.end.line, |
407 | } | 414 | end_character: Some(range.start.character), |
408 | }) | 415 | kind: Some(kind), |
409 | .collect()); | 416 | } |
417 | }) | ||
418 | .collect(), | ||
419 | ); | ||
410 | 420 | ||
411 | Ok(res) | 421 | Ok(res) |
412 | } | 422 | } |
@@ -422,25 +432,28 @@ pub fn handle_signature_help( | |||
422 | let line_index = world.analysis().file_line_index(file_id); | 432 | let line_index = world.analysis().file_line_index(file_id); |
423 | let offset = params.position.conv_with(&line_index); | 433 | let offset = params.position.conv_with(&line_index); |
424 | 434 | ||
425 | if let Some((descriptor, active_param)) = world.analysis().resolve_callable(file_id, offset, &token) { | 435 | if let Some((descriptor, active_param)) = |
426 | let parameters : Vec<ParameterInformation> = | 436 | world.analysis().resolve_callable(file_id, offset, &token) |
427 | descriptor.params.iter().map(|param| | 437 | { |
428 | ParameterInformation { | 438 | let parameters: Vec<ParameterInformation> = descriptor |
429 | label: param.clone(), | 439 | .params |
430 | documentation: None | 440 | .iter() |
431 | } | 441 | .map(|param| ParameterInformation { |
432 | ).collect(); | 442 | label: param.clone(), |
443 | documentation: None, | ||
444 | }) | ||
445 | .collect(); | ||
433 | 446 | ||
434 | let sig_info = SignatureInformation { | 447 | let sig_info = SignatureInformation { |
435 | label: descriptor.label, | 448 | label: descriptor.label, |
436 | documentation: None, | 449 | documentation: None, |
437 | parameters: Some(parameters) | 450 | parameters: Some(parameters), |
438 | }; | 451 | }; |
439 | 452 | ||
440 | Ok(Some(req::SignatureHelp { | 453 | Ok(Some(req::SignatureHelp { |
441 | signatures: vec![sig_info], | 454 | signatures: vec![sig_info], |
442 | active_signature: Some(0), | 455 | active_signature: Some(0), |
443 | active_parameter: active_param.map(|a| a as u64) | 456 | active_parameter: active_param.map(|a| a as u64), |
444 | })) | 457 | })) |
445 | } else { | 458 | } else { |
446 | Ok(None) | 459 | Ok(None) |
@@ -457,7 +470,10 @@ pub fn handle_code_action( | |||
457 | let range = params.range.conv_with(&line_index); | 470 | let range = params.range.conv_with(&line_index); |
458 | 471 | ||
459 | let assists = world.analysis().assists(file_id, range).into_iter(); | 472 | let assists = world.analysis().assists(file_id, range).into_iter(); |
460 | let fixes = world.analysis().diagnostics(file_id).into_iter() | 473 | let fixes = world |
474 | .analysis() | ||
475 | .diagnostics(file_id) | ||
476 | .into_iter() | ||
461 | .filter_map(|d| Some((d.range, d.fix?))) | 477 | .filter_map(|d| Some((d.range, d.fix?))) |
462 | .filter(|(range, _fix)| contains_offset_nonstrict(*range, range.start())) | 478 | .filter(|(range, _fix)| contains_offset_nonstrict(*range, range.start())) |
463 | .map(|(_range, fix)| fix); | 479 | .map(|(_range, fix)| fix); |
@@ -483,7 +499,9 @@ pub fn publish_diagnostics( | |||
483 | ) -> Result<req::PublishDiagnosticsParams> { | 499 | ) -> Result<req::PublishDiagnosticsParams> { |
484 | let uri = world.file_id_to_uri(file_id)?; | 500 | let uri = world.file_id_to_uri(file_id)?; |
485 | let line_index = world.analysis().file_line_index(file_id); | 501 | let line_index = world.analysis().file_line_index(file_id); |
486 | let diagnostics = world.analysis().diagnostics(file_id) | 502 | let diagnostics = world |
503 | .analysis() | ||
504 | .diagnostics(file_id) | ||
487 | .into_iter() | 505 | .into_iter() |
488 | .map(|d| Diagnostic { | 506 | .map(|d| Diagnostic { |
489 | range: d.range.conv_with(&line_index), | 507 | range: d.range.conv_with(&line_index), |
@@ -492,7 +510,8 @@ pub fn publish_diagnostics( | |||
492 | source: Some("rust-analyzer".to_string()), | 510 | source: Some("rust-analyzer".to_string()), |
493 | message: d.message, | 511 | message: d.message, |
494 | related_information: None, | 512 | related_information: None, |
495 | }).collect(); | 513 | }) |
514 | .collect(); | ||
496 | Ok(req::PublishDiagnosticsParams { uri, diagnostics }) | 515 | Ok(req::PublishDiagnosticsParams { uri, diagnostics }) |
497 | } | 516 | } |
498 | 517 | ||
@@ -509,10 +528,13 @@ pub fn publish_decorations( | |||
509 | 528 | ||
510 | fn highlight(world: &ServerWorld, file_id: FileId) -> Vec<Decoration> { | 529 | fn highlight(world: &ServerWorld, file_id: FileId) -> Vec<Decoration> { |
511 | let line_index = world.analysis().file_line_index(file_id); | 530 | let line_index = world.analysis().file_line_index(file_id); |
512 | world.analysis().highlight(file_id) | 531 | world |
532 | .analysis() | ||
533 | .highlight(file_id) | ||
513 | .into_iter() | 534 | .into_iter() |
514 | .map(|h| Decoration { | 535 | .map(|h| Decoration { |
515 | range: h.range.conv_with(&line_index), | 536 | range: h.range.conv_with(&line_index), |
516 | tag: h.tag, | 537 | tag: h.tag, |
517 | }).collect() | 538 | }) |
539 | .collect() | ||
518 | } | 540 | } |
diff --git a/crates/ra_lsp_server/src/main_loop/mod.rs b/crates/ra_lsp_server/src/main_loop/mod.rs index cf2477cb5..a11baf4aa 100644 --- a/crates/ra_lsp_server/src/main_loop/mod.rs +++ b/crates/ra_lsp_server/src/main_loop/mod.rs | |||
@@ -1,29 +1,26 @@ | |||
1 | mod handlers; | 1 | mod handlers; |
2 | mod subscriptions; | 2 | mod subscriptions; |
3 | 3 | ||
4 | use std::{ | 4 | use std::path::PathBuf; |
5 | path::PathBuf, | ||
6 | }; | ||
7 | 5 | ||
8 | use serde::{Serialize, de::DeserializeOwned}; | 6 | use crossbeam_channel::{unbounded, Receiver, Sender}; |
9 | use crossbeam_channel::{unbounded, Sender, Receiver}; | ||
10 | use rayon::{self, ThreadPool}; | ||
11 | use languageserver_types::{NumberOrString}; | ||
12 | use ra_analysis::{FileId, JobHandle, JobToken, LibraryData}; | ||
13 | use gen_lsp_server::{ | 7 | use gen_lsp_server::{ |
14 | RawRequest, RawNotification, RawMessage, RawResponse, ErrorCode, | 8 | handle_shutdown, ErrorCode, RawMessage, RawNotification, RawRequest, RawResponse, |
15 | handle_shutdown, | ||
16 | }; | 9 | }; |
10 | use languageserver_types::NumberOrString; | ||
11 | use ra_analysis::{FileId, JobHandle, JobToken, LibraryData}; | ||
12 | use rayon::{self, ThreadPool}; | ||
17 | use rustc_hash::FxHashMap; | 13 | use rustc_hash::FxHashMap; |
14 | use serde::{de::DeserializeOwned, Serialize}; | ||
18 | 15 | ||
19 | use crate::{ | 16 | use crate::{ |
17 | main_loop::subscriptions::Subscriptions, | ||
18 | project_model::{workspace_loader, CargoWorkspace}, | ||
20 | req, | 19 | req, |
21 | Result, | 20 | server_world::{ServerWorld, ServerWorldState}, |
22 | vfs::{self, FileEvent}, | ||
23 | server_world::{ServerWorldState, ServerWorld}, | ||
24 | main_loop::subscriptions::{Subscriptions}, | ||
25 | project_model::{CargoWorkspace, workspace_loader}, | ||
26 | thread_watcher::Worker, | 21 | thread_watcher::Worker, |
22 | vfs::{self, FileEvent}, | ||
23 | Result, | ||
27 | }; | 24 | }; |
28 | 25 | ||
29 | #[derive(Debug)] | 26 | #[derive(Debug)] |
@@ -147,56 +144,50 @@ fn main_loop_inner( | |||
147 | } | 144 | } |
148 | state_changed = true; | 145 | state_changed = true; |
149 | } | 146 | } |
150 | Event::Ws(ws) => { | 147 | Event::Ws(ws) => match ws { |
151 | match ws { | 148 | Ok(ws) => { |
152 | Ok(ws) => { | 149 | let workspaces = vec![ws]; |
153 | let workspaces = vec![ws]; | 150 | feedback(internal_mode, "workspace loaded", msg_sender); |
154 | feedback(internal_mode, "workspace loaded", msg_sender); | 151 | for ws in workspaces.iter() { |
155 | for ws in workspaces.iter() { | 152 | for pkg in ws.packages().filter(|pkg| !pkg.is_member(ws)) { |
156 | for pkg in ws.packages().filter(|pkg| !pkg.is_member(ws)) { | 153 | debug!("sending root, {}", pkg.root(ws).to_path_buf().display()); |
157 | debug!("sending root, {}", pkg.root(ws).to_path_buf().display()); | 154 | fs_worker.send(pkg.root(ws).to_path_buf()); |
158 | fs_worker.send(pkg.root(ws).to_path_buf()); | ||
159 | } | ||
160 | } | 155 | } |
161 | state.set_workspaces(workspaces); | ||
162 | state_changed = true; | ||
163 | } | 156 | } |
164 | Err(e) => warn!("loading workspace failed: {}", e), | 157 | state.set_workspaces(workspaces); |
158 | state_changed = true; | ||
165 | } | 159 | } |
166 | } | 160 | Err(e) => warn!("loading workspace failed: {}", e), |
161 | }, | ||
167 | Event::Lib(lib) => { | 162 | Event::Lib(lib) => { |
168 | feedback(internal_mode, "library loaded", msg_sender); | 163 | feedback(internal_mode, "library loaded", msg_sender); |
169 | state.add_lib(lib); | 164 | state.add_lib(lib); |
170 | } | 165 | } |
171 | Event::Msg(msg) => { | 166 | Event::Msg(msg) => match msg { |
172 | match msg { | 167 | RawMessage::Request(req) => { |
173 | RawMessage::Request(req) => { | 168 | let req = match handle_shutdown(req, msg_sender) { |
174 | let req = match handle_shutdown(req, msg_sender) { | 169 | Some(req) => req, |
175 | Some(req) => req, | 170 | None => return Ok(()), |
176 | None => return Ok(()), | 171 | }; |
177 | }; | 172 | match on_request(state, pending_requests, pool, &task_sender, req)? { |
178 | match on_request(state, pending_requests, pool, &task_sender, req)? { | 173 | None => (), |
179 | None => (), | 174 | Some(req) => { |
180 | Some(req) => { | 175 | error!("unknown request: {:?}", req); |
181 | error!("unknown request: {:?}", req); | 176 | let resp = RawResponse::err( |
182 | let resp = RawResponse::err( | 177 | req.id, |
183 | req.id, | 178 | ErrorCode::MethodNotFound as i32, |
184 | ErrorCode::MethodNotFound as i32, | 179 | "unknown request".to_string(), |
185 | "unknown request".to_string(), | 180 | ); |
186 | ); | 181 | msg_sender.send(RawMessage::Response(resp)) |
187 | msg_sender.send(RawMessage::Response(resp)) | ||
188 | } | ||
189 | } | 182 | } |
190 | } | 183 | } |
191 | RawMessage::Notification(not) => { | ||
192 | on_notification(msg_sender, state, pending_requests, subs, not)?; | ||
193 | state_changed = true; | ||
194 | } | ||
195 | RawMessage::Response(resp) => { | ||
196 | error!("unexpected response: {:?}", resp) | ||
197 | } | ||
198 | } | 184 | } |
199 | } | 185 | RawMessage::Notification(not) => { |
186 | on_notification(msg_sender, state, pending_requests, subs, not)?; | ||
187 | state_changed = true; | ||
188 | } | ||
189 | RawMessage::Response(resp) => error!("unexpected response: {:?}", resp), | ||
190 | }, | ||
200 | }; | 191 | }; |
201 | 192 | ||
202 | if state_changed { | 193 | if state_changed { |
@@ -222,8 +213,7 @@ fn on_task( | |||
222 | } | 213 | } |
223 | msg_sender.send(RawMessage::Response(response)) | 214 | msg_sender.send(RawMessage::Response(response)) |
224 | } | 215 | } |
225 | Task::Notify(n) => | 216 | Task::Notify(n) => msg_sender.send(RawMessage::Notification(n)), |
226 | msg_sender.send(RawMessage::Notification(n)), | ||
227 | } | 217 | } |
228 | } | 218 | } |
229 | 219 | ||
@@ -237,7 +227,9 @@ fn on_request( | |||
237 | let mut pool_dispatcher = PoolDispatcher { | 227 | let mut pool_dispatcher = PoolDispatcher { |
238 | req: Some(req), | 228 | req: Some(req), |
239 | res: None, | 229 | res: None, |
240 | pool, world, sender | 230 | pool, |
231 | world, | ||
232 | sender, | ||
241 | }; | 233 | }; |
242 | let req = pool_dispatcher | 234 | let req = pool_dispatcher |
243 | .on::<req::SyntaxTree>(handlers::handle_syntax_tree)? | 235 | .on::<req::SyntaxTree>(handlers::handle_syntax_tree)? |
@@ -262,7 +254,7 @@ fn on_request( | |||
262 | let inserted = pending_requests.insert(id, handle).is_none(); | 254 | let inserted = pending_requests.insert(id, handle).is_none(); |
263 | assert!(inserted, "duplicate request: {}", id); | 255 | assert!(inserted, "duplicate request: {}", id); |
264 | Ok(None) | 256 | Ok(None) |
265 | }, | 257 | } |
266 | Err(req) => Ok(Some(req)), | 258 | Err(req) => Ok(Some(req)), |
267 | } | 259 | } |
268 | } | 260 | } |
@@ -285,45 +277,53 @@ fn on_notification( | |||
285 | if let Some(handle) = pending_requests.remove(&id) { | 277 | if let Some(handle) = pending_requests.remove(&id) { |
286 | handle.cancel(); | 278 | handle.cancel(); |
287 | } | 279 | } |
288 | return Ok(()) | 280 | return Ok(()); |
289 | } | 281 | } |
290 | Err(not) => not, | 282 | Err(not) => not, |
291 | }; | 283 | }; |
292 | let not = match not.cast::<req::DidOpenTextDocument>() { | 284 | let not = match not.cast::<req::DidOpenTextDocument>() { |
293 | Ok(params) => { | 285 | Ok(params) => { |
294 | let uri = params.text_document.uri; | 286 | let uri = params.text_document.uri; |
295 | let path = uri.to_file_path() | 287 | let path = uri |
288 | .to_file_path() | ||
296 | .map_err(|()| format_err!("invalid uri: {}", uri))?; | 289 | .map_err(|()| format_err!("invalid uri: {}", uri))?; |
297 | let file_id = state.add_mem_file(path, params.text_document.text); | 290 | let file_id = state.add_mem_file(path, params.text_document.text); |
298 | subs.add_sub(file_id); | 291 | subs.add_sub(file_id); |
299 | return Ok(()) | 292 | return Ok(()); |
300 | } | 293 | } |
301 | Err(not) => not, | 294 | Err(not) => not, |
302 | }; | 295 | }; |
303 | let not = match not.cast::<req::DidChangeTextDocument>() { | 296 | let not = match not.cast::<req::DidChangeTextDocument>() { |
304 | Ok(mut params) => { | 297 | Ok(mut params) => { |
305 | let uri = params.text_document.uri; | 298 | let uri = params.text_document.uri; |
306 | let path = uri.to_file_path() | 299 | let path = uri |
300 | .to_file_path() | ||
307 | .map_err(|()| format_err!("invalid uri: {}", uri))?; | 301 | .map_err(|()| format_err!("invalid uri: {}", uri))?; |
308 | let text = params.content_changes.pop() | 302 | let text = params |
303 | .content_changes | ||
304 | .pop() | ||
309 | .ok_or_else(|| format_err!("empty changes"))? | 305 | .ok_or_else(|| format_err!("empty changes"))? |
310 | .text; | 306 | .text; |
311 | state.change_mem_file(path.as_path(), text)?; | 307 | state.change_mem_file(path.as_path(), text)?; |
312 | return Ok(()) | 308 | return Ok(()); |
313 | } | 309 | } |
314 | Err(not) => not, | 310 | Err(not) => not, |
315 | }; | 311 | }; |
316 | let not = match not.cast::<req::DidCloseTextDocument>() { | 312 | let not = match not.cast::<req::DidCloseTextDocument>() { |
317 | Ok(params) => { | 313 | Ok(params) => { |
318 | let uri = params.text_document.uri; | 314 | let uri = params.text_document.uri; |
319 | let path = uri.to_file_path() | 315 | let path = uri |
316 | .to_file_path() | ||
320 | .map_err(|()| format_err!("invalid uri: {}", uri))?; | 317 | .map_err(|()| format_err!("invalid uri: {}", uri))?; |
321 | let file_id = state.remove_mem_file(path.as_path())?; | 318 | let file_id = state.remove_mem_file(path.as_path())?; |
322 | subs.remove_sub(file_id); | 319 | subs.remove_sub(file_id); |
323 | let params = req::PublishDiagnosticsParams { uri, diagnostics: Vec::new() }; | 320 | let params = req::PublishDiagnosticsParams { |
321 | uri, | ||
322 | diagnostics: Vec::new(), | ||
323 | }; | ||
324 | let not = RawNotification::new::<req::PublishDiagnostics>(¶ms); | 324 | let not = RawNotification::new::<req::PublishDiagnostics>(¶ms); |
325 | msg_sender.send(RawMessage::Notification(not)); | 325 | msg_sender.send(RawMessage::Notification(not)); |
326 | return Ok(()) | 326 | return Ok(()); |
327 | } | 327 | } |
328 | Err(not) => not, | 328 | Err(not) => not, |
329 | }; | 329 | }; |
@@ -342,11 +342,12 @@ struct PoolDispatcher<'a> { | |||
342 | impl<'a> PoolDispatcher<'a> { | 342 | impl<'a> PoolDispatcher<'a> { |
343 | fn on<'b, R>( | 343 | fn on<'b, R>( |
344 | &'b mut self, | 344 | &'b mut self, |
345 | f: fn(ServerWorld, R::Params, JobToken) -> Result<R::Result> | 345 | f: fn(ServerWorld, R::Params, JobToken) -> Result<R::Result>, |
346 | ) -> Result<&'b mut Self> | 346 | ) -> Result<&'b mut Self> |
347 | where R: req::Request, | 347 | where |
348 | R::Params: DeserializeOwned + Send + 'static, | 348 | R: req::Request, |
349 | R::Result: Serialize + 'static, | 349 | R::Params: DeserializeOwned + Send + 'static, |
350 | R::Result: Serialize + 'static, | ||
350 | { | 351 | { |
351 | let req = match self.req.take() { | 352 | let req = match self.req.take() { |
352 | None => return Ok(self), | 353 | None => return Ok(self), |
@@ -360,16 +361,16 @@ impl<'a> PoolDispatcher<'a> { | |||
360 | self.pool.spawn(move || { | 361 | self.pool.spawn(move || { |
361 | let resp = match f(world, params, token) { | 362 | let resp = match f(world, params, token) { |
362 | Ok(resp) => RawResponse::ok::<R>(id, &resp), | 363 | Ok(resp) => RawResponse::ok::<R>(id, &resp), |
363 | Err(e) => RawResponse::err(id, ErrorCode::InternalError as i32, e.to_string()), | 364 | Err(e) => { |
365 | RawResponse::err(id, ErrorCode::InternalError as i32, e.to_string()) | ||
366 | } | ||
364 | }; | 367 | }; |
365 | let task = Task::Respond(resp); | 368 | let task = Task::Respond(resp); |
366 | sender.send(task); | 369 | sender.send(task); |
367 | }); | 370 | }); |
368 | self.res = Some((id, handle)); | 371 | self.res = Some((id, handle)); |
369 | } | 372 | } |
370 | Err(req) => { | 373 | Err(req) => self.req = Some(req), |
371 | self.req = Some(req) | ||
372 | } | ||
373 | } | 374 | } |
374 | Ok(self) | 375 | Ok(self) |
375 | } | 376 | } |
@@ -392,18 +393,14 @@ fn update_file_notifications_on_threadpool( | |||
392 | pool.spawn(move || { | 393 | pool.spawn(move || { |
393 | for file_id in subscriptions { | 394 | for file_id in subscriptions { |
394 | match handlers::publish_diagnostics(&world, file_id) { | 395 | match handlers::publish_diagnostics(&world, file_id) { |
395 | Err(e) => { | 396 | Err(e) => error!("failed to compute diagnostics: {:?}", e), |
396 | error!("failed to compute diagnostics: {:?}", e) | ||
397 | } | ||
398 | Ok(params) => { | 397 | Ok(params) => { |
399 | let not = RawNotification::new::<req::PublishDiagnostics>(¶ms); | 398 | let not = RawNotification::new::<req::PublishDiagnostics>(¶ms); |
400 | sender.send(Task::Notify(not)); | 399 | sender.send(Task::Notify(not)); |
401 | } | 400 | } |
402 | } | 401 | } |
403 | match handlers::publish_decorations(&world, file_id) { | 402 | match handlers::publish_decorations(&world, file_id) { |
404 | Err(e) => { | 403 | Err(e) => error!("failed to compute decorations: {:?}", e), |
405 | error!("failed to compute decorations: {:?}", e) | ||
406 | } | ||
407 | Ok(params) => { | 404 | Ok(params) => { |
408 | let not = RawNotification::new::<req::PublishDecorations>(¶ms); | 405 | let not = RawNotification::new::<req::PublishDecorations>(¶ms); |
409 | sender.send(Task::Notify(not)) | 406 | sender.send(Task::Notify(not)) |
diff --git a/crates/ra_lsp_server/src/main_loop/subscriptions.rs b/crates/ra_lsp_server/src/main_loop/subscriptions.rs index 310153382..03f41e870 100644 --- a/crates/ra_lsp_server/src/main_loop/subscriptions.rs +++ b/crates/ra_lsp_server/src/main_loop/subscriptions.rs | |||
@@ -1,5 +1,5 @@ | |||
1 | use rustc_hash::FxHashSet; | ||
2 | use ra_analysis::FileId; | 1 | use ra_analysis::FileId; |
2 | use rustc_hash::FxHashSet; | ||
3 | 3 | ||
4 | pub struct Subscriptions { | 4 | pub struct Subscriptions { |
5 | subs: FxHashSet<FileId>, | 5 | subs: FxHashSet<FileId>, |
@@ -7,7 +7,9 @@ pub struct Subscriptions { | |||
7 | 7 | ||
8 | impl Subscriptions { | 8 | impl Subscriptions { |
9 | pub fn new() -> Subscriptions { | 9 | pub fn new() -> Subscriptions { |
10 | Subscriptions { subs: FxHashSet::default() } | 10 | Subscriptions { |
11 | subs: FxHashSet::default(), | ||
12 | } | ||
11 | } | 13 | } |
12 | pub fn add_sub(&mut self, file_id: FileId) { | 14 | pub fn add_sub(&mut self, file_id: FileId) { |
13 | self.subs.insert(file_id); | 15 | self.subs.insert(file_id); |
diff --git a/crates/ra_lsp_server/src/path_map.rs b/crates/ra_lsp_server/src/path_map.rs index 19c3b1d3b..585013acd 100644 --- a/crates/ra_lsp_server/src/path_map.rs +++ b/crates/ra_lsp_server/src/path_map.rs | |||
@@ -1,11 +1,13 @@ | |||
1 | use std::path::{PathBuf, Path, Component}; | ||
2 | use im; | 1 | use im; |
3 | use relative_path::RelativePath; | ||
4 | use ra_analysis::{FileId, FileResolver}; | 2 | use ra_analysis::{FileId, FileResolver}; |
3 | use relative_path::RelativePath; | ||
4 | |||
5 | use std::path::{Component, Path, PathBuf}; | ||
5 | 6 | ||
6 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | 7 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
7 | pub enum Root { | 8 | pub enum Root { |
8 | Workspace, Lib | 9 | Workspace, |
10 | Lib, | ||
9 | } | 11 | } |
10 | 12 | ||
11 | #[derive(Debug, Default, Clone)] | 13 | #[derive(Debug, Default, Clone)] |
@@ -21,7 +23,8 @@ impl PathMap { | |||
21 | Default::default() | 23 | Default::default() |
22 | } | 24 | } |
23 | pub fn get_or_insert(&mut self, path: PathBuf, root: Root) -> FileId { | 25 | pub fn get_or_insert(&mut self, path: PathBuf, root: Root) -> FileId { |
24 | self.path2id.get(path.as_path()) | 26 | self.path2id |
27 | .get(path.as_path()) | ||
25 | .map(|&id| id) | 28 | .map(|&id| id) |
26 | .unwrap_or_else(|| { | 29 | .unwrap_or_else(|| { |
27 | let id = self.new_file_id(); | 30 | let id = self.new_file_id(); |
@@ -33,9 +36,7 @@ impl PathMap { | |||
33 | self.path2id.get(path).map(|&id| id) | 36 | self.path2id.get(path).map(|&id| id) |
34 | } | 37 | } |
35 | pub fn get_path(&self, file_id: FileId) -> &Path { | 38 | pub fn get_path(&self, file_id: FileId) -> &Path { |
36 | self.id2path.get(&file_id) | 39 | self.id2path.get(&file_id).unwrap().as_path() |
37 | .unwrap() | ||
38 | .as_path() | ||
39 | } | 40 | } |
40 | pub fn get_root(&self, file_id: FileId) -> Root { | 41 | pub fn get_root(&self, file_id: FileId) -> Root { |
41 | self.id2root[&file_id] | 42 | self.id2root[&file_id] |
@@ -55,7 +56,12 @@ impl PathMap { | |||
55 | 56 | ||
56 | impl FileResolver for PathMap { | 57 | impl FileResolver for PathMap { |
57 | fn file_stem(&self, file_id: FileId) -> String { | 58 | fn file_stem(&self, file_id: FileId) -> String { |
58 | self.get_path(file_id).file_stem().unwrap().to_str().unwrap().to_string() | 59 | self.get_path(file_id) |
60 | .file_stem() | ||
61 | .unwrap() | ||
62 | .to_str() | ||
63 | .unwrap() | ||
64 | .to_string() | ||
59 | } | 65 | } |
60 | 66 | ||
61 | fn resolve(&self, file_id: FileId, path: &RelativePath) -> Option<FileId> { | 67 | fn resolve(&self, file_id: FileId, path: &RelativePath) -> Option<FileId> { |
@@ -101,10 +107,6 @@ mod test { | |||
101 | let mut m = PathMap::new(); | 107 | let mut m = PathMap::new(); |
102 | let id1 = m.get_or_insert(PathBuf::from("/foo"), Root::Workspace); | 108 | let id1 = m.get_or_insert(PathBuf::from("/foo"), Root::Workspace); |
103 | let id2 = m.get_or_insert(PathBuf::from("/foo/bar.rs"), Root::Workspace); | 109 | let id2 = m.get_or_insert(PathBuf::from("/foo/bar.rs"), Root::Workspace); |
104 | assert_eq!( | 110 | assert_eq!(m.resolve(id1, &RelativePath::new("bar.rs")), Some(id2),) |
105 | m.resolve(id1, &RelativePath::new("bar.rs")), | ||
106 | Some(id2), | ||
107 | ) | ||
108 | } | 111 | } |
109 | } | 112 | } |
110 | |||
diff --git a/crates/ra_lsp_server/src/project_model.rs b/crates/ra_lsp_server/src/project_model.rs index c144d9596..d170ceb73 100644 --- a/crates/ra_lsp_server/src/project_model.rs +++ b/crates/ra_lsp_server/src/project_model.rs | |||
@@ -1,13 +1,12 @@ | |||
1 | use std::{ | ||
2 | path::{Path, PathBuf}, | ||
3 | }; | ||
4 | use rustc_hash::{FxHashMap, FxHashSet}; | ||
5 | use cargo_metadata::{metadata_run, CargoOpt}; | 1 | use cargo_metadata::{metadata_run, CargoOpt}; |
6 | use ra_syntax::SmolStr; | 2 | use ra_syntax::SmolStr; |
3 | use rustc_hash::{FxHashMap, FxHashSet}; | ||
4 | |||
5 | use std::path::{Path, PathBuf}; | ||
7 | 6 | ||
8 | use crate::{ | 7 | use crate::{ |
8 | thread_watcher::{ThreadWatcher, Worker}, | ||
9 | Result, | 9 | Result, |
10 | thread_watcher::{Worker, ThreadWatcher}, | ||
11 | }; | 10 | }; |
12 | 11 | ||
13 | #[derive(Debug, Clone)] | 12 | #[derive(Debug, Clone)] |
@@ -39,7 +38,12 @@ struct TargetData { | |||
39 | 38 | ||
40 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | 39 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
41 | pub enum TargetKind { | 40 | pub enum TargetKind { |
42 | Bin, Lib, Example, Test, Bench, Other, | 41 | Bin, |
42 | Lib, | ||
43 | Example, | ||
44 | Test, | ||
45 | Bench, | ||
46 | Other, | ||
43 | } | 47 | } |
44 | 48 | ||
45 | impl Package { | 49 | impl Package { |
@@ -49,7 +53,7 @@ impl Package { | |||
49 | pub fn root(self, ws: &CargoWorkspace) -> &Path { | 53 | pub fn root(self, ws: &CargoWorkspace) -> &Path { |
50 | ws.pkg(self).manifest.parent().unwrap() | 54 | ws.pkg(self).manifest.parent().unwrap() |
51 | } | 55 | } |
52 | pub fn targets<'a>(self, ws: &'a CargoWorkspace) -> impl Iterator<Item=Target> + 'a { | 56 | pub fn targets<'a>(self, ws: &'a CargoWorkspace) -> impl Iterator<Item = Target> + 'a { |
53 | ws.pkg(self).targets.iter().cloned() | 57 | ws.pkg(self).targets.iter().cloned() |
54 | } | 58 | } |
55 | pub fn is_member(self, ws: &CargoWorkspace) -> bool { | 59 | pub fn is_member(self, ws: &CargoWorkspace) -> bool { |
@@ -78,13 +82,15 @@ impl CargoWorkspace { | |||
78 | let meta = metadata_run( | 82 | let meta = metadata_run( |
79 | Some(cargo_toml.as_path()), | 83 | Some(cargo_toml.as_path()), |
80 | true, | 84 | true, |
81 | Some(CargoOpt::AllFeatures) | 85 | Some(CargoOpt::AllFeatures), |
82 | ).map_err(|e| format_err!("cargo metadata failed: {}", e))?; | 86 | ) |
87 | .map_err(|e| format_err!("cargo metadata failed: {}", e))?; | ||
83 | let mut pkg_by_id = FxHashMap::default(); | 88 | let mut pkg_by_id = FxHashMap::default(); |
84 | let mut packages = Vec::new(); | 89 | let mut packages = Vec::new(); |
85 | let mut targets = Vec::new(); | 90 | let mut targets = Vec::new(); |
86 | 91 | ||
87 | let ws_members: FxHashSet<String> = meta.workspace_members | 92 | let ws_members: FxHashSet<String> = meta |
93 | .workspace_members | ||
88 | .into_iter() | 94 | .into_iter() |
89 | .map(|it| it.raw) | 95 | .map(|it| it.raw) |
90 | .collect(); | 96 | .collect(); |
@@ -114,7 +120,7 @@ impl CargoWorkspace { | |||
114 | 120 | ||
115 | Ok(CargoWorkspace { packages, targets }) | 121 | Ok(CargoWorkspace { packages, targets }) |
116 | } | 122 | } |
117 | pub fn packages<'a>(&'a self) -> impl Iterator<Item=Package> + 'a { | 123 | pub fn packages<'a>(&'a self) -> impl Iterator<Item = Package> + 'a { |
118 | (0..self.packages.len()).map(Package) | 124 | (0..self.packages.len()).map(Package) |
119 | } | 125 | } |
120 | pub fn target_by_root(&self, root: &Path) -> Option<Target> { | 126 | pub fn target_by_root(&self, root: &Path) -> Option<Target> { |
@@ -155,7 +161,7 @@ impl TargetKind { | |||
155 | "example" => TargetKind::Example, | 161 | "example" => TargetKind::Example, |
156 | _ if kind.contains("lib") => TargetKind::Lib, | 162 | _ if kind.contains("lib") => TargetKind::Lib, |
157 | _ => continue, | 163 | _ => continue, |
158 | } | 164 | }; |
159 | } | 165 | } |
160 | TargetKind::Other | 166 | TargetKind::Other |
161 | } | 167 | } |
@@ -170,6 +176,6 @@ pub fn workspace_loader() -> (Worker<PathBuf, Result<CargoWorkspace>>, ThreadWat | |||
170 | .into_iter() | 176 | .into_iter() |
171 | .map(|path| CargoWorkspace::from_cargo_metadata(path.as_path())) | 177 | .map(|path| CargoWorkspace::from_cargo_metadata(path.as_path())) |
172 | .for_each(|it| output_sender.send(it)) | 178 | .for_each(|it| output_sender.send(it)) |
173 | } | 179 | }, |
174 | ) | 180 | ) |
175 | } | 181 | } |
diff --git a/crates/ra_lsp_server/src/req.rs b/crates/ra_lsp_server/src/req.rs index 1630edf7f..b76bfbcbc 100644 --- a/crates/ra_lsp_server/src/req.rs +++ b/crates/ra_lsp_server/src/req.rs | |||
@@ -1,20 +1,13 @@ | |||
1 | use languageserver_types::{Location, Position, Range, TextDocumentIdentifier, Url}; | ||
1 | use rustc_hash::FxHashMap; | 2 | use rustc_hash::FxHashMap; |
2 | use languageserver_types::{TextDocumentIdentifier, Range, Url, Position, Location}; | ||
3 | use url_serde; | 3 | use url_serde; |
4 | 4 | ||
5 | pub use languageserver_types::{ | 5 | pub use languageserver_types::{ |
6 | request::*, notification::*, | 6 | notification::*, request::*, ApplyWorkspaceEditParams, CodeActionParams, CompletionParams, |
7 | InitializeResult, PublishDiagnosticsParams, | 7 | CompletionResponse, DocumentOnTypeFormattingParams, DocumentSymbolParams, |
8 | DocumentSymbolParams, DocumentSymbolResponse, | 8 | DocumentSymbolResponse, ExecuteCommandParams, Hover, InitializeResult, |
9 | CodeActionParams, ApplyWorkspaceEditParams, | 9 | PublishDiagnosticsParams, SignatureHelp, TextDocumentEdit, TextDocumentPositionParams, |
10 | ExecuteCommandParams, | 10 | TextEdit, WorkspaceSymbolParams, |
11 | WorkspaceSymbolParams, | ||
12 | TextDocumentPositionParams, | ||
13 | TextEdit, | ||
14 | CompletionParams, CompletionResponse, | ||
15 | DocumentOnTypeFormattingParams, | ||
16 | TextDocumentEdit, | ||
17 | SignatureHelp, Hover | ||
18 | }; | 11 | }; |
19 | 12 | ||
20 | pub enum SyntaxTree {} | 13 | pub enum SyntaxTree {} |
@@ -28,7 +21,7 @@ impl Request for SyntaxTree { | |||
28 | #[derive(Deserialize, Debug)] | 21 | #[derive(Deserialize, Debug)] |
29 | #[serde(rename_all = "camelCase")] | 22 | #[serde(rename_all = "camelCase")] |
30 | pub struct SyntaxTreeParams { | 23 | pub struct SyntaxTreeParams { |
31 | pub text_document: TextDocumentIdentifier | 24 | pub text_document: TextDocumentIdentifier, |
32 | } | 25 | } |
33 | 26 | ||
34 | pub enum ExtendSelection {} | 27 | pub enum ExtendSelection {} |
@@ -94,7 +87,7 @@ pub struct PublishDecorationsParams { | |||
94 | #[serde(rename_all = "camelCase")] | 87 | #[serde(rename_all = "camelCase")] |
95 | pub struct Decoration { | 88 | pub struct Decoration { |
96 | pub range: Range, | 89 | pub range: Range, |
97 | pub tag: &'static str | 90 | pub tag: &'static str, |
98 | } | 91 | } |
99 | 92 | ||
100 | pub enum ParentModule {} | 93 | pub enum ParentModule {} |
@@ -167,14 +160,14 @@ pub struct SourceChange { | |||
167 | pub enum FileSystemEdit { | 160 | pub enum FileSystemEdit { |
168 | CreateFile { | 161 | CreateFile { |
169 | #[serde(with = "url_serde")] | 162 | #[serde(with = "url_serde")] |
170 | uri: Url | 163 | uri: Url, |
171 | }, | 164 | }, |
172 | MoveFile { | 165 | MoveFile { |
173 | #[serde(with = "url_serde")] | 166 | #[serde(with = "url_serde")] |
174 | src: Url, | 167 | src: Url, |
175 | #[serde(with = "url_serde")] | 168 | #[serde(with = "url_serde")] |
176 | dst: Url, | 169 | dst: Url, |
177 | } | 170 | }, |
178 | } | 171 | } |
179 | 172 | ||
180 | pub enum InternalFeedback {} | 173 | pub enum InternalFeedback {} |
diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs index 9b3013ae8..35ff65ea1 100644 --- a/crates/ra_lsp_server/src/server_world.rs +++ b/crates/ra_lsp_server/src/server_world.rs | |||
@@ -1,18 +1,18 @@ | |||
1 | use std::{ | 1 | use std::{ |
2 | fs, | 2 | fs, |
3 | path::{PathBuf, Path}, | 3 | path::{Path, PathBuf}, |
4 | sync::Arc, | 4 | sync::Arc, |
5 | }; | 5 | }; |
6 | 6 | ||
7 | use rustc_hash::FxHashMap; | ||
8 | use languageserver_types::Url; | 7 | use languageserver_types::Url; |
9 | use ra_analysis::{FileId, AnalysisHost, Analysis, CrateGraph, CrateId, LibraryData, FileResolver}; | 8 | use ra_analysis::{Analysis, AnalysisHost, CrateGraph, CrateId, FileId, FileResolver, LibraryData}; |
9 | use rustc_hash::FxHashMap; | ||
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | Result, | ||
13 | path_map::{PathMap, Root}, | 12 | path_map::{PathMap, Root}, |
14 | vfs::{FileEvent, FileEventKind}, | ||
15 | project_model::CargoWorkspace, | 13 | project_model::CargoWorkspace, |
14 | vfs::{FileEvent, FileEventKind}, | ||
15 | Result, | ||
16 | }; | 16 | }; |
17 | 17 | ||
18 | #[derive(Debug)] | 18 | #[derive(Debug)] |
@@ -42,16 +42,15 @@ impl ServerWorldState { | |||
42 | { | 42 | { |
43 | let pm = &mut self.path_map; | 43 | let pm = &mut self.path_map; |
44 | let mm = &mut self.mem_map; | 44 | let mm = &mut self.mem_map; |
45 | let changes = events.into_iter() | 45 | let changes = events |
46 | .into_iter() | ||
46 | .map(|event| { | 47 | .map(|event| { |
47 | let text = match event.kind { | 48 | let text = match event.kind { |
48 | FileEventKind::Add(text) => Some(text), | 49 | FileEventKind::Add(text) => Some(text), |
49 | }; | 50 | }; |
50 | (event.path, text) | 51 | (event.path, text) |
51 | }) | 52 | }) |
52 | .map(|(path, text)| { | 53 | .map(|(path, text)| (pm.get_or_insert(path, Root::Workspace), text)) |
53 | (pm.get_or_insert(path, Root::Workspace), text) | ||
54 | }) | ||
55 | .filter_map(|(id, text)| { | 54 | .filter_map(|(id, text)| { |
56 | if mm.contains_key(&id) { | 55 | if mm.contains_key(&id) { |
57 | mm.insert(id, text); | 56 | mm.insert(id, text); |
@@ -62,12 +61,17 @@ impl ServerWorldState { | |||
62 | }); | 61 | }); |
63 | self.analysis_host.change_files(changes); | 62 | self.analysis_host.change_files(changes); |
64 | } | 63 | } |
65 | self.analysis_host.set_file_resolver(Arc::new(self.path_map.clone())); | 64 | self.analysis_host |
65 | .set_file_resolver(Arc::new(self.path_map.clone())); | ||
66 | } | 66 | } |
67 | pub fn events_to_files(&mut self, events: Vec<FileEvent>) -> (Vec<(FileId, String)>, Arc<FileResolver>) { | 67 | pub fn events_to_files( |
68 | &mut self, | ||
69 | events: Vec<FileEvent>, | ||
70 | ) -> (Vec<(FileId, String)>, Arc<FileResolver>) { | ||
68 | let files = { | 71 | let files = { |
69 | let pm = &mut self.path_map; | 72 | let pm = &mut self.path_map; |
70 | events.into_iter() | 73 | events |
74 | .into_iter() | ||
71 | .map(|event| { | 75 | .map(|event| { |
72 | let text = match event.kind { | 76 | let text = match event.kind { |
73 | FileEventKind::Add(text) => text, | 77 | FileEventKind::Add(text) => text, |
@@ -86,7 +90,8 @@ impl ServerWorldState { | |||
86 | 90 | ||
87 | pub fn add_mem_file(&mut self, path: PathBuf, text: String) -> FileId { | 91 | pub fn add_mem_file(&mut self, path: PathBuf, text: String) -> FileId { |
88 | let file_id = self.path_map.get_or_insert(path, Root::Workspace); | 92 | let file_id = self.path_map.get_or_insert(path, Root::Workspace); |
89 | self.analysis_host.set_file_resolver(Arc::new(self.path_map.clone())); | 93 | self.analysis_host |
94 | .set_file_resolver(Arc::new(self.path_map.clone())); | ||
90 | self.mem_map.insert(file_id, None); | 95 | self.mem_map.insert(file_id, None); |
91 | if self.path_map.get_root(file_id) != Root::Lib { | 96 | if self.path_map.get_root(file_id) != Root::Lib { |
92 | self.analysis_host.change_file(file_id, Some(text)); | 97 | self.analysis_host.change_file(file_id, Some(text)); |
@@ -95,9 +100,10 @@ impl ServerWorldState { | |||
95 | } | 100 | } |
96 | 101 | ||
97 | pub fn change_mem_file(&mut self, path: &Path, text: String) -> Result<()> { | 102 | pub fn change_mem_file(&mut self, path: &Path, text: String) -> Result<()> { |
98 | let file_id = self.path_map.get_id(path).ok_or_else(|| { | 103 | let file_id = self |
99 | format_err!("change to unknown file: {}", path.display()) | 104 | .path_map |
100 | })?; | 105 | .get_id(path) |
106 | .ok_or_else(|| format_err!("change to unknown file: {}", path.display()))?; | ||
101 | if self.path_map.get_root(file_id) != Root::Lib { | 107 | if self.path_map.get_root(file_id) != Root::Lib { |
102 | self.analysis_host.change_file(file_id, Some(text)); | 108 | self.analysis_host.change_file(file_id, Some(text)); |
103 | } | 109 | } |
@@ -105,9 +111,10 @@ impl ServerWorldState { | |||
105 | } | 111 | } |
106 | 112 | ||
107 | pub fn remove_mem_file(&mut self, path: &Path) -> Result<FileId> { | 113 | pub fn remove_mem_file(&mut self, path: &Path) -> Result<FileId> { |
108 | let file_id = self.path_map.get_id(path).ok_or_else(|| { | 114 | let file_id = self |
109 | format_err!("change to unknown file: {}", path.display()) | 115 | .path_map |
110 | })?; | 116 | .get_id(path) |
117 | .ok_or_else(|| format_err!("change to unknown file: {}", path.display()))?; | ||
111 | match self.mem_map.remove(&file_id) { | 118 | match self.mem_map.remove(&file_id) { |
112 | Some(_) => (), | 119 | Some(_) => (), |
113 | None => bail!("unmatched close notification"), | 120 | None => bail!("unmatched close notification"), |
@@ -122,17 +129,17 @@ impl ServerWorldState { | |||
122 | pub fn set_workspaces(&mut self, ws: Vec<CargoWorkspace>) { | 129 | pub fn set_workspaces(&mut self, ws: Vec<CargoWorkspace>) { |
123 | let mut crate_roots = FxHashMap::default(); | 130 | let mut crate_roots = FxHashMap::default(); |
124 | ws.iter() | 131 | ws.iter() |
125 | .flat_map(|ws| { | 132 | .flat_map(|ws| { |
126 | ws.packages() | 133 | ws.packages() |
127 | .flat_map(move |pkg| pkg.targets(ws)) | 134 | .flat_map(move |pkg| pkg.targets(ws)) |
128 | .map(move |tgt| tgt.root(ws)) | 135 | .map(move |tgt| tgt.root(ws)) |
129 | }) | 136 | }) |
130 | .for_each(|root| { | 137 | .for_each(|root| { |
131 | if let Some(file_id) = self.path_map.get_id(root) { | 138 | if let Some(file_id) = self.path_map.get_id(root) { |
132 | let crate_id = CrateId(crate_roots.len() as u32); | 139 | let crate_id = CrateId(crate_roots.len() as u32); |
133 | crate_roots.insert(crate_id, file_id); | 140 | crate_roots.insert(crate_id, file_id); |
134 | } | 141 | } |
135 | }); | 142 | }); |
136 | let crate_graph = CrateGraph { crate_roots }; | 143 | let crate_graph = CrateGraph { crate_roots }; |
137 | self.workspaces = Arc::new(ws); | 144 | self.workspaces = Arc::new(ws); |
138 | self.analysis_host.set_crate_graph(crate_graph); | 145 | self.analysis_host.set_crate_graph(crate_graph); |
@@ -141,7 +148,7 @@ impl ServerWorldState { | |||
141 | ServerWorld { | 148 | ServerWorld { |
142 | workspaces: Arc::clone(&self.workspaces), | 149 | workspaces: Arc::clone(&self.workspaces), |
143 | analysis: self.analysis_host.analysis(), | 150 | analysis: self.analysis_host.analysis(), |
144 | path_map: self.path_map.clone() | 151 | path_map: self.path_map.clone(), |
145 | } | 152 | } |
146 | } | 153 | } |
147 | } | 154 | } |
@@ -152,9 +159,12 @@ impl ServerWorld { | |||
152 | } | 159 | } |
153 | 160 | ||
154 | pub fn uri_to_file_id(&self, uri: &Url) -> Result<FileId> { | 161 | pub fn uri_to_file_id(&self, uri: &Url) -> Result<FileId> { |
155 | let path = uri.to_file_path() | 162 | let path = uri |
163 | .to_file_path() | ||
156 | .map_err(|()| format_err!("invalid uri: {}", uri))?; | 164 | .map_err(|()| format_err!("invalid uri: {}", uri))?; |
157 | self.path_map.get_id(&path).ok_or_else(|| format_err!("unknown file: {}", path.display())) | 165 | self.path_map |
166 | .get_id(&path) | ||
167 | .ok_or_else(|| format_err!("unknown file: {}", path.display())) | ||
158 | } | 168 | } |
159 | 169 | ||
160 | pub fn file_id_to_uri(&self, id: FileId) -> Result<Url> { | 170 | pub fn file_id_to_uri(&self, id: FileId) -> Result<Url> { |
diff --git a/crates/ra_lsp_server/src/thread_watcher.rs b/crates/ra_lsp_server/src/thread_watcher.rs index 3257effcb..67952eb74 100644 --- a/crates/ra_lsp_server/src/thread_watcher.rs +++ b/crates/ra_lsp_server/src/thread_watcher.rs | |||
@@ -1,7 +1,8 @@ | |||
1 | use std::thread; | ||
2 | use crossbeam_channel::{bounded, unbounded, Sender, Receiver}; | ||
3 | use drop_bomb::DropBomb; | ||
4 | use crate::Result; | 1 | use crate::Result; |
2 | use crossbeam_channel::{bounded, unbounded, Receiver, Sender}; | ||
3 | use drop_bomb::DropBomb; | ||
4 | |||
5 | use std::thread; | ||
5 | 6 | ||
6 | pub struct Worker<I, O> { | 7 | pub struct Worker<I, O> { |
7 | pub inp: Sender<I>, | 8 | pub inp: Sender<I>, |
@@ -50,11 +51,13 @@ impl ThreadWatcher { | |||
50 | info!("waiting for {} to finish ...", self.name); | 51 | info!("waiting for {} to finish ...", self.name); |
51 | let name = self.name; | 52 | let name = self.name; |
52 | self.bomb.defuse(); | 53 | self.bomb.defuse(); |
53 | let res = self.thread.join() | 54 | let res = self |
55 | .thread | ||
56 | .join() | ||
54 | .map_err(|_| format_err!("ThreadWatcher {} died", name)); | 57 | .map_err(|_| format_err!("ThreadWatcher {} died", name)); |
55 | match &res { | 58 | match &res { |
56 | Ok(()) => info!("... {} terminated with ok", name), | 59 | Ok(()) => info!("... {} terminated with ok", name), |
57 | Err(_) => error!("... {} terminated with err", name) | 60 | Err(_) => error!("... {} terminated with err", name), |
58 | } | 61 | } |
59 | res | 62 | res |
60 | } | 63 | } |
@@ -66,5 +69,9 @@ impl ThreadWatcher { | |||
66 | fn worker_chan<I, O>(buf: usize) -> ((Sender<I>, Receiver<O>), Receiver<I>, Sender<O>) { | 69 | fn worker_chan<I, O>(buf: usize) -> ((Sender<I>, Receiver<O>), Receiver<I>, Sender<O>) { |
67 | let (input_sender, input_receiver) = bounded::<I>(buf); | 70 | let (input_sender, input_receiver) = bounded::<I>(buf); |
68 | let (output_sender, output_receiver) = unbounded::<O>(); | 71 | let (output_sender, output_receiver) = unbounded::<O>(); |
69 | ((input_sender, output_receiver), input_receiver, output_sender) | 72 | ( |
73 | (input_sender, output_receiver), | ||
74 | input_receiver, | ||
75 | output_sender, | ||
76 | ) | ||
70 | } | 77 | } |
diff --git a/crates/ra_lsp_server/src/vfs.rs b/crates/ra_lsp_server/src/vfs.rs index d8f9b1aac..417a3c19a 100644 --- a/crates/ra_lsp_server/src/vfs.rs +++ b/crates/ra_lsp_server/src/vfs.rs | |||
@@ -1,14 +1,11 @@ | |||
1 | use std::{ | 1 | use std::{ |
2 | path::{PathBuf, Path}, | ||
3 | fs, | 2 | fs, |
3 | path::{Path, PathBuf}, | ||
4 | }; | 4 | }; |
5 | 5 | ||
6 | use walkdir::WalkDir; | 6 | use walkdir::WalkDir; |
7 | 7 | ||
8 | use crate::{ | 8 | use crate::thread_watcher::{ThreadWatcher, Worker}; |
9 | thread_watcher::{Worker, ThreadWatcher}, | ||
10 | }; | ||
11 | |||
12 | 9 | ||
13 | #[derive(Debug)] | 10 | #[derive(Debug)] |
14 | pub struct FileEvent { | 11 | pub struct FileEvent { |
@@ -24,7 +21,8 @@ pub enum FileEventKind { | |||
24 | pub fn roots_loader() -> (Worker<PathBuf, (PathBuf, Vec<FileEvent>)>, ThreadWatcher) { | 21 | pub fn roots_loader() -> (Worker<PathBuf, (PathBuf, Vec<FileEvent>)>, ThreadWatcher) { |
25 | Worker::<PathBuf, (PathBuf, Vec<FileEvent>)>::spawn( | 22 | Worker::<PathBuf, (PathBuf, Vec<FileEvent>)>::spawn( |
26 | "roots loader", | 23 | "roots loader", |
27 | 128, |input_receiver, output_sender| { | 24 | 128, |
25 | |input_receiver, output_sender| { | ||
28 | input_receiver | 26 | input_receiver |
29 | .into_iter() | 27 | .into_iter() |
30 | .map(|path| { | 28 | .map(|path| { |
@@ -34,7 +32,7 @@ pub fn roots_loader() -> (Worker<PathBuf, (PathBuf, Vec<FileEvent>)>, ThreadWatc | |||
34 | (path, events) | 32 | (path, events) |
35 | }) | 33 | }) |
36 | .for_each(|it| output_sender.send(it)) | 34 | .for_each(|it| output_sender.send(it)) |
37 | } | 35 | }, |
38 | ) | 36 | ) |
39 | } | 37 | } |
40 | 38 | ||