aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/src/lib.rs30
-rw-r--r--lib/src/lints/bool_comparison.rs26
-rw-r--r--lib/src/lints/collapsible_let_in.rs9
-rw-r--r--lib/src/lints/empty_let_in.rs8
-rw-r--r--lib/src/lints/empty_pattern.rs4
-rw-r--r--lib/src/lints/eta_reduction.rs4
-rw-r--r--lib/src/lints/legacy_let_syntax.rs4
-rw-r--r--lib/src/lints/manual_inherit.rs4
-rw-r--r--lib/src/lints/manual_inherit_from.rs4
-rw-r--r--lib/src/lints/redundant_pattern_bind.rs4
-rw-r--r--lib/src/lints/unquoted_splice.rs4
-rw-r--r--lib/src/lints/useless_parens.rs10
12 files changed, 68 insertions, 43 deletions
diff --git a/lib/src/lib.rs b/lib/src/lib.rs
index 196cbf8..e6bfa6c 100644
--- a/lib/src/lib.rs
+++ b/lib/src/lib.rs
@@ -226,25 +226,29 @@ pub trait Rule {
226/// Contains information about the lint itself. Do not implement manually, 226/// Contains information about the lint itself. Do not implement manually,
227/// look at the `lint` attribute macro instead for implementing rules 227/// look at the `lint` attribute macro instead for implementing rules
228pub trait Metadata { 228pub trait Metadata {
229 fn name() -> &'static str 229 fn name(&self) -> &'static str;
230 where 230 fn note(&self) -> &'static str;
231 Self: Sized; 231 fn code(&self) -> u32;
232 fn note() -> &'static str 232 fn report(&self) -> Report;
233 where
234 Self: Sized;
235 fn code() -> u32
236 where
237 Self: Sized;
238 fn report() -> Report
239 where
240 Self: Sized;
241 fn match_with(&self, with: &SyntaxKind) -> bool; 233 fn match_with(&self, with: &SyntaxKind) -> bool;
242 fn match_kind(&self) -> Vec<SyntaxKind>; 234 fn match_kind(&self) -> Vec<SyntaxKind>;
243} 235}
244 236
237/// Contains offline explaination for each lint
238/// The `lint` macro scans nearby doc comments for
239/// explainations and derives this trait.
240///
241/// FIXME: the lint macro does way too much, maybe
242/// split it into smaller macros.
243pub trait Explain {
244 fn explaination(&self) -> &'static str {
245 "no explaination found"
246 }
247}
248
245/// Combines Rule and Metadata, do not implement manually, this is derived by 249/// Combines Rule and Metadata, do not implement manually, this is derived by
246/// the `lint` macro. 250/// the `lint` macro.
247pub trait Lint: Metadata + Rule + Send + Sync {} 251pub trait Lint: Metadata + Explain + Rule + Send + Sync {}
248 252
249/// Helper utility to take lints from modules and insert them into a map for efficient 253/// Helper utility to take lints from modules and insert them into a map for efficient
250/// access. Mapping is from a SyntaxKind to a list of lints that apply on that Kind. 254/// access. Mapping is from a SyntaxKind to a list of lints that apply on that Kind.
diff --git a/lib/src/lints/bool_comparison.rs b/lib/src/lints/bool_comparison.rs
index 0b5733b..6636faf 100644
--- a/lib/src/lints/bool_comparison.rs
+++ b/lib/src/lints/bool_comparison.rs
@@ -1,4 +1,4 @@
1use crate::{make, Lint, Metadata, Report, Rule, Suggestion}; 1use crate::{make, Metadata, Report, Rule, Suggestion};
2 2
3use if_chain::if_chain; 3use if_chain::if_chain;
4use macros::lint; 4use macros::lint;
@@ -7,6 +7,28 @@ use rnix::{
7 NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, 7 NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode,
8}; 8};
9 9
10/// What it does
11/// ------------
12/// Checks for expressions of the form x == true, x != true and
13/// suggests using the variable directly.
14///
15/// Why is this bad?
16/// ----------------
17/// Unnecessary code.
18///
19/// Example
20/// --------
21/// Instead of checking the value of x:
22///
23/// if x == true
24/// then 0
25/// else 1
26///
27/// Use x directly:
28///
29/// if x
30/// then 0
31/// else 1
10#[lint( 32#[lint(
11 name = "bool_comparison", 33 name = "bool_comparison",
12 note = "Unnecessary comparison with boolean", 34 note = "Unnecessary comparison with boolean",
@@ -71,7 +93,7 @@ impl Rule for BoolComparison {
71 non_bool_side, 93 non_bool_side,
72 bool_side 94 bool_side
73 ); 95 );
74 Some(Self::report().suggest(at, message, Suggestion::new(at, replacement))) 96 Some(self.report().suggest(at, message, Suggestion::new(at, replacement)))
75 } else { 97 } else {
76 None 98 None
77 } 99 }
diff --git a/lib/src/lints/collapsible_let_in.rs b/lib/src/lints/collapsible_let_in.rs
index 878d218..cb76c37 100644
--- a/lib/src/lints/collapsible_let_in.rs
+++ b/lib/src/lints/collapsible_let_in.rs
@@ -1,12 +1,12 @@
1use crate::{make, Lint, Metadata, Report, Rule, Suggestion}; 1use crate::{make, Metadata, Report, Rule, Suggestion};
2 2
3use if_chain::if_chain; 3use if_chain::if_chain;
4use macros::lint; 4use macros::lint;
5use rowan::Direction;
6use rnix::{ 5use rnix::{
7 types::{LetIn, TypedNode}, 6 types::{LetIn, TypedNode},
8 NodeOrToken, SyntaxElement, SyntaxKind, TextRange 7 NodeOrToken, SyntaxElement, SyntaxKind, TextRange,
9}; 8};
9use rowan::Direction;
10 10
11#[lint( 11#[lint(
12 name = "collapsible let in", 12 name = "collapsible let in",
@@ -47,7 +47,7 @@ impl Rule for CollapsibleLetIn {
47 let replacement = make::empty().node().clone(); 47 let replacement = make::empty().node().clone();
48 48
49 Some( 49 Some(
50 Self::report() 50 self.report()
51 .diagnostic(first_annotation, first_message) 51 .diagnostic(first_annotation, first_message)
52 .suggest(second_annotation, second_message, Suggestion::new(replacement_at, replacement)) 52 .suggest(second_annotation, second_message, Suggestion::new(replacement_at, replacement))
53 ) 53 )
@@ -57,4 +57,3 @@ impl Rule for CollapsibleLetIn {
57 } 57 }
58 } 58 }
59} 59}
60
diff --git a/lib/src/lints/empty_let_in.rs b/lib/src/lints/empty_let_in.rs
index aae1377..4e0887d 100644
--- a/lib/src/lints/empty_let_in.rs
+++ b/lib/src/lints/empty_let_in.rs
@@ -1,12 +1,13 @@
1use crate::{Lint, Metadata, Report, Rule, Suggestion}; 1use crate::{Metadata, Report, Rule, Suggestion};
2 2
3use if_chain::if_chain; 3use if_chain::if_chain;
4use macros::lint; 4use macros::lint;
5use rnix::{ 5use rnix::{
6 types::{LetIn, TypedNode, EntryHolder}, 6 types::{EntryHolder, LetIn, TypedNode},
7 NodeOrToken, SyntaxElement, SyntaxKind, 7 NodeOrToken, SyntaxElement, SyntaxKind,
8}; 8};
9 9
10/// empty let-in found
10#[lint( 11#[lint(
11 name = "empty let-in", 12 name = "empty let-in",
12 note = "Useless let-in expression", 13 note = "Useless let-in expression",
@@ -31,11 +32,10 @@ impl Rule for EmptyLetIn {
31 let at = node.text_range(); 32 let at = node.text_range();
32 let replacement = body; 33 let replacement = body;
33 let message = "This let-in expression has no entries"; 34 let message = "This let-in expression has no entries";
34 Some(Self::report().suggest(at, message, Suggestion::new(at, replacement))) 35 Some(self.report().suggest(at, message, Suggestion::new(at, replacement)))
35 } else { 36 } else {
36 None 37 None
37 } 38 }
38 } 39 }
39 } 40 }
40} 41}
41
diff --git a/lib/src/lints/empty_pattern.rs b/lib/src/lints/empty_pattern.rs
index 6fb7558..ef47c69 100644
--- a/lib/src/lints/empty_pattern.rs
+++ b/lib/src/lints/empty_pattern.rs
@@ -1,4 +1,4 @@
1use crate::{make, Lint, Metadata, Report, Rule, Suggestion}; 1use crate::{make, Metadata, Report, Rule, Suggestion};
2 2
3use if_chain::if_chain; 3use if_chain::if_chain;
4use macros::lint; 4use macros::lint;
@@ -28,7 +28,7 @@ impl Rule for EmptyPattern {
28 let at = node.text_range(); 28 let at = node.text_range();
29 let message = "This pattern is empty, use `_` instead"; 29 let message = "This pattern is empty, use `_` instead";
30 let replacement = make::ident("_").node().clone(); 30 let replacement = make::ident("_").node().clone();
31 Some(Self::report().suggest(at, message, Suggestion::new(at, replacement))) 31 Some(self.report().suggest(at, message, Suggestion::new(at, replacement)))
32 } else { 32 } else {
33 None 33 None
34 } 34 }
diff --git a/lib/src/lints/eta_reduction.rs b/lib/src/lints/eta_reduction.rs
index 79a5101..b329ae8 100644
--- a/lib/src/lints/eta_reduction.rs
+++ b/lib/src/lints/eta_reduction.rs
@@ -1,4 +1,4 @@
1use crate::{Lint, Metadata, Report, Rule, Suggestion}; 1use crate::{Metadata, Report, Rule, Suggestion};
2 2
3use if_chain::if_chain; 3use if_chain::if_chain;
4use macros::lint; 4use macros::lint;
@@ -43,7 +43,7 @@ impl Rule for EtaReduction {
43 "Found eta-reduction: `{}`", 43 "Found eta-reduction: `{}`",
44 replacement.text().to_string() 44 replacement.text().to_string()
45 ); 45 );
46 Some(Self::report().suggest(at, message, Suggestion::new(at, replacement))) 46 Some(self.report().suggest(at, message, Suggestion::new(at, replacement)))
47 } else { 47 } else {
48 None 48 None
49 } 49 }
diff --git a/lib/src/lints/legacy_let_syntax.rs b/lib/src/lints/legacy_let_syntax.rs
index 2087e27..8b37df8 100644
--- a/lib/src/lints/legacy_let_syntax.rs
+++ b/lib/src/lints/legacy_let_syntax.rs
@@ -1,4 +1,4 @@
1use crate::{make, Lint, Metadata, Report, Rule, Suggestion}; 1use crate::{make, Metadata, Report, Rule, Suggestion};
2 2
3use if_chain::if_chain; 3use if_chain::if_chain;
4use macros::lint; 4use macros::lint;
@@ -36,7 +36,7 @@ impl Rule for ManualInherit {
36 let message = "Prefer `rec` over undocumented `let` syntax"; 36 let message = "Prefer `rec` over undocumented `let` syntax";
37 let replacement = selected.node().clone(); 37 let replacement = selected.node().clone();
38 38
39 Some(Self::report().suggest(at, message, Suggestion::new(at, replacement))) 39 Some(self.report().suggest(at, message, Suggestion::new(at, replacement)))
40 } else { 40 } else {
41 None 41 None
42 } 42 }
diff --git a/lib/src/lints/manual_inherit.rs b/lib/src/lints/manual_inherit.rs
index 0a6933c..1c10cbf 100644
--- a/lib/src/lints/manual_inherit.rs
+++ b/lib/src/lints/manual_inherit.rs
@@ -1,4 +1,4 @@
1use crate::{make, Lint, Metadata, Report, Rule, Suggestion}; 1use crate::{make, Metadata, Report, Rule, Suggestion};
2 2
3use if_chain::if_chain; 3use if_chain::if_chain;
4use macros::lint; 4use macros::lint;
@@ -35,7 +35,7 @@ impl Rule for ManualInherit {
35 let at = node.text_range(); 35 let at = node.text_range();
36 let replacement = make::inherit_stmt(&[key]).node().clone(); 36 let replacement = make::inherit_stmt(&[key]).node().clone();
37 let message = "This assignment is better written with `inherit`"; 37 let message = "This assignment is better written with `inherit`";
38 Some(Self::report().suggest(at, message, Suggestion::new(at, replacement))) 38 Some(self.report().suggest(at, message, Suggestion::new(at, replacement)))
39 } else { 39 } else {
40 None 40 None
41 } 41 }
diff --git a/lib/src/lints/manual_inherit_from.rs b/lib/src/lints/manual_inherit_from.rs
index 794aaf9..146d55b 100644
--- a/lib/src/lints/manual_inherit_from.rs
+++ b/lib/src/lints/manual_inherit_from.rs
@@ -1,4 +1,4 @@
1use crate::{make, Lint, Metadata, Report, Rule, Suggestion}; 1use crate::{make, Metadata, Report, Rule, Suggestion};
2 2
3use if_chain::if_chain; 3use if_chain::if_chain;
4use macros::lint; 4use macros::lint;
@@ -40,7 +40,7 @@ impl Rule for ManualInherit {
40 make::inherit_from_stmt(set, &[key]).node().clone() 40 make::inherit_from_stmt(set, &[key]).node().clone()
41 }; 41 };
42 let message = "This assignment is better written with `inherit`"; 42 let message = "This assignment is better written with `inherit`";
43 Some(Self::report().suggest(at, message, Suggestion::new(at, replacement))) 43 Some(self.report().suggest(at, message, Suggestion::new(at, replacement)))
44 } else { 44 } else {
45 None 45 None
46 } 46 }
diff --git a/lib/src/lints/redundant_pattern_bind.rs b/lib/src/lints/redundant_pattern_bind.rs
index aebc549..ad1aba8 100644
--- a/lib/src/lints/redundant_pattern_bind.rs
+++ b/lib/src/lints/redundant_pattern_bind.rs
@@ -1,4 +1,4 @@
1use crate::{Lint, Metadata, Report, Rule, Suggestion}; 1use crate::{Metadata, Report, Rule, Suggestion};
2 2
3use if_chain::if_chain; 3use if_chain::if_chain;
4use macros::lint; 4use macros::lint;
@@ -32,7 +32,7 @@ impl Rule for RedundantPatternBind {
32 let at = node.text_range(); 32 let at = node.text_range();
33 let message = format!("This pattern bind is redundant, use `{}` instead", ident.as_str()); 33 let message = format!("This pattern bind is redundant, use `{}` instead", ident.as_str());
34 let replacement = ident.node().clone(); 34 let replacement = ident.node().clone();
35 Some(Self::report().suggest(at, message, Suggestion::new(at, replacement))) 35 Some(self.report().suggest(at, message, Suggestion::new(at, replacement)))
36 } else { 36 } else {
37 None 37 None
38 } 38 }
diff --git a/lib/src/lints/unquoted_splice.rs b/lib/src/lints/unquoted_splice.rs
index 4d1ed69..2831c1b 100644
--- a/lib/src/lints/unquoted_splice.rs
+++ b/lib/src/lints/unquoted_splice.rs
@@ -1,4 +1,4 @@
1use crate::{make, Lint, Metadata, Report, Rule, Suggestion}; 1use crate::{make, Metadata, Report, Rule, Suggestion};
2 2
3use if_chain::if_chain; 3use if_chain::if_chain;
4use macros::lint; 4use macros::lint;
@@ -24,7 +24,7 @@ impl Rule for UnquotedSplice {
24 let at = node.text_range(); 24 let at = node.text_range();
25 let replacement = make::quote(&node).node().clone(); 25 let replacement = make::quote(&node).node().clone();
26 let message = "Consider quoting this splice expression"; 26 let message = "Consider quoting this splice expression";
27 Some(Self::report().suggest(at, message, Suggestion::new(at, replacement))) 27 Some(self.report().suggest(at, message, Suggestion::new(at, replacement)))
28 } else { 28 } else {
29 None 29 None
30 } 30 }
diff --git a/lib/src/lints/useless_parens.rs b/lib/src/lints/useless_parens.rs
index 2d6ba8f..9dfeabb 100644
--- a/lib/src/lints/useless_parens.rs
+++ b/lib/src/lints/useless_parens.rs
@@ -1,9 +1,9 @@
1use crate::{Lint, Metadata, Report, Rule, Suggestion, Diagnostic}; 1use crate::{Diagnostic, Metadata, Report, Rule, Suggestion};
2 2
3use if_chain::if_chain; 3use if_chain::if_chain;
4use macros::lint; 4use macros::lint;
5use rnix::{ 5use rnix::{
6 types::{ParsedType, KeyValue, Paren, TypedNode, Wrapper}, 6 types::{KeyValue, Paren, ParsedType, TypedNode, Wrapper},
7 NodeOrToken, SyntaxElement, SyntaxKind, 7 NodeOrToken, SyntaxElement, SyntaxKind,
8}; 8};
9 9
@@ -27,7 +27,7 @@ impl Rule for UselessParens {
27 27
28 if let Some(diagnostic) = do_thing(parsed_type_node); 28 if let Some(diagnostic) = do_thing(parsed_type_node);
29 then { 29 then {
30 let mut report = Self::report(); 30 let mut report = self.report();
31 report.diagnostics.push(diagnostic); 31 report.diagnostics.push(diagnostic);
32 Some(report) 32 Some(report)
33 } else { 33 } else {
@@ -79,7 +79,7 @@ fn do_thing(parsed_type_node: ParsedType) -> Option<Diagnostic> {
79 if let Some(parsed_inner) = ParsedType::cast(inner_node); 79 if let Some(parsed_inner) = ParsedType::cast(inner_node);
80 if matches!( 80 if matches!(
81 parsed_inner, 81 parsed_inner,
82 ParsedType::List(_) 82 ParsedType::List(_)
83 | ParsedType::Paren(_) 83 | ParsedType::Paren(_)
84 | ParsedType::Str(_) 84 | ParsedType::Str(_)
85 | ParsedType::AttrSet(_) 85 | ParsedType::AttrSet(_)
@@ -95,6 +95,6 @@ fn do_thing(parsed_type_node: ParsedType) -> Option<Diagnostic> {
95 None 95 None
96 } 96 }
97 }, 97 },
98 _ => None 98 _ => None,
99 } 99 }
100} 100}