aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_expand/src/diagnostics.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_expand/src/diagnostics.rs')
-rw-r--r--crates/ra_hir_expand/src/diagnostics.rs25
1 files changed, 22 insertions, 3 deletions
diff --git a/crates/ra_hir_expand/src/diagnostics.rs b/crates/ra_hir_expand/src/diagnostics.rs
index 6a5844f31..84ba97b14 100644
--- a/crates/ra_hir_expand/src/diagnostics.rs
+++ b/crates/ra_hir_expand/src/diagnostics.rs
@@ -24,6 +24,9 @@ pub trait Diagnostic: Any + Send + Sync + fmt::Debug + 'static {
24 fn message(&self) -> String; 24 fn message(&self) -> String;
25 fn source(&self) -> InFile<SyntaxNodePtr>; 25 fn source(&self) -> InFile<SyntaxNodePtr>;
26 fn as_any(&self) -> &(dyn Any + Send + 'static); 26 fn as_any(&self) -> &(dyn Any + Send + 'static);
27 fn is_experimental(&self) -> bool {
28 false
29 }
27} 30}
28 31
29pub trait AstDiagnostic { 32pub trait AstDiagnostic {
@@ -44,6 +47,7 @@ impl dyn Diagnostic {
44 47
45pub struct DiagnosticSink<'a> { 48pub struct DiagnosticSink<'a> {
46 callbacks: Vec<Box<dyn FnMut(&dyn Diagnostic) -> Result<(), ()> + 'a>>, 49 callbacks: Vec<Box<dyn FnMut(&dyn Diagnostic) -> Result<(), ()> + 'a>>,
50 filters: Vec<Box<dyn FnMut(&dyn Diagnostic) -> bool + 'a>>,
47 default_callback: Box<dyn FnMut(&dyn Diagnostic) + 'a>, 51 default_callback: Box<dyn FnMut(&dyn Diagnostic) + 'a>,
48} 52}
49 53
@@ -54,7 +58,12 @@ impl<'a> DiagnosticSink<'a> {
54 } 58 }
55 59
56 fn _push(&mut self, d: &dyn Diagnostic) { 60 fn _push(&mut self, d: &dyn Diagnostic) {
57 for cb in self.callbacks.iter_mut() { 61 for filter in &mut self.filters {
62 if !filter(d) {
63 return;
64 }
65 }
66 for cb in &mut self.callbacks {
58 match cb(d) { 67 match cb(d) {
59 Ok(()) => return, 68 Ok(()) => return,
60 Err(()) => (), 69 Err(()) => (),
@@ -66,11 +75,17 @@ impl<'a> DiagnosticSink<'a> {
66 75
67pub struct DiagnosticSinkBuilder<'a> { 76pub struct DiagnosticSinkBuilder<'a> {
68 callbacks: Vec<Box<dyn FnMut(&dyn Diagnostic) -> Result<(), ()> + 'a>>, 77 callbacks: Vec<Box<dyn FnMut(&dyn Diagnostic) -> Result<(), ()> + 'a>>,
78 filters: Vec<Box<dyn FnMut(&dyn Diagnostic) -> bool + 'a>>,
69} 79}
70 80
71impl<'a> DiagnosticSinkBuilder<'a> { 81impl<'a> DiagnosticSinkBuilder<'a> {
72 pub fn new() -> Self { 82 pub fn new() -> Self {
73 Self { callbacks: Vec::new() } 83 Self { callbacks: Vec::new(), filters: Vec::new() }
84 }
85
86 pub fn filter<F: FnMut(&dyn Diagnostic) -> bool + 'a>(mut self, cb: F) -> Self {
87 self.filters.push(Box::new(cb));
88 self
74 } 89 }
75 90
76 pub fn on<D: Diagnostic, F: FnMut(&D) + 'a>(mut self, mut cb: F) -> Self { 91 pub fn on<D: Diagnostic, F: FnMut(&D) + 'a>(mut self, mut cb: F) -> Self {
@@ -86,6 +101,10 @@ impl<'a> DiagnosticSinkBuilder<'a> {
86 } 101 }
87 102
88 pub fn build<F: FnMut(&dyn Diagnostic) + 'a>(self, default_callback: F) -> DiagnosticSink<'a> { 103 pub fn build<F: FnMut(&dyn Diagnostic) + 'a>(self, default_callback: F) -> DiagnosticSink<'a> {
89 DiagnosticSink { callbacks: self.callbacks, default_callback: Box::new(default_callback) } 104 DiagnosticSink {
105 callbacks: self.callbacks,
106 filters: self.filters,
107 default_callback: Box::new(default_callback),
108 }
90 } 109 }
91} 110}