aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/src/code_model_api.rs16
-rw-r--r--crates/ra_hir/src/diagnostics.rs39
2 files changed, 45 insertions, 10 deletions
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs
index bc0f74c89..5437133b8 100644
--- a/crates/ra_hir/src/code_model_api.rs
+++ b/crates/ra_hir/src/code_model_api.rs
@@ -168,6 +168,22 @@ impl Module {
168 168
169 pub fn diagnostics(&self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { 169 pub fn diagnostics(&self, db: &impl HirDatabase, sink: &mut DiagnosticSink) {
170 db.crate_def_map(self.krate).add_diagnostics(db, self.module_id, sink); 170 db.crate_def_map(self.krate).add_diagnostics(db, self.module_id, sink);
171 for decl in self.declarations(db) {
172 match decl {
173 crate::ModuleDef::Function(f) => f.diagnostics(db, sink),
174 crate::ModuleDef::Module(f) => f.diagnostics(db, sink),
175 _ => (),
176 }
177 }
178
179 for impl_block in self.impl_blocks(db) {
180 for item in impl_block.items(db) {
181 match item {
182 crate::ImplItem::Method(f) => f.diagnostics(db, sink),
183 _ => (),
184 }
185 }
186 }
171 } 187 }
172 188
173 pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { 189 pub fn resolver(&self, db: &impl HirDatabase) -> Resolver {
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