Add names for diagnostics and add a possibility to disable them

This commit is contained in:
Igor Aleksanov 2020-08-07 13:18:47 +03:00
parent f1d507270c
commit c463d217a1
3 changed files with 44 additions and 2 deletions

View 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()
}

View file

@ -14,13 +14,14 @@
//! 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 @@ impl<'a> DiagnosticSink<'a> {
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 @@ impl<'a> DiagnosticSinkBuilder<'a> {
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,
}
}
}

View 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)