diff options
Diffstat (limited to 'crates/ra_lsp_server/src/main_loop')
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/handlers.rs | 74 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/pending_requests.rs | 72 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/subscriptions.rs | 12 |
3 files changed, 114 insertions, 44 deletions
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 0ebfd641d..6373240d5 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs | |||
@@ -24,22 +24,22 @@ use crate::{ | |||
24 | cargo_target_spec::{runnable_args, CargoTargetSpec}, | 24 | cargo_target_spec::{runnable_args, CargoTargetSpec}, |
25 | conv::{to_location, to_location_link, Conv, ConvWith, MapConvWith, TryConvWith}, | 25 | conv::{to_location, to_location_link, Conv, ConvWith, MapConvWith, TryConvWith}, |
26 | req::{self, Decoration}, | 26 | req::{self, Decoration}, |
27 | server_world::ServerWorld, | 27 | world::WorldSnapshot, |
28 | LspError, Result, | 28 | LspError, Result, |
29 | }; | 29 | }; |
30 | 30 | ||
31 | pub fn handle_analyzer_status(world: ServerWorld, _: ()) -> Result<String> { | 31 | pub fn handle_analyzer_status(world: WorldSnapshot, _: ()) -> Result<String> { |
32 | let mut buf = world.status(); | 32 | let mut buf = world.status(); |
33 | writeln!(buf, "\n\nrequests:").unwrap(); | 33 | writeln!(buf, "\n\nrequests:").unwrap(); |
34 | let requests = world.latest_completed_requests.read(); | 34 | let requests = world.latest_requests.read(); |
35 | for (idx, r) in requests.iter().enumerate() { | 35 | for (is_last, r) in requests.iter() { |
36 | let current = if idx == world.request_idx { "*" } else { " " }; | 36 | let mark = if is_last { "*" } else { " " }; |
37 | writeln!(buf, "{:4}{}{:<36}{}ms", r.id, current, r.method, r.duration.as_millis()).unwrap(); | 37 | writeln!(buf, "{}{:4} {:<36}{}ms", mark, r.id, r.method, r.duration.as_millis()).unwrap(); |
38 | } | 38 | } |
39 | Ok(buf) | 39 | Ok(buf) |
40 | } | 40 | } |
41 | 41 | ||
42 | pub fn handle_syntax_tree(world: ServerWorld, params: req::SyntaxTreeParams) -> Result<String> { | 42 | pub fn handle_syntax_tree(world: WorldSnapshot, params: req::SyntaxTreeParams) -> Result<String> { |
43 | let id = params.text_document.try_conv_with(&world)?; | 43 | let id = params.text_document.try_conv_with(&world)?; |
44 | let line_index = world.analysis().file_line_index(id); | 44 | let line_index = world.analysis().file_line_index(id); |
45 | let text_range = params.range.map(|p| p.conv_with(&line_index)); | 45 | let text_range = params.range.map(|p| p.conv_with(&line_index)); |
@@ -49,7 +49,7 @@ pub fn handle_syntax_tree(world: ServerWorld, params: req::SyntaxTreeParams) -> | |||
49 | 49 | ||
50 | // FIXME: drop this API | 50 | // FIXME: drop this API |
51 | pub fn handle_extend_selection( | 51 | pub fn handle_extend_selection( |
52 | world: ServerWorld, | 52 | world: WorldSnapshot, |
53 | params: req::ExtendSelectionParams, | 53 | params: req::ExtendSelectionParams, |
54 | ) -> Result<req::ExtendSelectionResult> { | 54 | ) -> Result<req::ExtendSelectionResult> { |
55 | log::error!( | 55 | log::error!( |
@@ -69,7 +69,7 @@ pub fn handle_extend_selection( | |||
69 | } | 69 | } |
70 | 70 | ||
71 | pub fn handle_selection_range( | 71 | pub fn handle_selection_range( |
72 | world: ServerWorld, | 72 | world: WorldSnapshot, |
73 | params: req::SelectionRangeParams, | 73 | params: req::SelectionRangeParams, |
74 | ) -> Result<Vec<req::SelectionRange>> { | 74 | ) -> Result<Vec<req::SelectionRange>> { |
75 | let _p = profile("handle_selection_range"); | 75 | let _p = profile("handle_selection_range"); |
@@ -110,7 +110,7 @@ pub fn handle_selection_range( | |||
110 | } | 110 | } |
111 | 111 | ||
112 | pub fn handle_find_matching_brace( | 112 | pub fn handle_find_matching_brace( |
113 | world: ServerWorld, | 113 | world: WorldSnapshot, |
114 | params: req::FindMatchingBraceParams, | 114 | params: req::FindMatchingBraceParams, |
115 | ) -> Result<Vec<Position>> { | 115 | ) -> Result<Vec<Position>> { |
116 | let _p = profile("handle_find_matching_brace"); | 116 | let _p = profile("handle_find_matching_brace"); |
@@ -129,7 +129,7 @@ pub fn handle_find_matching_brace( | |||
129 | } | 129 | } |
130 | 130 | ||
131 | pub fn handle_join_lines( | 131 | pub fn handle_join_lines( |
132 | world: ServerWorld, | 132 | world: WorldSnapshot, |
133 | params: req::JoinLinesParams, | 133 | params: req::JoinLinesParams, |
134 | ) -> Result<req::SourceChange> { | 134 | ) -> Result<req::SourceChange> { |
135 | let _p = profile("handle_join_lines"); | 135 | let _p = profile("handle_join_lines"); |
@@ -138,7 +138,7 @@ pub fn handle_join_lines( | |||
138 | } | 138 | } |
139 | 139 | ||
140 | pub fn handle_on_enter( | 140 | pub fn handle_on_enter( |
141 | world: ServerWorld, | 141 | world: WorldSnapshot, |
142 | params: req::TextDocumentPositionParams, | 142 | params: req::TextDocumentPositionParams, |
143 | ) -> Result<Option<req::SourceChange>> { | 143 | ) -> Result<Option<req::SourceChange>> { |
144 | let _p = profile("handle_on_enter"); | 144 | let _p = profile("handle_on_enter"); |
@@ -150,7 +150,7 @@ pub fn handle_on_enter( | |||
150 | } | 150 | } |
151 | 151 | ||
152 | pub fn handle_on_type_formatting( | 152 | pub fn handle_on_type_formatting( |
153 | world: ServerWorld, | 153 | world: WorldSnapshot, |
154 | params: req::DocumentOnTypeFormattingParams, | 154 | params: req::DocumentOnTypeFormattingParams, |
155 | ) -> Result<Option<Vec<TextEdit>>> { | 155 | ) -> Result<Option<Vec<TextEdit>>> { |
156 | let _p = profile("handle_on_type_formatting"); | 156 | let _p = profile("handle_on_type_formatting"); |
@@ -181,7 +181,7 @@ pub fn handle_on_type_formatting( | |||
181 | } | 181 | } |
182 | 182 | ||
183 | pub fn handle_document_symbol( | 183 | pub fn handle_document_symbol( |
184 | world: ServerWorld, | 184 | world: WorldSnapshot, |
185 | params: req::DocumentSymbolParams, | 185 | params: req::DocumentSymbolParams, |
186 | ) -> Result<Option<req::DocumentSymbolResponse>> { | 186 | ) -> Result<Option<req::DocumentSymbolResponse>> { |
187 | let file_id = params.text_document.try_conv_with(&world)?; | 187 | let file_id = params.text_document.try_conv_with(&world)?; |
@@ -219,7 +219,7 @@ pub fn handle_document_symbol( | |||
219 | } | 219 | } |
220 | 220 | ||
221 | pub fn handle_workspace_symbol( | 221 | pub fn handle_workspace_symbol( |
222 | world: ServerWorld, | 222 | world: WorldSnapshot, |
223 | params: req::WorkspaceSymbolParams, | 223 | params: req::WorkspaceSymbolParams, |
224 | ) -> Result<Option<Vec<SymbolInformation>>> { | 224 | ) -> Result<Option<Vec<SymbolInformation>>> { |
225 | let all_symbols = params.query.contains('#'); | 225 | let all_symbols = params.query.contains('#'); |
@@ -245,7 +245,7 @@ pub fn handle_workspace_symbol( | |||
245 | 245 | ||
246 | return Ok(Some(res)); | 246 | return Ok(Some(res)); |
247 | 247 | ||
248 | fn exec_query(world: &ServerWorld, query: Query) -> Result<Vec<SymbolInformation>> { | 248 | fn exec_query(world: &WorldSnapshot, query: Query) -> Result<Vec<SymbolInformation>> { |
249 | let mut res = Vec::new(); | 249 | let mut res = Vec::new(); |
250 | for nav in world.analysis().symbol_search(query)? { | 250 | for nav in world.analysis().symbol_search(query)? { |
251 | let info = SymbolInformation { | 251 | let info = SymbolInformation { |
@@ -262,7 +262,7 @@ pub fn handle_workspace_symbol( | |||
262 | } | 262 | } |
263 | 263 | ||
264 | pub fn handle_goto_definition( | 264 | pub fn handle_goto_definition( |
265 | world: ServerWorld, | 265 | world: WorldSnapshot, |
266 | params: req::TextDocumentPositionParams, | 266 | params: req::TextDocumentPositionParams, |
267 | ) -> Result<Option<req::GotoDefinitionResponse>> { | 267 | ) -> Result<Option<req::GotoDefinitionResponse>> { |
268 | let position = params.try_conv_with(&world)?; | 268 | let position = params.try_conv_with(&world)?; |
@@ -282,7 +282,7 @@ pub fn handle_goto_definition( | |||
282 | } | 282 | } |
283 | 283 | ||
284 | pub fn handle_goto_implementation( | 284 | pub fn handle_goto_implementation( |
285 | world: ServerWorld, | 285 | world: WorldSnapshot, |
286 | params: req::TextDocumentPositionParams, | 286 | params: req::TextDocumentPositionParams, |
287 | ) -> Result<Option<req::GotoImplementationResponse>> { | 287 | ) -> Result<Option<req::GotoImplementationResponse>> { |
288 | let position = params.try_conv_with(&world)?; | 288 | let position = params.try_conv_with(&world)?; |
@@ -302,7 +302,7 @@ pub fn handle_goto_implementation( | |||
302 | } | 302 | } |
303 | 303 | ||
304 | pub fn handle_goto_type_definition( | 304 | pub fn handle_goto_type_definition( |
305 | world: ServerWorld, | 305 | world: WorldSnapshot, |
306 | params: req::TextDocumentPositionParams, | 306 | params: req::TextDocumentPositionParams, |
307 | ) -> Result<Option<req::GotoTypeDefinitionResponse>> { | 307 | ) -> Result<Option<req::GotoTypeDefinitionResponse>> { |
308 | let position = params.try_conv_with(&world)?; | 308 | let position = params.try_conv_with(&world)?; |
@@ -322,7 +322,7 @@ pub fn handle_goto_type_definition( | |||
322 | } | 322 | } |
323 | 323 | ||
324 | pub fn handle_parent_module( | 324 | pub fn handle_parent_module( |
325 | world: ServerWorld, | 325 | world: WorldSnapshot, |
326 | params: req::TextDocumentPositionParams, | 326 | params: req::TextDocumentPositionParams, |
327 | ) -> Result<Vec<Location>> { | 327 | ) -> Result<Vec<Location>> { |
328 | let position = params.try_conv_with(&world)?; | 328 | let position = params.try_conv_with(&world)?; |
@@ -335,7 +335,7 @@ pub fn handle_parent_module( | |||
335 | } | 335 | } |
336 | 336 | ||
337 | pub fn handle_runnables( | 337 | pub fn handle_runnables( |
338 | world: ServerWorld, | 338 | world: WorldSnapshot, |
339 | params: req::RunnablesParams, | 339 | params: req::RunnablesParams, |
340 | ) -> Result<Vec<req::Runnable>> { | 340 | ) -> Result<Vec<req::Runnable>> { |
341 | let file_id = params.text_document.try_conv_with(&world)?; | 341 | let file_id = params.text_document.try_conv_with(&world)?; |
@@ -396,7 +396,7 @@ pub fn handle_runnables( | |||
396 | } | 396 | } |
397 | 397 | ||
398 | pub fn handle_decorations( | 398 | pub fn handle_decorations( |
399 | world: ServerWorld, | 399 | world: WorldSnapshot, |
400 | params: TextDocumentIdentifier, | 400 | params: TextDocumentIdentifier, |
401 | ) -> Result<Vec<Decoration>> { | 401 | ) -> Result<Vec<Decoration>> { |
402 | let file_id = params.try_conv_with(&world)?; | 402 | let file_id = params.try_conv_with(&world)?; |
@@ -404,7 +404,7 @@ pub fn handle_decorations( | |||
404 | } | 404 | } |
405 | 405 | ||
406 | pub fn handle_completion( | 406 | pub fn handle_completion( |
407 | world: ServerWorld, | 407 | world: WorldSnapshot, |
408 | params: req::CompletionParams, | 408 | params: req::CompletionParams, |
409 | ) -> Result<Option<req::CompletionResponse>> { | 409 | ) -> Result<Option<req::CompletionResponse>> { |
410 | let _p = profile("handle_completion"); | 410 | let _p = profile("handle_completion"); |
@@ -447,7 +447,7 @@ pub fn handle_completion( | |||
447 | } | 447 | } |
448 | 448 | ||
449 | pub fn handle_folding_range( | 449 | pub fn handle_folding_range( |
450 | world: ServerWorld, | 450 | world: WorldSnapshot, |
451 | params: FoldingRangeParams, | 451 | params: FoldingRangeParams, |
452 | ) -> Result<Option<Vec<FoldingRange>>> { | 452 | ) -> Result<Option<Vec<FoldingRange>>> { |
453 | let file_id = params.text_document.try_conv_with(&world)?; | 453 | let file_id = params.text_document.try_conv_with(&world)?; |
@@ -481,7 +481,7 @@ pub fn handle_folding_range( | |||
481 | } | 481 | } |
482 | 482 | ||
483 | pub fn handle_signature_help( | 483 | pub fn handle_signature_help( |
484 | world: ServerWorld, | 484 | world: WorldSnapshot, |
485 | params: req::TextDocumentPositionParams, | 485 | params: req::TextDocumentPositionParams, |
486 | ) -> Result<Option<req::SignatureHelp>> { | 486 | ) -> Result<Option<req::SignatureHelp>> { |
487 | let position = params.try_conv_with(&world)?; | 487 | let position = params.try_conv_with(&world)?; |
@@ -500,7 +500,7 @@ pub fn handle_signature_help( | |||
500 | } | 500 | } |
501 | 501 | ||
502 | pub fn handle_hover( | 502 | pub fn handle_hover( |
503 | world: ServerWorld, | 503 | world: WorldSnapshot, |
504 | params: req::TextDocumentPositionParams, | 504 | params: req::TextDocumentPositionParams, |
505 | ) -> Result<Option<Hover>> { | 505 | ) -> Result<Option<Hover>> { |
506 | let position = params.try_conv_with(&world)?; | 506 | let position = params.try_conv_with(&world)?; |
@@ -522,7 +522,7 @@ pub fn handle_hover( | |||
522 | 522 | ||
523 | /// Test doc comment | 523 | /// Test doc comment |
524 | pub fn handle_prepare_rename( | 524 | pub fn handle_prepare_rename( |
525 | world: ServerWorld, | 525 | world: WorldSnapshot, |
526 | params: req::TextDocumentPositionParams, | 526 | params: req::TextDocumentPositionParams, |
527 | ) -> Result<Option<PrepareRenameResponse>> { | 527 | ) -> Result<Option<PrepareRenameResponse>> { |
528 | let position = params.try_conv_with(&world)?; | 528 | let position = params.try_conv_with(&world)?; |
@@ -543,7 +543,7 @@ pub fn handle_prepare_rename( | |||
543 | Ok(Some(PrepareRenameResponse::Range(loc.range))) | 543 | Ok(Some(PrepareRenameResponse::Range(loc.range))) |
544 | } | 544 | } |
545 | 545 | ||
546 | pub fn handle_rename(world: ServerWorld, params: RenameParams) -> Result<Option<WorkspaceEdit>> { | 546 | pub fn handle_rename(world: WorldSnapshot, params: RenameParams) -> Result<Option<WorkspaceEdit>> { |
547 | let file_id = params.text_document.try_conv_with(&world)?; | 547 | let file_id = params.text_document.try_conv_with(&world)?; |
548 | let line_index = world.analysis().file_line_index(file_id); | 548 | let line_index = world.analysis().file_line_index(file_id); |
549 | let offset = params.position.conv_with(&line_index); | 549 | let offset = params.position.conv_with(&line_index); |
@@ -569,7 +569,7 @@ pub fn handle_rename(world: ServerWorld, params: RenameParams) -> Result<Option< | |||
569 | } | 569 | } |
570 | 570 | ||
571 | pub fn handle_references( | 571 | pub fn handle_references( |
572 | world: ServerWorld, | 572 | world: WorldSnapshot, |
573 | params: req::ReferenceParams, | 573 | params: req::ReferenceParams, |
574 | ) -> Result<Option<Vec<Location>>> { | 574 | ) -> Result<Option<Vec<Location>>> { |
575 | let file_id = params.text_document.try_conv_with(&world)?; | 575 | let file_id = params.text_document.try_conv_with(&world)?; |
@@ -597,7 +597,7 @@ pub fn handle_references( | |||
597 | } | 597 | } |
598 | 598 | ||
599 | pub fn handle_formatting( | 599 | pub fn handle_formatting( |
600 | world: ServerWorld, | 600 | world: WorldSnapshot, |
601 | params: DocumentFormattingParams, | 601 | params: DocumentFormattingParams, |
602 | ) -> Result<Option<Vec<TextEdit>>> { | 602 | ) -> Result<Option<Vec<TextEdit>>> { |
603 | let file_id = params.text_document.try_conv_with(&world)?; | 603 | let file_id = params.text_document.try_conv_with(&world)?; |
@@ -641,7 +641,7 @@ pub fn handle_formatting( | |||
641 | } | 641 | } |
642 | 642 | ||
643 | pub fn handle_code_action( | 643 | pub fn handle_code_action( |
644 | world: ServerWorld, | 644 | world: WorldSnapshot, |
645 | params: req::CodeActionParams, | 645 | params: req::CodeActionParams, |
646 | ) -> Result<Option<CodeActionResponse>> { | 646 | ) -> Result<Option<CodeActionResponse>> { |
647 | let _p = profile("handle_code_action"); | 647 | let _p = profile("handle_code_action"); |
@@ -704,7 +704,7 @@ pub fn handle_code_action( | |||
704 | } | 704 | } |
705 | 705 | ||
706 | pub fn handle_code_lens( | 706 | pub fn handle_code_lens( |
707 | world: ServerWorld, | 707 | world: WorldSnapshot, |
708 | params: req::CodeLensParams, | 708 | params: req::CodeLensParams, |
709 | ) -> Result<Option<Vec<CodeLens>>> { | 709 | ) -> Result<Option<Vec<CodeLens>>> { |
710 | let file_id = params.text_document.try_conv_with(&world)?; | 710 | let file_id = params.text_document.try_conv_with(&world)?; |
@@ -781,7 +781,7 @@ enum CodeLensResolveData { | |||
781 | Impls(req::TextDocumentPositionParams), | 781 | Impls(req::TextDocumentPositionParams), |
782 | } | 782 | } |
783 | 783 | ||
784 | pub fn handle_code_lens_resolve(world: ServerWorld, code_lens: CodeLens) -> Result<CodeLens> { | 784 | pub fn handle_code_lens_resolve(world: WorldSnapshot, code_lens: CodeLens) -> Result<CodeLens> { |
785 | let data = code_lens.data.unwrap(); | 785 | let data = code_lens.data.unwrap(); |
786 | let resolve = serde_json::from_value(data)?; | 786 | let resolve = serde_json::from_value(data)?; |
787 | match resolve { | 787 | match resolve { |
@@ -826,7 +826,7 @@ pub fn handle_code_lens_resolve(world: ServerWorld, code_lens: CodeLens) -> Resu | |||
826 | } | 826 | } |
827 | 827 | ||
828 | pub fn handle_document_highlight( | 828 | pub fn handle_document_highlight( |
829 | world: ServerWorld, | 829 | world: WorldSnapshot, |
830 | params: req::TextDocumentPositionParams, | 830 | params: req::TextDocumentPositionParams, |
831 | ) -> Result<Option<Vec<DocumentHighlight>>> { | 831 | ) -> Result<Option<Vec<DocumentHighlight>>> { |
832 | let file_id = params.text_document.try_conv_with(&world)?; | 832 | let file_id = params.text_document.try_conv_with(&world)?; |
@@ -845,7 +845,7 @@ pub fn handle_document_highlight( | |||
845 | } | 845 | } |
846 | 846 | ||
847 | pub fn publish_diagnostics( | 847 | pub fn publish_diagnostics( |
848 | world: &ServerWorld, | 848 | world: &WorldSnapshot, |
849 | file_id: FileId, | 849 | file_id: FileId, |
850 | ) -> Result<req::PublishDiagnosticsParams> { | 850 | ) -> Result<req::PublishDiagnosticsParams> { |
851 | let uri = world.file_id_to_uri(file_id)?; | 851 | let uri = world.file_id_to_uri(file_id)?; |
@@ -867,14 +867,14 @@ pub fn publish_diagnostics( | |||
867 | } | 867 | } |
868 | 868 | ||
869 | pub fn publish_decorations( | 869 | pub fn publish_decorations( |
870 | world: &ServerWorld, | 870 | world: &WorldSnapshot, |
871 | file_id: FileId, | 871 | file_id: FileId, |
872 | ) -> Result<req::PublishDecorationsParams> { | 872 | ) -> Result<req::PublishDecorationsParams> { |
873 | let uri = world.file_id_to_uri(file_id)?; | 873 | let uri = world.file_id_to_uri(file_id)?; |
874 | Ok(req::PublishDecorationsParams { uri, decorations: highlight(&world, file_id)? }) | 874 | Ok(req::PublishDecorationsParams { uri, decorations: highlight(&world, file_id)? }) |
875 | } | 875 | } |
876 | 876 | ||
877 | fn highlight(world: &ServerWorld, file_id: FileId) -> Result<Vec<Decoration>> { | 877 | fn highlight(world: &WorldSnapshot, file_id: FileId) -> Result<Vec<Decoration>> { |
878 | let line_index = world.analysis().file_line_index(file_id); | 878 | let line_index = world.analysis().file_line_index(file_id); |
879 | let res = world | 879 | let res = world |
880 | .analysis() | 880 | .analysis() |
diff --git a/crates/ra_lsp_server/src/main_loop/pending_requests.rs b/crates/ra_lsp_server/src/main_loop/pending_requests.rs new file mode 100644 index 000000000..741770e45 --- /dev/null +++ b/crates/ra_lsp_server/src/main_loop/pending_requests.rs | |||
@@ -0,0 +1,72 @@ | |||
1 | use std::time::{Duration, Instant}; | ||
2 | |||
3 | use rustc_hash::FxHashMap; | ||
4 | |||
5 | #[derive(Debug)] | ||
6 | pub struct CompletedRequest { | ||
7 | pub id: u64, | ||
8 | pub method: String, | ||
9 | pub duration: Duration, | ||
10 | } | ||
11 | |||
12 | #[derive(Debug)] | ||
13 | pub(crate) struct PendingRequest { | ||
14 | pub(crate) id: u64, | ||
15 | pub(crate) method: String, | ||
16 | pub(crate) received: Instant, | ||
17 | } | ||
18 | |||
19 | impl From<PendingRequest> for CompletedRequest { | ||
20 | fn from(pending: PendingRequest) -> CompletedRequest { | ||
21 | CompletedRequest { | ||
22 | id: pending.id, | ||
23 | method: pending.method, | ||
24 | duration: pending.received.elapsed(), | ||
25 | } | ||
26 | } | ||
27 | } | ||
28 | |||
29 | #[derive(Debug, Default)] | ||
30 | pub(crate) struct PendingRequests { | ||
31 | map: FxHashMap<u64, PendingRequest>, | ||
32 | } | ||
33 | |||
34 | impl PendingRequests { | ||
35 | pub(crate) fn start(&mut self, request: PendingRequest) { | ||
36 | let id = request.id; | ||
37 | let prev = self.map.insert(id, request); | ||
38 | assert!(prev.is_none(), "duplicate request with id {}", id); | ||
39 | } | ||
40 | pub(crate) fn cancel(&mut self, id: u64) -> bool { | ||
41 | self.map.remove(&id).is_some() | ||
42 | } | ||
43 | pub(crate) fn finish(&mut self, id: u64) -> Option<CompletedRequest> { | ||
44 | self.map.remove(&id).map(CompletedRequest::from) | ||
45 | } | ||
46 | } | ||
47 | |||
48 | const N_COMPLETED_REQUESTS: usize = 10; | ||
49 | |||
50 | #[derive(Debug, Default)] | ||
51 | pub struct LatestRequests { | ||
52 | // hand-rolling VecDeque here to print things in a nicer way | ||
53 | buf: [Option<CompletedRequest>; N_COMPLETED_REQUESTS], | ||
54 | idx: usize, | ||
55 | } | ||
56 | |||
57 | impl LatestRequests { | ||
58 | pub(crate) fn record(&mut self, request: CompletedRequest) { | ||
59 | // special case: don't track status request itself | ||
60 | if request.method == "rust-analyzer/analyzerStatus" { | ||
61 | return; | ||
62 | } | ||
63 | let idx = self.idx; | ||
64 | self.buf[idx] = Some(request); | ||
65 | self.idx = (idx + 1) % N_COMPLETED_REQUESTS; | ||
66 | } | ||
67 | |||
68 | pub(crate) fn iter(&self) -> impl Iterator<Item = (bool, &CompletedRequest)> { | ||
69 | let idx = self.idx; | ||
70 | self.buf.iter().enumerate().filter_map(move |(i, req)| Some((i == idx, req.as_ref()?))) | ||
71 | } | ||
72 | } | ||
diff --git a/crates/ra_lsp_server/src/main_loop/subscriptions.rs b/crates/ra_lsp_server/src/main_loop/subscriptions.rs index 11bd952d9..470bc1205 100644 --- a/crates/ra_lsp_server/src/main_loop/subscriptions.rs +++ b/crates/ra_lsp_server/src/main_loop/subscriptions.rs | |||
@@ -1,21 +1,19 @@ | |||
1 | use ra_ide_api::FileId; | 1 | use ra_ide_api::FileId; |
2 | use rustc_hash::FxHashSet; | 2 | use rustc_hash::FxHashSet; |
3 | 3 | ||
4 | pub struct Subscriptions { | 4 | #[derive(Default)] |
5 | pub(crate) struct Subscriptions { | ||
5 | subs: FxHashSet<FileId>, | 6 | subs: FxHashSet<FileId>, |
6 | } | 7 | } |
7 | 8 | ||
8 | impl Subscriptions { | 9 | impl Subscriptions { |
9 | pub fn new() -> Subscriptions { | 10 | pub(crate) fn add_sub(&mut self, file_id: FileId) { |
10 | Subscriptions { subs: FxHashSet::default() } | ||
11 | } | ||
12 | pub fn add_sub(&mut self, file_id: FileId) { | ||
13 | self.subs.insert(file_id); | 11 | self.subs.insert(file_id); |
14 | } | 12 | } |
15 | pub fn remove_sub(&mut self, file_id: FileId) { | 13 | pub(crate) fn remove_sub(&mut self, file_id: FileId) { |
16 | self.subs.remove(&file_id); | 14 | self.subs.remove(&file_id); |
17 | } | 15 | } |
18 | pub fn subscriptions(&self) -> Vec<FileId> { | 16 | pub(crate) fn subscriptions(&self) -> Vec<FileId> { |
19 | self.subs.iter().cloned().collect() | 17 | self.subs.iter().cloned().collect() |
20 | } | 18 | } |
21 | } | 19 | } |