diff options
-rw-r--r-- | bin/tests/data/empty_pattern.nix | 8 | ||||
-rw-r--r-- | lib/src/lints/empty_pattern.rs | 36 |
2 files changed, 37 insertions, 7 deletions
diff --git a/bin/tests/data/empty_pattern.nix b/bin/tests/data/empty_pattern.nix index 23d99e8..2df5445 100644 --- a/bin/tests/data/empty_pattern.nix +++ b/bin/tests/data/empty_pattern.nix | |||
@@ -5,5 +5,13 @@ | |||
5 | # don't match | 5 | # don't match |
6 | ({ a, ... }: a) | 6 | ({ a, ... }: a) |
7 | ({ ... } @ inputs: inputs) | 7 | ({ ... } @ inputs: inputs) |
8 | |||
9 | # nixos module, don't match | ||
10 | ({ ... }: { | ||
11 | imports = [ | ||
12 | ./module.nix | ||
13 | /path/to/absolute/module.nix | ||
14 | ]; | ||
15 | }) | ||
8 | ] | 16 | ] |
9 | 17 | ||
diff --git a/lib/src/lints/empty_pattern.rs b/lib/src/lints/empty_pattern.rs index e03708b..b399ba2 100644 --- a/lib/src/lints/empty_pattern.rs +++ b/lib/src/lints/empty_pattern.rs | |||
@@ -3,8 +3,8 @@ use crate::{make, session::SessionInfo, Metadata, Report, Rule, Suggestion}; | |||
3 | use if_chain::if_chain; | 3 | use if_chain::if_chain; |
4 | use macros::lint; | 4 | use macros::lint; |
5 | use rnix::{ | 5 | use rnix::{ |
6 | types::{Pattern, TypedNode}, | 6 | types::{AttrSet, EntryHolder, Lambda, Pattern, TypedNode}, |
7 | NodeOrToken, SyntaxElement, SyntaxKind, | 7 | NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, |
8 | }; | 8 | }; |
9 | 9 | ||
10 | /// ## What it does | 10 | /// ## What it does |
@@ -20,7 +20,6 @@ use rnix::{ | |||
20 | /// | 20 | /// |
21 | /// ```nix | 21 | /// ```nix |
22 | /// client = { ... }: { | 22 | /// client = { ... }: { |
23 | /// imports = [ self.nixosModules.irmaseal-pkg ]; | ||
24 | /// services.irmaseal-pkg.enable = true; | 23 | /// services.irmaseal-pkg.enable = true; |
25 | /// }; | 24 | /// }; |
26 | /// ``` | 25 | /// ``` |
@@ -30,7 +29,6 @@ use rnix::{ | |||
30 | /// | 29 | /// |
31 | /// ```nix | 30 | /// ```nix |
32 | /// client = _: { | 31 | /// client = _: { |
33 | /// imports = [ self.nixosModules.irmaseal-pkg ]; | ||
34 | /// services.irmaseal-pkg.enable = true; | 32 | /// services.irmaseal-pkg.enable = true; |
35 | /// }; | 33 | /// }; |
36 | /// ``` | 34 | /// ``` |
@@ -38,7 +36,7 @@ use rnix::{ | |||
38 | name = "empty_pattern", | 36 | name = "empty_pattern", |
39 | note = "Found empty pattern in function argument", | 37 | note = "Found empty pattern in function argument", |
40 | code = 10, | 38 | code = 10, |
41 | match_with = SyntaxKind::NODE_PATTERN | 39 | match_with = SyntaxKind::NODE_LAMBDA |
42 | )] | 40 | )] |
43 | struct EmptyPattern; | 41 | struct EmptyPattern; |
44 | 42 | ||
@@ -46,13 +44,21 @@ impl Rule for EmptyPattern { | |||
46 | fn validate(&self, node: &SyntaxElement, _sess: &SessionInfo) -> Option<Report> { | 44 | fn validate(&self, node: &SyntaxElement, _sess: &SessionInfo) -> Option<Report> { |
47 | if_chain! { | 45 | if_chain! { |
48 | if let NodeOrToken::Node(node) = node; | 46 | if let NodeOrToken::Node(node) = node; |
49 | if let Some(pattern) = Pattern::cast(node.clone()); | 47 | if let Some(lambda_expr) = Lambda::cast(node.clone()); |
48 | if let Some(arg) = lambda_expr.arg(); | ||
49 | if let Some(body) = lambda_expr.body(); | ||
50 | |||
51 | if let Some(pattern) = Pattern::cast(arg.clone()); | ||
50 | // no patterns within `{ }` | 52 | // no patterns within `{ }` |
51 | if pattern.entries().count() == 0; | 53 | if pattern.entries().count() == 0; |
52 | // pattern is not bound | 54 | // pattern is not bound |
53 | if pattern.at().is_none(); | 55 | if pattern.at().is_none(); |
56 | |||
57 | // not a nixos module | ||
58 | if !is_module(&body); | ||
59 | |||
54 | then { | 60 | then { |
55 | let at = node.text_range(); | 61 | let at = pattern.node().text_range(); |
56 | let message = "This pattern is empty, use `_` instead"; | 62 | let message = "This pattern is empty, use `_` instead"; |
57 | let replacement = make::ident("_").node().clone(); | 63 | let replacement = make::ident("_").node().clone(); |
58 | Some(self.report().suggest(at, message, Suggestion::new(at, replacement))) | 64 | Some(self.report().suggest(at, message, Suggestion::new(at, replacement))) |
@@ -62,3 +68,19 @@ impl Rule for EmptyPattern { | |||
62 | } | 68 | } |
63 | } | 69 | } |
64 | } | 70 | } |
71 | |||
72 | fn is_module(body: &SyntaxNode) -> bool { | ||
73 | if_chain! { | ||
74 | if let Some(attr_set) = AttrSet::cast(body.clone()); | ||
75 | if attr_set | ||
76 | .entries() | ||
77 | .map(|e| e.key()) | ||
78 | .flatten() | ||
79 | .any(|k| k.node().to_string() == "imports"); | ||
80 | then { | ||
81 | true | ||
82 | } else { | ||
83 | false | ||
84 | } | ||
85 | } | ||
86 | } | ||