aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/diagnostics.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-03-24 07:21:36 +0000
committerAleksey Kladov <[email protected]>2019-03-25 07:52:50 +0000
commitc7ffd939f670a1cba5bf415759b43e63700761a7 (patch)
tree01407564dcac6ad08bd84ab350272aca5acb7355 /crates/ra_hir/src/diagnostics.rs
parent7ee2887d1ec129afed80845c2361ce35f1a0c013 (diff)
more enterprisey diagnostics setup
Diffstat (limited to 'crates/ra_hir/src/diagnostics.rs')
-rw-r--r--crates/ra_hir/src/diagnostics.rs39
1 files changed, 29 insertions, 10 deletions
diff --git a/crates/ra_hir/src/diagnostics.rs b/crates/ra_hir/src/diagnostics.rs
index d6b28159e..a6ca68d86 100644
--- a/crates/ra_hir/src/diagnostics.rs
+++ b/crates/ra_hir/src/diagnostics.rs
@@ -1,9 +1,9 @@
1use std::{fmt, any::Any}; 1use std::{fmt, any::Any};
2 2
3use ra_syntax::{SyntaxNodePtr, AstPtr, ast}; 3use ra_syntax::{SyntaxNodePtr, AstPtr, ast};
4use relative_path::RelativePathBuf;
4 5
5use crate::HirFileId; 6use crate::HirFileId;
6use relative_path::RelativePathBuf;
7 7
8/// Diagnostic defines hir API for errors and warnings. 8/// Diagnostic defines hir API for errors and warnings.
9/// 9///
@@ -21,7 +21,7 @@ pub trait Diagnostic: Any + Send + Sync + fmt::Debug + 'static {
21 fn message(&self) -> String; 21 fn message(&self) -> String;
22 fn file(&self) -> HirFileId; 22 fn file(&self) -> HirFileId;
23 fn syntax_node(&self) -> SyntaxNodePtr; 23 fn syntax_node(&self) -> SyntaxNodePtr;
24 fn as_any(&self) -> &(Any + Send + 'static); 24 fn as_any(&self) -> &(dyn Any + Send + 'static);
25} 25}
26 26
27impl dyn Diagnostic { 27impl dyn Diagnostic {
@@ -30,18 +30,37 @@ impl dyn Diagnostic {
30 } 30 }
31} 31}
32 32
33#[derive(Debug, Default)] 33pub struct DiagnosticSink<'a> {
34pub struct DiagnosticSink { 34 callbacks: Vec<Box<dyn FnMut(&dyn Diagnostic) -> Result<(), ()> + 'a>>,
35 data: Vec<Box<dyn Diagnostic>>, 35 default_callback: Box<dyn FnMut(&dyn Diagnostic) + 'a>,
36} 36}
37 37
38impl DiagnosticSink { 38impl<'a> DiagnosticSink<'a> {
39 pub fn push(&mut self, d: impl Diagnostic) { 39 pub fn new(cb: impl FnMut(&dyn Diagnostic) + 'a) -> DiagnosticSink<'a> {
40 self.data.push(Box::new(d)) 40 DiagnosticSink { callbacks: Vec::new(), default_callback: Box::new(cb) }
41 }
42
43 pub fn on<D: Diagnostic, F: FnMut(&D) + 'a>(mut self, mut cb: F) -> DiagnosticSink<'a> {
44 let cb = move |diag: &dyn Diagnostic| match diag.downcast_ref::<D>() {
45 Some(d) => {
46 cb(d);
47 Ok(())
48 }
49 None => Err(()),
50 };
51 self.callbacks.push(Box::new(cb));
52 self
41 } 53 }
42 54
43 pub fn into_diagnostics(self) -> Vec<Box<dyn Diagnostic>> { 55 pub(crate) fn push(&mut self, d: impl Diagnostic) {
44 self.data 56 let d: &dyn Diagnostic = &d;
57 for cb in self.callbacks.iter_mut() {
58 match cb(d) {
59 Ok(()) => return,
60 Err(()) => (),
61 }
62 }
63 (self.default_callback)(d)
45 } 64 }
46} 65}
47 66