diff options
author | Aleksey Kladov <[email protected]> | 2020-02-18 11:37:45 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2020-02-18 11:37:45 +0000 |
commit | 865759925be6b72f7ef39124ed0e4c86c0412a69 (patch) | |
tree | 0fc36373073a66c2bbd6c7cfae6cb734527d847f /crates/rust-analyzer/src/diagnostics.rs | |
parent | c855e36696afa54260773a6bc8a358df67d60dea (diff) |
Rename folder
Diffstat (limited to 'crates/rust-analyzer/src/diagnostics.rs')
-rw-r--r-- | crates/rust-analyzer/src/diagnostics.rs | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/crates/rust-analyzer/src/diagnostics.rs b/crates/rust-analyzer/src/diagnostics.rs new file mode 100644 index 000000000..e7924f0a3 --- /dev/null +++ b/crates/rust-analyzer/src/diagnostics.rs | |||
@@ -0,0 +1,87 @@ | |||
1 | //! Book keeping for keeping diagnostics easily in sync with the client. | ||
2 | |||
3 | use std::{collections::HashMap, sync::Arc}; | ||
4 | |||
5 | use lsp_types::{CodeActionOrCommand, Diagnostic, Range}; | ||
6 | use ra_ide::FileId; | ||
7 | |||
8 | pub type CheckFixes = Arc<HashMap<FileId, Vec<Fix>>>; | ||
9 | |||
10 | #[derive(Debug, Default, Clone)] | ||
11 | pub struct DiagnosticCollection { | ||
12 | pub native: HashMap<FileId, Vec<Diagnostic>>, | ||
13 | pub check: HashMap<FileId, Vec<Diagnostic>>, | ||
14 | pub check_fixes: CheckFixes, | ||
15 | } | ||
16 | |||
17 | #[derive(Debug, Clone)] | ||
18 | pub struct Fix { | ||
19 | pub range: Range, | ||
20 | pub action: CodeActionOrCommand, | ||
21 | } | ||
22 | |||
23 | #[derive(Debug)] | ||
24 | pub enum DiagnosticTask { | ||
25 | ClearCheck, | ||
26 | AddCheck(FileId, Diagnostic, Vec<CodeActionOrCommand>), | ||
27 | SetNative(FileId, Vec<Diagnostic>), | ||
28 | } | ||
29 | |||
30 | impl DiagnosticCollection { | ||
31 | pub fn clear_check(&mut self) -> Vec<FileId> { | ||
32 | Arc::make_mut(&mut self.check_fixes).clear(); | ||
33 | self.check.drain().map(|(key, _value)| key).collect() | ||
34 | } | ||
35 | |||
36 | pub fn add_check_diagnostic( | ||
37 | &mut self, | ||
38 | file_id: FileId, | ||
39 | diagnostic: Diagnostic, | ||
40 | fixes: Vec<CodeActionOrCommand>, | ||
41 | ) { | ||
42 | let diagnostics = self.check.entry(file_id).or_default(); | ||
43 | for existing_diagnostic in diagnostics.iter() { | ||
44 | if are_diagnostics_equal(&existing_diagnostic, &diagnostic) { | ||
45 | return; | ||
46 | } | ||
47 | } | ||
48 | |||
49 | let check_fixes = Arc::make_mut(&mut self.check_fixes); | ||
50 | check_fixes | ||
51 | .entry(file_id) | ||
52 | .or_default() | ||
53 | .extend(fixes.into_iter().map(|action| Fix { range: diagnostic.range, action })); | ||
54 | diagnostics.push(diagnostic); | ||
55 | } | ||
56 | |||
57 | pub fn set_native_diagnostics(&mut self, file_id: FileId, diagnostics: Vec<Diagnostic>) { | ||
58 | self.native.insert(file_id, diagnostics); | ||
59 | } | ||
60 | |||
61 | pub fn diagnostics_for(&self, file_id: FileId) -> impl Iterator<Item = &Diagnostic> { | ||
62 | let native = self.native.get(&file_id).into_iter().flatten(); | ||
63 | let check = self.check.get(&file_id).into_iter().flatten(); | ||
64 | native.chain(check) | ||
65 | } | ||
66 | |||
67 | pub fn handle_task(&mut self, task: DiagnosticTask) -> Vec<FileId> { | ||
68 | match task { | ||
69 | DiagnosticTask::ClearCheck => self.clear_check(), | ||
70 | DiagnosticTask::AddCheck(file_id, diagnostic, fixes) => { | ||
71 | self.add_check_diagnostic(file_id, diagnostic, fixes); | ||
72 | vec![file_id] | ||
73 | } | ||
74 | DiagnosticTask::SetNative(file_id, diagnostics) => { | ||
75 | self.set_native_diagnostics(file_id, diagnostics); | ||
76 | vec![file_id] | ||
77 | } | ||
78 | } | ||
79 | } | ||
80 | } | ||
81 | |||
82 | fn are_diagnostics_equal(left: &Diagnostic, right: &Diagnostic) -> bool { | ||
83 | left.source == right.source | ||
84 | && left.severity == right.severity | ||
85 | && left.range == right.range | ||
86 | && left.message == right.message | ||
87 | } | ||