From 7953d8cc9345794613ba2e7b90af9429579bc0cf Mon Sep 17 00:00:00 2001
From: Akshay <nerdy@peppe.rs>
Date: Tue, 21 Sep 2021 20:51:20 +0530
Subject: add error code and report codegen, document a bit

---
 lib/src/lib.rs                   | 76 +++++++++++++++++++++++++++-------------
 lib/src/lints/bool_comparison.rs |  6 ++--
 2 files changed, 54 insertions(+), 28 deletions(-)

(limited to 'lib/src')

diff --git a/lib/src/lib.rs b/lib/src/lib.rs
index 0f92d0d..93792d4 100644
--- a/lib/src/lib.rs
+++ b/lib/src/lib.rs
@@ -6,10 +6,41 @@ pub use lints::LINTS;
 use rnix::{SyntaxElement, SyntaxKind, TextRange};
 use std::{default::Default, convert::Into};
 
-pub trait Rule {
-    fn validate(&self, node: &SyntaxElement) -> Option<Report>;
+/// Report generated by a lint
+#[derive(Debug, Default)]
+pub struct Report {
+    /// General information about this lint and where it applies.
+    pub note: &'static str,
+    /// An error code to uniquely identify this lint
+    pub code: u32,
+    /// Collection of diagnostics raised by this lint
+    pub diagnostics: Vec<Diagnostic>,
+}
+
+impl Report {
+    /// Construct a report. Do not invoke manually, see `lint` macro
+    pub fn new(note: &'static str, code: u32) -> Self {
+        Self {
+            note,
+            code,
+            ..Default::default()
+        }
+    }
+    /// Add a diagnostic to this report
+    pub fn diagnostic(mut self, at: TextRange, message: String) -> Self {
+        self.diagnostics.push(Diagnostic::new(at, message));
+        self
+    }
+    /// Add a diagnostic with a fix to this report
+    pub fn suggest(mut self, at: TextRange, message: String, suggestion: Suggestion) -> Self {
+        self.diagnostics.push(Diagnostic::suggest(at, message, suggestion));
+        self
+    }
+
 }
 
+/// Mapping from a bytespan to an error message.
+/// Can optionally suggest a fix.
 #[derive(Debug)]
 pub struct Diagnostic {
     pub at: TextRange,
@@ -18,14 +49,18 @@ pub struct Diagnostic {
 }
 
 impl Diagnostic {
+    /// Construct a diagnostic.
     pub fn new(at: TextRange, message: String) -> Self {
         Self { at, message, suggestion: None }
     }
+    /// Construct a diagnostic with a fix.
     pub fn suggest(at: TextRange, message: String, suggestion: Suggestion) -> Self {
         Self { at, message, suggestion: Some(suggestion) }
     }
 }
 
+/// Suggested fix for a diagnostic, the fix is provided as a syntax element.
+/// Look at `make.rs` to construct fixes.
 #[derive(Debug)]
 pub struct Suggestion {
     pub at: TextRange,
@@ -33,6 +68,7 @@ pub struct Suggestion {
 }
 
 impl Suggestion {
+    /// Construct a suggestion.
     pub fn new<E: Into<SyntaxElement>>(at: TextRange, fix: E) -> Self {
         Self {
             at,
@@ -41,39 +77,31 @@ impl Suggestion {
     }
 }
 
-#[derive(Debug, Default)]
-pub struct Report {
-    pub diagnostics: Vec<Diagnostic>,
-    pub note: &'static str
-}
-
-impl Report {
-    pub fn new(note: &'static str) -> Self {
-        Self {
-            note,
-            ..Default::default()
-        }
-    }
-    pub fn diagnostic(mut self, at: TextRange, message: String) -> Self {
-        self.diagnostics.push(Diagnostic::new(at, message));
-        self
-    }
-    pub fn suggest(mut self, at: TextRange, message: String, suggestion: Suggestion) -> Self {
-        self.diagnostics.push(Diagnostic::suggest(at, message, suggestion));
-        self
-    }
-
+/// Lint logic is defined via this trait. Do not implement manually,
+/// look at the `lint` attribute macro instead for implementing rules
+pub trait Rule {
+    fn validate(&self, node: &SyntaxElement) -> Option<Report>;
 }
 
+/// Contains information about the lint itself. Do not implement manually,
+/// look at the `lint` attribute macro instead for implementing rules
 pub trait Metadata {
     fn name() -> &'static str where Self: Sized;
     fn note() -> &'static str where Self: Sized;
+    fn code() -> u32 where Self: Sized;
+    fn report() -> Report where Self: Sized;
     fn match_with(&self, with: &SyntaxKind) -> bool;
     fn match_kind(&self) -> SyntaxKind;
 }
 
+/// Combines Rule and Metadata, do not implement manually, this is derived by
+/// the `lint` macro.
 pub trait Lint: Metadata + Rule + Send + Sync {}
 
+/// Helper utility to take lints from modules and insert them into a map for efficient
+/// access. Mapping is from a SyntaxKind to a list of lints that apply on that Kind.
+///
+/// See `lints.rs` for usage.
 #[macro_export]
 macro_rules! lint_map {
     ($($s:ident),*,) => {
diff --git a/lib/src/lints/bool_comparison.rs b/lib/src/lints/bool_comparison.rs
index f869e17..d23a4b0 100644
--- a/lib/src/lints/bool_comparison.rs
+++ b/lib/src/lints/bool_comparison.rs
@@ -10,6 +10,7 @@ use rnix::{
 #[lint(
     name = "bool_comparison",
     note = "Unnecessary comparison with boolean",
+    code = 1,
     match_with = SyntaxKind::NODE_BIN_OP
 )]
 struct BoolComparison;
@@ -70,10 +71,7 @@ impl Rule for BoolComparison {
                     non_bool_side,
                     bool_side
                 );
-                Some(
-                    Report::new(Self::note())
-                      .suggest(at, message, Suggestion::new(at, replacement))
-                )
+                Some(Self::report().suggest(at, message, Suggestion::new(at, replacement)))
             } else {
                 None
             }
-- 
cgit v1.2.3