add snapshot test suite

This commit is contained in:
Akshay 2021-11-03 14:48:35 +05:30
parent 78decf580d
commit 4e063b2abc
35 changed files with 665 additions and 49 deletions

186
Cargo.lock generated
View File

@ -20,6 +20,12 @@ dependencies = [
"yansi",
]
[[package]]
name = "arrayvec"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "atty"
version = "0.2.14"
@ -69,9 +75,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "3.0.0-beta.4"
version = "3.0.0-beta.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcd70aa5597dbc42f7217a543f9ef2768b2ef823ba29036072d30e1d88e98406"
checksum = "feff3878564edb93745d58cf63e17b63f24142506e7a20c87a5521ed7bfb1d63"
dependencies = [
"atty",
"bitflags",
@ -82,14 +88,14 @@ dependencies = [
"strsim",
"termcolor",
"textwrap",
"vec_map",
"unicase",
]
[[package]]
name = "clap_derive"
version = "3.0.0-beta.4"
version = "3.0.0-beta.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b5bb0d655624a0b8770d1c178fb8ffcb1f91cc722cb08f451e3dc72465421ac"
checksum = "8b15c6b4f786ffb6192ffe65a36855bc1fc2444bcd0945ae16748dcd6ed7d0d3"
dependencies = [
"heck",
"proc-macro-error",
@ -98,6 +104,19 @@ dependencies = [
"syn",
]
[[package]]
name = "console"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3993e6445baa160675931ec041a5e03ca84b9c6e32a056150d3aa2bdda0a1f45"
dependencies = [
"encode_unicode",
"lazy_static",
"libc",
"terminal_size",
"winapi",
]
[[package]]
name = "countme"
version = "2.0.4"
@ -114,6 +133,18 @@ dependencies = [
"lazy_static",
]
[[package]]
name = "dtoa"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0"
[[package]]
name = "encode_unicode"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]]
name = "fnv"
version = "1.0.7"
@ -197,6 +228,21 @@ dependencies = [
"hashbrown 0.11.2",
]
[[package]]
name = "insta"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15226a375927344c78d39dc6b49e2d5562a5b0705e26a589093c6792e52eed8e"
dependencies = [
"console",
"lazy_static",
"serde",
"serde_json",
"serde_yaml",
"similar 1.3.0",
"uuid",
]
[[package]]
name = "itoa"
version = "0.4.8"
@ -224,9 +270,15 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.103"
version = "0.2.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6"
checksum = "a60553f9a9e039a333b4e9b20573b9e9b9c0bb3a11e201ccc48ef4283456d673"
[[package]]
name = "linked-hash-map"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
[[package]]
name = "log"
@ -278,9 +330,12 @@ checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
[[package]]
name = "os_str_bytes"
version = "3.1.0"
version = "4.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6acbef58a60fe69ab50510a55bc8cdd4d6cf2283d27ad338f54cb52747a9cf2d"
checksum = "addaa943333a514159c80c97ff4a93306530d965d27e139188283cd13e06a799"
dependencies = [
"memchr",
]
[[package]]
name = "proc-macro-error"
@ -308,18 +363,18 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.29"
version = "1.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d"
checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.9"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
dependencies = [
"proc-macro2",
]
@ -343,9 +398,9 @@ checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "rnix"
version = "0.9.0"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b37f8af07a0354606141df076458660af7e22238e4117a041c21c548080addd"
checksum = "294becb48f58c496d96c10a12df290266204ca75c9799be4d04222bfaebb6a37"
dependencies = [
"cbitset",
"rowan",
@ -417,6 +472,24 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_yaml"
version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8c608a35705a5d3cdc9fbe403147647ff34b921f8e833e49306df898f9b20af"
dependencies = [
"dtoa",
"indexmap",
"serde",
"yaml-rust",
]
[[package]]
name = "similar"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad1d488a557b235fc46dae55512ffbfc429d2482b08b4d9435ab07384ca8aec"
[[package]]
name = "similar"
version = "2.1.0"
@ -425,9 +498,12 @@ checksum = "2e24979f63a11545f5f2c60141afe249d4f19f84581ea2138065e400941d83d3"
[[package]]
name = "smol_str"
version = "0.1.18"
version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b203e79e90905594272c1c97c7af701533d42adaab0beb3859018e477d54a3b0"
checksum = "559b173452ec4061933b0c0e22d7d429c90ecdc1b3ae1c6e64238e7c15c3ee15"
dependencies = [
"serde",
]
[[package]]
name = "statix"
@ -436,15 +512,26 @@ dependencies = [
"ariadne",
"clap",
"ignore",
"insta",
"lib",
"rnix",
"serde",
"serde_json",
"similar",
"similar 2.1.0",
"strip-ansi-escapes",
"thiserror",
"vfs",
]
[[package]]
name = "strip-ansi-escapes"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "011cbb39cf7c1f62871aea3cc46e5817b0937b49e9447370c93cacbe93a766d8"
dependencies = [
"vte",
]
[[package]]
name = "strsim"
version = "0.10.0"
@ -453,9 +540,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "syn"
version = "1.0.76"
version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6f107db402c2c2055242dbf4d2af0e69197202e9faacbef9571bbe47f5a1b84"
checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966"
dependencies = [
"proc-macro2",
"quote",
@ -471,6 +558,16 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "terminal_size"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "text-size"
version = "1.1.0"
@ -515,6 +612,15 @@ dependencies = [
"once_cell",
]
[[package]]
name = "unicase"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
dependencies = [
"version_check",
]
[[package]]
name = "unicode-segmentation"
version = "1.8.0"
@ -534,10 +640,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "vec_map"
name = "utf8parse"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372"
[[package]]
name = "uuid"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
[[package]]
name = "version_check"
@ -552,6 +664,27 @@ dependencies = [
"indexmap",
]
[[package]]
name = "vte"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6cbce692ab4ca2f1f3047fcf732430249c0e971bfdd2b234cf2c47ad93af5983"
dependencies = [
"arrayvec",
"utf8parse",
"vte_generate_state_changes",
]
[[package]]
name = "vte_generate_state_changes"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ff"
dependencies = [
"proc-macro2",
"quote",
]
[[package]]
name = "walkdir"
version = "2.3.2"
@ -594,6 +727,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]
[[package]]
name = "yansi"
version = "0.5.0"

View File

@ -6,7 +6,13 @@ license = "MIT"
authors = [ "Akshay <nerdy@peppe.rs>" ]
description = "Lints and suggestions for the Nix programming language"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
name = "statix"
path = "src/lib.rs"
[[bin]]
name = "statix"
path = "src/main.rs"
[dependencies]
ariadne = "0.1.3"
@ -27,5 +33,9 @@ version = "1.0.68"
features = [ "derive" ]
optional = true
[dev-dependencies]
insta = "1.8.0"
strip-ansi-escapes = "0.1.1"
[features]
json = [ "lib/json-out", "serde_json", "serde" ]

View File

@ -2,17 +2,17 @@ use std::{default::Default, fmt, fs, path::PathBuf, str::FromStr};
use crate::{dirs, err::ConfigErr};
use clap::Clap;
use clap::Parser;
use vfs::ReadOnlyVfs;
#[derive(Clap, Debug)]
#[derive(Parser, Debug)]
#[clap(version, author, about)]
pub struct Opts {
#[clap(subcommand)]
pub cmd: SubCommand,
}
#[derive(Clap, Debug)]
#[derive(Parser, Debug)]
pub enum SubCommand {
/// Lints and suggestions for the nix programming language
Check(Check),
@ -24,7 +24,7 @@ pub enum SubCommand {
Explain(Explain),
}
#[derive(Clap, Debug)]
#[derive(Parser, Debug)]
pub struct Check {
/// File or directory to run check on
#[clap(default_value = ".", parse(from_os_str))]
@ -67,7 +67,7 @@ impl Check {
}
}
#[derive(Clap, Debug)]
#[derive(Parser, Debug)]
pub struct Fix {
/// File or directory to run fix on
#[clap(default_value = ".", parse(from_os_str))]
@ -127,7 +127,7 @@ impl Fix {
}
}
#[derive(Clap, Debug)]
#[derive(Parser, Debug)]
pub struct Single {
/// File to run single-fix on
#[clap(parse(from_os_str))]
@ -174,7 +174,7 @@ impl Single {
}
}
#[derive(Clap, Debug)]
#[derive(Parser, Debug)]
pub struct Explain {
/// Warning code to explain
#[clap(parse(try_from_str = parse_warning_code))]

7
bin/src/lib.rs Normal file
View File

@ -0,0 +1,7 @@
pub mod config;
pub mod dirs;
pub mod err;
pub mod explain;
pub mod fix;
pub mod lint;
pub mod traits;

View File

@ -1,15 +1,9 @@
mod config;
mod dirs;
mod err;
mod explain;
mod fix;
mod lint;
mod traits;
use crate::err::StatixErr;
use clap::Clap;
use config::{Opts, SubCommand};
use clap::Parser;
use statix::{
config::{Opts, SubCommand},
err::StatixErr,
explain, fix, lint,
};
fn _main() -> Result<(), StatixErr> {
let opts = Opts::parse();

View File

@ -0,0 +1,13 @@
[
# trivial
(a == true)
(b == true)
(true == c)
(true == d)
# not equals
(e != true)
(f != false)
(true != g)
(false != h)
]

View File

@ -0,0 +1,9 @@
let
a = 2;
b = 3;
in
let
c = 5;
d = 6;
in
a + b + c + d

View File

@ -0,0 +1,6 @@
let
e = null;
in
if isNull e
then "no"
else "yes"

View File

@ -0,0 +1,3 @@
let
in
null

View File

@ -0,0 +1,9 @@
[
# match
({ ... }: 42)
# don't match
({ a, ... }: a)
({ ... } @ inputs: inputs)
]

View File

@ -0,0 +1,18 @@
let
double = x: x * 2;
inherit (builtins) map;
xs = [ 1 2 3 ];
f = {
inherit double;
val = 2;
};
in
[
(map (x: double x) xs)
# don't lint on non-free exprs
(map (f: f.double f.val) [ f ])
# other non-free forms
(map (f: {inherit f;}.double f.val) [ f ])
]

View File

@ -0,0 +1,5 @@
let {
body = x + y;
x = "hello,";
y = " world!";
}

View File

@ -0,0 +1,12 @@
let
a = 2;
y = "y";
in
{
# trivial
a = a;
# don't lint
x.y = y;
}

View File

@ -0,0 +1,8 @@
let
a = {b = 2; c = 3;};
in
{
b = a.b;
c = a.c;
}

View File

@ -0,0 +1 @@
{ ... } @ inputs: null

View File

@ -0,0 +1,15 @@
let
x = 2;
y = 3;
a = { "2" = y; };
in
[
${x}
${toString (x + y)}
a.${toString x}
# multiline test
${
toString x
}
]

View File

@ -0,0 +1 @@
github:nerdypepper/statix

View File

@ -0,0 +1,16 @@
let
# parens around primitives
a = {
b = ("hello");
c = (d);
e = ({ f = 2; });
};
# parens around let-value
g = (1 + 2);
h = ({ inherit i; });
# TODO: binary exprs, function args etc.
in
# parens around let body
(null)

47
bin/tests/main.rs Normal file
View File

@ -0,0 +1,47 @@
mod util {
#[macro_export]
macro_rules! test_lint {
($($tname:ident),*,) => {
test_lint!($($tname),*);
};
($($tname:ident),*) => {
$(
#[test]
fn $tname() {
use statix::{config::OutFormat, traits::WriteDiagnostic, lint};
use vfs::ReadOnlyVfs;
let file_path = concat!("data/", stringify!($tname), ".nix");
let contents = include_str!(concat!("data/", stringify!($tname), ".nix"));
let vfs = ReadOnlyVfs::singleton(file_path, contents.as_bytes());
let mut buffer = Vec::new();
vfs.iter().map(lint::lint).for_each(|r| {
buffer.write(&r, &vfs, OutFormat::StdErr).unwrap();
});
let stripped = strip_ansi_escapes::strip(&buffer).unwrap();
let out = std::str::from_utf8(&stripped).unwrap();
insta::assert_snapshot!(&out);
}
)*
};
}
}
test_lint! {
bool_comparison,
empty_let_in,
manual_inherit,
manual_inherit_from,
legacy_let_syntax,
collapsible_let_in,
eta_reduction,
useless_parens,
unquoted_splices,
empty_pattern,
redundant_pattern_bind,
unquoted_uri,
deprecated_is_null,
}

View File

@ -0,0 +1,62 @@
---
source: bin/tests/main.rs
expression: "&out"
---
[W01] Warning: Unnecessary comparison with boolean
╭─[data/bool_comparison.nix:3:4]
3 │ (a == true)
· ────┬────
· ╰────── Comparing a with boolean literal true
───╯
[W01] Warning: Unnecessary comparison with boolean
╭─[data/bool_comparison.nix:4:4]
4 │ (b == true)
· ────┬────
· ╰────── Comparing b with boolean literal true
───╯
[W01] Warning: Unnecessary comparison with boolean
╭─[data/bool_comparison.nix:5:4]
5 │ (true == c)
· ────┬────
· ╰────── Comparing c with boolean literal true
───╯
[W01] Warning: Unnecessary comparison with boolean
╭─[data/bool_comparison.nix:6:4]
6 │ (true == d)
· ────┬────
· ╰────── Comparing d with boolean literal true
───╯
[W01] Warning: Unnecessary comparison with boolean
╭─[data/bool_comparison.nix:9:4]
9 │ (e != true)
· ────┬────
· ╰────── Comparing e with boolean literal true
───╯
[W01] Warning: Unnecessary comparison with boolean
╭─[data/bool_comparison.nix:10:4]
10 │ (f != false)
· ─────┬────
· ╰────── Comparing f with boolean literal false
────╯
[W01] Warning: Unnecessary comparison with boolean
╭─[data/bool_comparison.nix:11:4]
11 │ (true != g)
· ────┬────
· ╰────── Comparing g with boolean literal true
────╯
[W01] Warning: Unnecessary comparison with boolean
╭─[data/bool_comparison.nix:12:4]
12 │ (false != h)
· ─────┬────
· ╰────── Comparing h with boolean literal false
────╯

View File

@ -0,0 +1,17 @@
---
source: bin/tests/main.rs
expression: "&out"
---
[W06] Warning: These let-in expressions are collapsible
╭─[data/collapsible_let_in.nix:1:1]
1 │ ╭───▶ let
5 │ │ ╭─▶ let
9 │ │ ├─▶ a + b + c + d
· │ │ │
· │ ╰───────────────────── This let in expression is nested
· │ │
· ╰───────────────────┴─── This let in expression contains a nested let in expression
───╯

View File

@ -0,0 +1,13 @@
---
source: bin/tests/main.rs
expression: "&out"
---
[W13] Warning: Found usage of deprecated builtin isNull
╭─[data/deprecated_is_null.nix:4:4]
4 │ if isNull e
· ────┬───
· ╰───── isNull is deprecated, check equality with null instead
───╯

View File

@ -0,0 +1,14 @@
---
source: bin/tests/main.rs
expression: "&out"
---
[W02] Warning: Useless let-in expression
╭─[data/empty_let_in.nix:1:1]
1 │ ╭─▶ let
3 │ ├─▶ null
· │
· ╰──────────── This let-in expression has no entries
───╯

View File

@ -0,0 +1,20 @@
---
source: bin/tests/main.rs
expression: "&out"
---
[W10] Warning: Found empty pattern in function argument
╭─[data/empty_pattern.nix:3:4]
3 │ ({ ... }: 42)
· ───┬───
· ╰───── This pattern is empty, use _ instead
───╯
[W11] Warning: Found redundant pattern bind in function argument
╭─[data/empty_pattern.nix:7:4]
7 │ ({ ... } @ inputs: inputs)
· ────────┬───────
· ╰───────── This pattern bind is redundant, use inputs instead
───╯

View File

@ -0,0 +1,13 @@
---
source: bin/tests/main.rs
expression: "&out"
---
[W07] Warning: This function expression is eta reducible
╭─[data/eta_reduction.nix:11:9]
11 │ (map (x: double x) xs)
· ─────┬─────
· ╰─────── Found eta-reduction: double
────╯

View File

@ -0,0 +1,14 @@
---
source: bin/tests/main.rs
expression: "&out"
---
[W05] Warning: Using undocumented `let` syntax
╭─[data/legacy_let_syntax.nix:1:1]
1 │ ╭─▶ let {
5 │ ├─▶ }
· │
· ╰─────── Prefer rec over undocumented let syntax
───╯

View File

@ -0,0 +1,13 @@
---
source: bin/tests/main.rs
expression: "&out"
---
[W03] Warning: Assignment instead of inherit
╭─[data/manual_inherit.nix:7:3]
7 │ a = a;
· ───┬──
· ╰──── This assignment is better written with inherit
───╯

View File

@ -0,0 +1,20 @@
---
source: bin/tests/main.rs
expression: "&out"
---
[W04] Warning: Assignment instead of inherit from
╭─[data/manual_inherit_from.nix:5:3]
5 │ b = a.b;
· ────┬───
· ╰───── This assignment is better written with inherit
───╯
[W04] Warning: Assignment instead of inherit from
╭─[data/manual_inherit_from.nix:6:3]
6 │ c = a.c;
· ────┬───
· ╰───── This assignment is better written with inherit
───╯

View File

@ -0,0 +1,13 @@
---
source: bin/tests/main.rs
expression: "&out"
---
[W11] Warning: Found redundant pattern bind in function argument
╭─[data/redundant_pattern_bind.nix:1:1]
1 │ { ... } @ inputs: null
· ────────┬────────
· ╰────────── This pattern bind is redundant, use inputs instead
───╯

View File

@ -0,0 +1,35 @@
---
source: bin/tests/main.rs
expression: "&out"
---
[W09] Warning: Found unquoted splice expression
╭─[data/unquoted_splices.nix:7:3]
7 │ ${x}
· ──┬─
· ╰─── Consider quoting this splice expression
───╯
[W09] Warning: Found unquoted splice expression
╭─[data/unquoted_splices.nix:8:3]
8 │ ${toString (x + y)}
· ─────────┬─────────
· ╰─────────── Consider quoting this splice expression
───╯
[W09] Warning: Found unquoted splice expression
╭─[data/unquoted_splices.nix:9:5]
9 │ a.${toString x}
· ──────┬──────
· ╰──────── Consider quoting this splice expression
───╯
[W09] Warning: Found unquoted splice expression
╭─[data/unquoted_splices.nix:12:3]
12 │ ╭─▶ ${
14 │ ├─▶ }
· │
· ╰───────── Consider quoting this splice expression
────╯

View File

@ -0,0 +1,13 @@
---
source: bin/tests/main.rs
expression: "&out"
---
[W12] Warning: Found unquoted URI expression
╭─[data/unquoted_uri.nix:1:1]
1 │ github:nerdypepper/statix
· ────────────┬────────────
· ╰────────────── Consider quoting this URI expression
───╯

View File

@ -0,0 +1,48 @@
---
source: bin/tests/main.rs
expression: "&out"
---
[W08] Warning: These parentheses can be omitted
╭─[data/useless_parens.nix:16:3]
16 │ (null)
· ───┬──
· ╰──── Useless parentheses around body of let expression
────╯
[W08] Warning: These parentheses can be omitted
╭─[data/useless_parens.nix:4:9]
4 │ b = ("hello");
· ────┬────
· ╰────── Useless parentheses around value in binding
───╯
[W08] Warning: These parentheses can be omitted
╭─[data/useless_parens.nix:5:9]
5 │ c = (d);
· ─┬─
· ╰─── Useless parentheses around value in binding
───╯
[W08] Warning: These parentheses can be omitted
╭─[data/useless_parens.nix:6:9]
6 │ e = ({ f = 2; });
· ──────┬─────
· ╰─────── Useless parentheses around value in binding
───╯
[W08] Warning: These parentheses can be omitted
╭─[data/useless_parens.nix:10:7]
10 │ g = (1 + 2);
· ───┬───
· ╰───── Useless parentheses around value in binding
────╯
[W08] Warning: These parentheses can be omitted
╭─[data/useless_parens.nix:11:7]
11 │ h = ({ inherit i; });
· ────────┬───────
· ╰───────── Useless parentheses around value in binding
────╯

View File

@ -93,11 +93,12 @@
"clippy"
"rust-src"
];
inherit (fenix.packages."${system}") rust-analyzer;
in
with pkgs;
mkShell rec {
pkgs.mkShell {
nativeBuildInputs = [
cargo-watch
pkgs.cargo-watch
pkgs.cargo-insta
rust-analyzer
toolchain
];

View File

@ -3,7 +3,7 @@ use crate::{Diagnostic, Metadata, Report, Rule, Suggestion};
use if_chain::if_chain;
use macros::lint;
use rnix::{
types::{KeyValue, Paren, ParsedType, TypedNode, Wrapper},
types::{KeyValue, LetIn, Paren, ParsedType, TypedNode, Wrapper},
NodeOrToken, SyntaxElement, SyntaxKind,
};
@ -71,7 +71,7 @@ fn do_thing(parsed_type_node: ParsedType) -> Option<Diagnostic> {
if let Some(inner) = value_in_parens.inner();
then {
let at = value_range;
let message = "Useless parentheses around value in `let` binding";
let message = "Useless parentheses around value in binding";
let replacement = inner;
Some(Diagnostic::suggest(at, message, Suggestion::new(at, replacement)))
} else {
@ -98,7 +98,11 @@ fn do_thing(parsed_type_node: ParsedType) -> Option<Diagnostic> {
// ensure that we don't lint inside let-in statements
// we already lint such cases in previous match stmt
if KeyValue::cast(father_node).is_none();
if KeyValue::cast(father_node.clone()).is_none();
// ensure that we don't lint inside let-bodies
// if this primitive is a let-body, we have already linted it
if LetIn::cast(father_node).is_none();
if let Some(inner_node) = paren_expr.inner();
if let Some(parsed_inner) = ParsedType::cast(inner_node);

View File

@ -7,7 +7,7 @@ use std::{
use indexmap::IndexSet;
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash)]
pub struct FileId(u32);
pub struct FileId(pub u32);
#[derive(Debug, Default)]
pub struct Interner {