]> git.lizzy.rs Git - rust.git/commitdiff
Add names for diagnostics and add a possibility to disable them
authorIgor Aleksanov <popzxc@yandex.ru>
Fri, 7 Aug 2020 10:18:47 +0000 (13:18 +0300)
committerIgor Aleksanov <popzxc@yandex.ru>
Fri, 7 Aug 2020 10:18:47 +0000 (13:18 +0300)
crates/ra_hir_def/src/diagnostics.rs
crates/ra_hir_expand/src/diagnostics.rs
crates/ra_hir_ty/src/diagnostics.rs

index 30db48f86828d1820bba8a62b08df4bf08f9eaef..1d28c24e888876893826fc2ad29ffce9a400212a 100644 (file)
@@ -15,6 +15,9 @@ pub struct UnresolvedModule {
 }
 
 impl Diagnostic for UnresolvedModule {
+    fn name(&self) -> String {
+        "unresolved-module".to_string()
+    }
     fn message(&self) -> String {
         "unresolved module".to_string()
     }
index 84ba97b14a1fedd42f4ee77268f068336731e9ab..bf9fb081aae5bbce53ebd3e24952906f3f6d12a1 100644 (file)
 //! subsystem provides a separate, non-query-based API which can walk all stored
 //! values and transform them into instances of `Diagnostic`.
 
-use std::{any::Any, fmt};
+use std::{any::Any, collections::HashSet, fmt};
 
 use ra_syntax::{SyntaxNode, SyntaxNodePtr};
 
 use crate::{db::AstDatabase, InFile};
 
 pub trait Diagnostic: Any + Send + Sync + fmt::Debug + 'static {
+    fn name(&self) -> String;
     fn message(&self) -> String;
     fn source(&self) -> InFile<SyntaxNodePtr>;
     fn as_any(&self) -> &(dyn Any + Send + 'static);
@@ -49,10 +50,16 @@ pub struct DiagnosticSink<'a> {
     callbacks: Vec<Box<dyn FnMut(&dyn Diagnostic) -> Result<(), ()> + 'a>>,
     filters: Vec<Box<dyn FnMut(&dyn Diagnostic) -> bool + 'a>>,
     default_callback: Box<dyn FnMut(&dyn Diagnostic) + 'a>,
+    disabled_diagnostics: HashSet<String>,
 }
 
 impl<'a> DiagnosticSink<'a> {
     pub fn push(&mut self, d: impl Diagnostic) {
+        if self.disabled_diagnostics.contains(&d.name()) {
+            // This diagnostic is disabled, ignore it completely.
+            return;
+        }
+
         let d: &dyn Diagnostic = &d;
         self._push(d);
     }
@@ -76,11 +83,12 @@ fn _push(&mut self, d: &dyn Diagnostic) {
 pub struct DiagnosticSinkBuilder<'a> {
     callbacks: Vec<Box<dyn FnMut(&dyn Diagnostic) -> Result<(), ()> + 'a>>,
     filters: Vec<Box<dyn FnMut(&dyn Diagnostic) -> bool + 'a>>,
+    disabled_diagnostics: HashSet<String>,
 }
 
 impl<'a> DiagnosticSinkBuilder<'a> {
     pub fn new() -> Self {
-        Self { callbacks: Vec::new(), filters: Vec::new() }
+        Self { callbacks: Vec::new(), filters: Vec::new(), disabled_diagnostics: HashSet::new() }
     }
 
     pub fn filter<F: FnMut(&dyn Diagnostic) -> bool + 'a>(mut self, cb: F) -> Self {
@@ -100,11 +108,17 @@ pub fn on<D: Diagnostic, F: FnMut(&D) + 'a>(mut self, mut cb: F) -> Self {
         self
     }
 
+    pub fn disable_diagnostic(mut self, diagnostic: impl Into<String>) -> Self {
+        self.disabled_diagnostics.insert(diagnostic.into());
+        self
+    }
+
     pub fn build<F: FnMut(&dyn Diagnostic) + 'a>(self, default_callback: F) -> DiagnosticSink<'a> {
         DiagnosticSink {
             callbacks: self.callbacks,
             filters: self.filters,
             default_callback: Box::new(default_callback),
+            disabled_diagnostics: self.disabled_diagnostics,
         }
     }
 }
index 977c0525b526f55fff4228a949a8fd993ab287af..0b3e16ae7aed9cbca88593431891b3f56d140879 100644 (file)
@@ -33,6 +33,10 @@ pub struct NoSuchField {
 }
 
 impl Diagnostic for NoSuchField {
+    fn name(&self) -> String {
+        "no-such-field".to_string()
+    }
+
     fn message(&self) -> String {
         "no such field".to_string()
     }
@@ -64,6 +68,9 @@ pub struct MissingFields {
 }
 
 impl Diagnostic for MissingFields {
+    fn name(&self) -> String {
+        "missing-structure-fields".to_string()
+    }
     fn message(&self) -> String {
         let mut buf = String::from("Missing structure fields:\n");
         for field in &self.missed_fields {
@@ -97,6 +104,9 @@ pub struct MissingPatFields {
 }
 
 impl Diagnostic for MissingPatFields {
+    fn name(&self) -> String {
+        "missing-pat-fields".to_string()
+    }
     fn message(&self) -> String {
         let mut buf = String::from("Missing structure fields:\n");
         for field in &self.missed_fields {
@@ -120,6 +130,9 @@ pub struct MissingMatchArms {
 }
 
 impl Diagnostic for MissingMatchArms {
+    fn name(&self) -> String {
+        "missing-match-arm".to_string()
+    }
     fn message(&self) -> String {
         String::from("Missing match arm")
     }
@@ -138,6 +151,9 @@ pub struct MissingOkInTailExpr {
 }
 
 impl Diagnostic for MissingOkInTailExpr {
+    fn name(&self) -> String {
+        "missing-ok-in-tail-expr".to_string()
+    }
     fn message(&self) -> String {
         "wrap return expression in Ok".to_string()
     }
@@ -166,6 +182,9 @@ pub struct BreakOutsideOfLoop {
 }
 
 impl Diagnostic for BreakOutsideOfLoop {
+    fn name(&self) -> String {
+        "break-outside-of-loop".to_string()
+    }
     fn message(&self) -> String {
         "break outside of loop".to_string()
     }
@@ -194,6 +213,9 @@ pub struct MissingUnsafe {
 }
 
 impl Diagnostic for MissingUnsafe {
+    fn name(&self) -> String {
+        "missing-unsafe".to_string()
+    }
     fn message(&self) -> String {
         format!("This operation is unsafe and requires an unsafe function or block")
     }
@@ -224,6 +246,9 @@ pub struct MismatchedArgCount {
 }
 
 impl Diagnostic for MismatchedArgCount {
+    fn name(&self) -> String {
+        "mismatched-arg-count".to_string()
+    }
     fn message(&self) -> String {
         let s = if self.expected == 1 { "" } else { "s" };
         format!("Expected {} argument{}, found {}", self.expected, s, self.found)