From c7ffd939f670a1cba5bf415759b43e63700761a7 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 24 Mar 2019 10:21:36 +0300 Subject: more enterprisey diagnostics setup --- crates/ra_hir/src/code_model_api.rs | 16 +++++++++++++++ crates/ra_hir/src/diagnostics.rs | 39 +++++++++++++++++++++++++++---------- 2 files changed, 45 insertions(+), 10 deletions(-) (limited to 'crates/ra_hir/src') 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 { pub fn diagnostics(&self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { db.crate_def_map(self.krate).add_diagnostics(db, self.module_id, sink); + for decl in self.declarations(db) { + match decl { + crate::ModuleDef::Function(f) => f.diagnostics(db, sink), + crate::ModuleDef::Module(f) => f.diagnostics(db, sink), + _ => (), + } + } + + for impl_block in self.impl_blocks(db) { + for item in impl_block.items(db) { + match item { + crate::ImplItem::Method(f) => f.diagnostics(db, sink), + _ => (), + } + } + } } 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 @@ use std::{fmt, any::Any}; use ra_syntax::{SyntaxNodePtr, AstPtr, ast}; +use relative_path::RelativePathBuf; use crate::HirFileId; -use relative_path::RelativePathBuf; /// Diagnostic defines hir API for errors and warnings. /// @@ -21,7 +21,7 @@ pub trait Diagnostic: Any + Send + Sync + fmt::Debug + 'static { fn message(&self) -> String; fn file(&self) -> HirFileId; fn syntax_node(&self) -> SyntaxNodePtr; - fn as_any(&self) -> &(Any + Send + 'static); + fn as_any(&self) -> &(dyn Any + Send + 'static); } impl dyn Diagnostic { @@ -30,18 +30,37 @@ impl dyn Diagnostic { } } -#[derive(Debug, Default)] -pub struct DiagnosticSink { - data: Vec>, +pub struct DiagnosticSink<'a> { + callbacks: Vec Result<(), ()> + 'a>>, + default_callback: Box, } -impl DiagnosticSink { - pub fn push(&mut self, d: impl Diagnostic) { - self.data.push(Box::new(d)) +impl<'a> DiagnosticSink<'a> { + pub fn new(cb: impl FnMut(&dyn Diagnostic) + 'a) -> DiagnosticSink<'a> { + DiagnosticSink { callbacks: Vec::new(), default_callback: Box::new(cb) } + } + + pub fn on(mut self, mut cb: F) -> DiagnosticSink<'a> { + let cb = move |diag: &dyn Diagnostic| match diag.downcast_ref::() { + Some(d) => { + cb(d); + Ok(()) + } + None => Err(()), + }; + self.callbacks.push(Box::new(cb)); + self } - pub fn into_diagnostics(self) -> Vec> { - self.data + pub(crate) fn push(&mut self, d: impl Diagnostic) { + let d: &dyn Diagnostic = &d; + for cb in self.callbacks.iter_mut() { + match cb(d) { + Ok(()) => return, + Err(()) => (), + } + } + (self.default_callback)(d) } } -- cgit v1.2.3