diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-02-03 11:27:31 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2020-02-03 11:27:31 +0000 |
commit | d400fde66c7139aad04e5c5c9875a1d41ef5eae8 (patch) | |
tree | f86b6711bc6fb006d99b0be09bf17f0a9a79b3ec /crates/ra_lsp_server/src/main_loop | |
parent | 5b1b2cac39d88e730d594f951ab6613eab5ee498 (diff) | |
parent | 9f70f443a35bc12caf37e2548abf7987926c3875 (diff) |
Merge #2959
2959: Rework how we send diagnostics to client r=matklad a=kiljacken
The previous way of sending from the thread pool suffered from stale diagnostics due to being canceled before we could clear the old ones.
The key change is moving to sending diagnostics from the main loop thread, but doing all the hard work in the thread pool. This should provide the best of both worlds, with little to no of the downsides.
This should hopefully fix a lot of issues, but we'll need testing in each individual issue to be sure.
Co-authored-by: Emil Lauridsen <[email protected]>
Diffstat (limited to 'crates/ra_lsp_server/src/main_loop')
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/handlers.rs | 36 |
1 files changed, 7 insertions, 29 deletions
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 9aa1e7eea..282f6e8fc 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs | |||
@@ -33,6 +33,7 @@ use crate::{ | |||
33 | to_call_hierarchy_item, to_location, Conv, ConvWith, FoldConvCtx, MapConvWith, TryConvWith, | 33 | to_call_hierarchy_item, to_location, Conv, ConvWith, FoldConvCtx, MapConvWith, TryConvWith, |
34 | TryConvWithToVec, | 34 | TryConvWithToVec, |
35 | }, | 35 | }, |
36 | diagnostics::DiagnosticTask, | ||
36 | req::{self, Decoration, InlayHint, InlayHintsParams, InlayKind}, | 37 | req::{self, Decoration, InlayHint, InlayHintsParams, InlayKind}, |
37 | world::WorldSnapshot, | 38 | world::WorldSnapshot, |
38 | LspError, Result, | 39 | LspError, Result, |
@@ -676,28 +677,12 @@ pub fn handle_code_action( | |||
676 | res.push(action.into()); | 677 | res.push(action.into()); |
677 | } | 678 | } |
678 | 679 | ||
679 | for fix in world.check_watcher.fixes_for(¶ms.text_document.uri).into_iter().flatten() { | 680 | for fix in world.check_fixes.get(&file_id).into_iter().flatten() { |
680 | let fix_range = fix.location.range.conv_with(&line_index); | 681 | let fix_range = fix.range.conv_with(&line_index); |
681 | if fix_range.intersection(&range).is_none() { | 682 | if fix_range.intersection(&range).is_none() { |
682 | continue; | 683 | continue; |
683 | } | 684 | } |
684 | 685 | res.push(fix.action.clone()); | |
685 | let edit = { | ||
686 | let edits = vec![TextEdit::new(fix.location.range, fix.replacement.clone())]; | ||
687 | let mut edit_map = std::collections::HashMap::new(); | ||
688 | edit_map.insert(fix.location.uri.clone(), edits); | ||
689 | WorkspaceEdit::new(edit_map) | ||
690 | }; | ||
691 | |||
692 | let action = CodeAction { | ||
693 | title: fix.title.clone(), | ||
694 | kind: Some("quickfix".to_string()), | ||
695 | diagnostics: Some(fix.diagnostics.clone()), | ||
696 | edit: Some(edit), | ||
697 | command: None, | ||
698 | is_preferred: None, | ||
699 | }; | ||
700 | res.push(action.into()); | ||
701 | } | 686 | } |
702 | 687 | ||
703 | for assist in world.analysis().assists(FileRange { file_id, range })?.into_iter() { | 688 | for assist in world.analysis().assists(FileRange { file_id, range })?.into_iter() { |
@@ -875,14 +860,10 @@ pub fn handle_document_highlight( | |||
875 | )) | 860 | )) |
876 | } | 861 | } |
877 | 862 | ||
878 | pub fn publish_diagnostics( | 863 | pub fn publish_diagnostics(world: &WorldSnapshot, file_id: FileId) -> Result<DiagnosticTask> { |
879 | world: &WorldSnapshot, | ||
880 | file_id: FileId, | ||
881 | ) -> Result<req::PublishDiagnosticsParams> { | ||
882 | let _p = profile("publish_diagnostics"); | 864 | let _p = profile("publish_diagnostics"); |
883 | let uri = world.file_id_to_uri(file_id)?; | ||
884 | let line_index = world.analysis().file_line_index(file_id)?; | 865 | let line_index = world.analysis().file_line_index(file_id)?; |
885 | let mut diagnostics: Vec<Diagnostic> = world | 866 | let diagnostics: Vec<Diagnostic> = world |
886 | .analysis() | 867 | .analysis() |
887 | .diagnostics(file_id)? | 868 | .diagnostics(file_id)? |
888 | .into_iter() | 869 | .into_iter() |
@@ -896,10 +877,7 @@ pub fn publish_diagnostics( | |||
896 | tags: None, | 877 | tags: None, |
897 | }) | 878 | }) |
898 | .collect(); | 879 | .collect(); |
899 | if let Some(check_diags) = world.check_watcher.diagnostics_for(&uri) { | 880 | Ok(DiagnosticTask::SetNative(file_id, diagnostics)) |
900 | diagnostics.extend(check_diags.iter().cloned()); | ||
901 | } | ||
902 | Ok(req::PublishDiagnosticsParams { uri, diagnostics, version: None }) | ||
903 | } | 881 | } |
904 | 882 | ||
905 | pub fn publish_decorations( | 883 | pub fn publish_decorations( |