aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/src/lints/bool_comparison.rs27
-rw-r--r--lib/src/lints/collapsible_let_in.rs28
-rw-r--r--lib/src/lints/empty_let_in.rs19
-rw-r--r--lib/src/lints/empty_pattern.rs27
-rw-r--r--lib/src/lints/eta_reduction.rs26
-rw-r--r--lib/src/lints/legacy_let_syntax.rs28
-rw-r--r--lib/src/lints/manual_inherit.rs24
-rw-r--r--lib/src/lints/manual_inherit_from.rs24
-rw-r--r--lib/src/lints/redundant_pattern_bind.rs21
-rw-r--r--lib/src/lints/unquoted_splice.rs24
-rw-r--r--lib/src/lints/useless_parens.rs25
11 files changed, 256 insertions, 17 deletions
diff --git a/lib/src/lints/bool_comparison.rs b/lib/src/lints/bool_comparison.rs
index 6636faf..5c9bee8 100644
--- a/lib/src/lints/bool_comparison.rs
+++ b/lib/src/lints/bool_comparison.rs
@@ -7,28 +7,25 @@ use rnix::{
7 NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, 7 NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode,
8}; 8};
9 9
10/// What it does 10/// ## What it does
11/// ------------ 11/// Checks for expressions of the form `x == true`, `x != true` and
12/// Checks for expressions of the form x == true, x != true and
13/// suggests using the variable directly. 12/// suggests using the variable directly.
14/// 13///
15/// Why is this bad? 14/// ## Why is this bad?
16/// ----------------
17/// Unnecessary code. 15/// Unnecessary code.
18/// 16///
19/// Example 17/// ## Example
20/// -------- 18/// Instead of checking the value of `x`:
21/// Instead of checking the value of x:
22/// 19///
23/// if x == true 20/// ```
24/// then 0 21/// if x == true then 0 else 1
25/// else 1 22/// ```
26/// 23///
27/// Use x directly: 24/// Use `x` directly:
28/// 25///
29/// if x 26/// ```
30/// then 0 27/// if x then 0 else 1
31/// else 1 28/// ```
32#[lint( 29#[lint(
33 name = "bool_comparison", 30 name = "bool_comparison",
34 note = "Unnecessary comparison with boolean", 31 note = "Unnecessary comparison with boolean",
diff --git a/lib/src/lints/collapsible_let_in.rs b/lib/src/lints/collapsible_let_in.rs
index cb76c37..21199a8 100644
--- a/lib/src/lints/collapsible_let_in.rs
+++ b/lib/src/lints/collapsible_let_in.rs
@@ -8,6 +8,34 @@ use rnix::{
8}; 8};
9use rowan::Direction; 9use rowan::Direction;
10 10
11/// ## What it does
12/// Checks for `let-in` expressions whose body is another `let-in`
13/// expression.
14///
15/// ## Why is this bad?
16/// Unnecessary code, the `let-in` expressions can be merged.
17///
18/// ## Example
19///
20/// ```
21/// let
22/// a = 2;
23/// in
24/// let
25/// b = 3;
26/// in
27/// a + b
28/// ```
29///
30/// Merge both `let-in` expressions:
31///
32/// ```
33/// let
34/// a = 2;
35/// b = 3;
36/// in
37/// a + b
38/// ```
11#[lint( 39#[lint(
12 name = "collapsible let in", 40 name = "collapsible let in",
13 note = "These let-in expressions are collapsible", 41 note = "These let-in expressions are collapsible",
diff --git a/lib/src/lints/empty_let_in.rs b/lib/src/lints/empty_let_in.rs
index 4e0887d..b255c23 100644
--- a/lib/src/lints/empty_let_in.rs
+++ b/lib/src/lints/empty_let_in.rs
@@ -7,7 +7,24 @@ use rnix::{
7 NodeOrToken, SyntaxElement, SyntaxKind, 7 NodeOrToken, SyntaxElement, SyntaxKind,
8}; 8};
9 9
10/// empty let-in found 10/// ## What it does
11/// Checks for `let-in` expressions which create no new bindings.
12///
13/// ## Why is this bad?
14/// `let-in` expressions that create no new bindings are useless.
15/// These are probably remnants from debugging or editing expressions.
16///
17/// ## Example
18///
19/// ```
20/// let in pkgs.statix
21/// ```
22///
23/// Preserve only the body of the `let-in` expression:
24///
25/// ```
26/// pkgs.statix
27/// ```
11#[lint( 28#[lint(
12 name = "empty let-in", 29 name = "empty let-in",
13 note = "Useless let-in expression", 30 note = "Useless let-in expression",
diff --git a/lib/src/lints/empty_pattern.rs b/lib/src/lints/empty_pattern.rs
index ef47c69..5312548 100644
--- a/lib/src/lints/empty_pattern.rs
+++ b/lib/src/lints/empty_pattern.rs
@@ -7,6 +7,33 @@ use rnix::{
7 NodeOrToken, SyntaxElement, SyntaxKind, 7 NodeOrToken, SyntaxElement, SyntaxKind,
8}; 8};
9 9
10/// ## What it does
11/// Checks for an empty variadic pattern: `{...}`, in a function
12/// argument.
13///
14/// ## Why is this bad?
15/// The intention with empty patterns is not instantly obvious. Prefer
16/// an underscore identifier instead, to indicate that the argument
17/// is being ignored.
18///
19/// ## Example
20///
21/// ```
22/// client = { ... }: {
23/// imports = [ self.nixosModules.irmaseal-pkg ];
24/// services.irmaseal-pkg.enable = true;
25/// };
26/// ```
27///
28/// Replace the empty variadic pattern with `_` to indicate that you
29/// intend to ignore the argument:
30///
31/// ```
32/// client = _: {
33/// imports = [ self.nixosModules.irmaseal-pkg ];
34/// services.irmaseal-pkg.enable = true;
35/// };
36/// ```
10#[lint( 37#[lint(
11 name = "empty pattern", 38 name = "empty pattern",
12 note = "Found empty pattern in function argument", 39 note = "Found empty pattern in function argument",
diff --git a/lib/src/lints/eta_reduction.rs b/lib/src/lints/eta_reduction.rs
index b329ae8..3a483d0 100644
--- a/lib/src/lints/eta_reduction.rs
+++ b/lib/src/lints/eta_reduction.rs
@@ -7,6 +7,32 @@ use rnix::{
7 NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, 7 NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode,
8}; 8};
9 9
10/// ## What it does
11/// Checks for eta-reducible functions, i.e.: converts lambda
12/// expressions into free standing functions where applicable.
13///
14/// ## Why is this bad?
15/// Oftentimes, eta-reduction results in code that is more natural
16/// to read.
17///
18/// ## Example
19///
20/// ```
21/// let
22/// double = i: 2 * i;
23/// in
24/// map (x: double x) [ 1 2 3 ]
25/// ```
26///
27/// The lambda passed to the `map` function is eta-reducible, and the
28/// result reads more naturally:
29///
30/// ```
31/// let
32/// double = i: 2 * i;
33/// in
34/// map double [ 1 2 3 ]
35/// ```
10#[lint( 36#[lint(
11 name = "eta reduction", 37 name = "eta reduction",
12 note = "This function expression is eta reducible", 38 note = "This function expression is eta reducible",
diff --git a/lib/src/lints/legacy_let_syntax.rs b/lib/src/lints/legacy_let_syntax.rs
index 8b37df8..139f633 100644
--- a/lib/src/lints/legacy_let_syntax.rs
+++ b/lib/src/lints/legacy_let_syntax.rs
@@ -7,6 +7,34 @@ use rnix::{
7 NodeOrToken, SyntaxElement, SyntaxKind, 7 NodeOrToken, SyntaxElement, SyntaxKind,
8}; 8};
9 9
10/// ## What it does
11/// Checks for legacy-let syntax that was never formalized.
12///
13/// ## Why is this bad?
14/// This syntax construct is undocumented, refrain from using it.
15///
16/// ## Example
17///
18/// Legacy let syntax makes use of an attribute set annotated with
19/// `let` and expects a `body` attribute.
20/// ```
21/// let {
22/// body = x + y;
23/// x = 2;
24/// y = 3;
25/// }
26/// ```
27///
28/// This is trivially representible via `rec`, which is documented
29/// and more widely known:
30///
31/// ```
32/// rec {
33/// body = x + y;
34/// x = 2;
35/// y = 3;
36/// }.body
37/// ```
10#[lint( 38#[lint(
11 name = "legacy let syntax", 39 name = "legacy let syntax",
12 note = "Using undocumented `let` syntax", 40 note = "Using undocumented `let` syntax",
diff --git a/lib/src/lints/manual_inherit.rs b/lib/src/lints/manual_inherit.rs
index 1c10cbf..2d119c3 100644
--- a/lib/src/lints/manual_inherit.rs
+++ b/lib/src/lints/manual_inherit.rs
@@ -7,6 +7,30 @@ use rnix::{
7 NodeOrToken, SyntaxElement, SyntaxKind, 7 NodeOrToken, SyntaxElement, SyntaxKind,
8}; 8};
9 9
10/// ## What it does
11/// Checks for bindings of the form `a = a`.
12///
13/// ## Why is this bad?
14/// If the aim is to bring attributes from a larger scope into
15/// the current scope, prefer an inherit statement.
16///
17/// ## Example
18///
19/// ```
20/// let
21/// a = 2;
22/// in
23/// { a = a; b = 3; }
24/// ```
25///
26/// Try `inherit` instead:
27///
28/// ```
29/// let
30/// a = 2;
31/// in
32/// { inherit a; b = 3; }
33/// ```
10#[lint( 34#[lint(
11 name = "manual inherit", 35 name = "manual inherit",
12 note = "Assignment instead of inherit", 36 note = "Assignment instead of inherit",
diff --git a/lib/src/lints/manual_inherit_from.rs b/lib/src/lints/manual_inherit_from.rs
index 146d55b..8d0f539 100644
--- a/lib/src/lints/manual_inherit_from.rs
+++ b/lib/src/lints/manual_inherit_from.rs
@@ -7,6 +7,30 @@ use rnix::{
7 NodeOrToken, SyntaxElement, SyntaxKind, 7 NodeOrToken, SyntaxElement, SyntaxKind,
8}; 8};
9 9
10/// ## What it does
11/// Checks for bindings of the form `a = someAttr.a`.
12///
13/// ## Why is this bad?
14/// If the aim is to extract or bring attributes of an attrset into
15/// scope, prefer an inherit statement.
16///
17/// ## Example
18///
19/// ```
20/// let
21/// mtl = pkgs.haskellPackages.mtl;
22/// in
23/// null
24/// ```
25///
26/// Try `inherit` instead:
27///
28/// ```
29/// let
30/// inherit (pkgs.haskellPackages) mtl;
31/// in
32/// null
33/// ```
10#[lint( 34#[lint(
11 name = "manual inherit from", 35 name = "manual inherit from",
12 note = "Assignment instead of inherit from", 36 note = "Assignment instead of inherit from",
diff --git a/lib/src/lints/redundant_pattern_bind.rs b/lib/src/lints/redundant_pattern_bind.rs
index ad1aba8..5b0711f 100644
--- a/lib/src/lints/redundant_pattern_bind.rs
+++ b/lib/src/lints/redundant_pattern_bind.rs
@@ -7,10 +7,29 @@ use rnix::{
7 NodeOrToken, SyntaxElement, SyntaxKind, 7 NodeOrToken, SyntaxElement, SyntaxKind,
8}; 8};
9 9
10/// ## What it does
11/// Checks for binds of the form `inputs @ { ... }` in function
12/// arguments.
13///
14/// ## Why is this bad?
15/// The variadic pattern here is redundant, as it does not capture
16/// anything.
17///
18/// ## Example
19///
20/// ```
21/// inputs @ { ... }: inputs.nixpkgs
22/// ```
23///
24/// Remove the pattern altogether:
25///
26/// ```
27/// inputs: inputs.nixpkgs
28/// ```
10#[lint( 29#[lint(
11 name = "redundant pattern bind", 30 name = "redundant pattern bind",
12 note = "Found redundant pattern bind in function argument", 31 note = "Found redundant pattern bind in function argument",
13 code = 10, 32 code = 11,
14 match_with = SyntaxKind::NODE_PATTERN 33 match_with = SyntaxKind::NODE_PATTERN
15)] 34)]
16struct RedundantPatternBind; 35struct RedundantPatternBind;
diff --git a/lib/src/lints/unquoted_splice.rs b/lib/src/lints/unquoted_splice.rs
index 2831c1b..c2fd6e4 100644
--- a/lib/src/lints/unquoted_splice.rs
+++ b/lib/src/lints/unquoted_splice.rs
@@ -7,6 +7,30 @@ use rnix::{
7 NodeOrToken, SyntaxElement, SyntaxKind, 7 NodeOrToken, SyntaxElement, SyntaxKind,
8}; 8};
9 9
10/// ## What it does
11/// Checks for antiquote/splice expressions that are not quoted.
12///
13/// ## Why is this bad?
14/// An *anti*quoted expression should always occur within a *quoted*
15/// expression.
16///
17/// ## Example
18///
19/// ```
20/// let
21/// pkgs = nixpkgs.legacyPackages.${system};
22/// in
23/// pkgs
24/// ```
25///
26/// Quote the splice expression:
27///
28/// ```
29/// let
30/// pkgs = nixpkgs.legacyPackages."${system}";
31/// in
32/// pkgs
33/// ```
10#[lint( 34#[lint(
11 name = "unquoted splice", 35 name = "unquoted splice",
12 note = "Found unquoted splice expression", 36 note = "Found unquoted splice expression",
diff --git a/lib/src/lints/useless_parens.rs b/lib/src/lints/useless_parens.rs
index 9dfeabb..36ad1b7 100644
--- a/lib/src/lints/useless_parens.rs
+++ b/lib/src/lints/useless_parens.rs
@@ -7,6 +7,31 @@ use rnix::{
7 NodeOrToken, SyntaxElement, SyntaxKind, 7 NodeOrToken, SyntaxElement, SyntaxKind,
8}; 8};
9 9
10/// ## What it does
11/// Checks for unnecessary parentheses.
12///
13/// ## Why is this bad?
14/// Unnecessarily parenthesized code is hard to read.
15///
16/// ## Example
17///
18/// ```
19/// let
20/// double = (x: 2 * x);
21/// ls = map (double) [ 1 2 3 ];
22/// in
23/// (2 + 3)
24/// ```
25///
26/// Remove unnecessary parentheses:
27///
28/// ```
29/// let
30/// double = x: 2 * x;
31/// ls = map double [ 1 2 3 ];
32/// in
33/// 2 + 3
34/// ```
10#[lint( 35#[lint(
11 name = "useless parens", 36 name = "useless parens",
12 note = "These parentheses can be omitted", 37 note = "These parentheses can be omitted",