add 3 new lints, bump to v0.2.3

- empty_pattern
- redundant_pattern_bind
- unquoted_splice
This commit is contained in:
Akshay 2021-10-27 19:50:52 +05:30
parent f909b20c54
commit 8eccf15964
9 changed files with 128 additions and 3 deletions

2
Cargo.lock generated
View File

@ -388,7 +388,7 @@ checksum = "b203e79e90905594272c1c97c7af701533d42adaab0beb3859018e477d54a3b0"
[[package]]
name = "statix"
version = "0.2.0"
version = "0.2.3"
dependencies = [
"ariadne",
"clap",

View File

@ -1,6 +1,6 @@
[package]
name = "statix"
version = "0.2.2"
version = "0.2.3"
edition = "2018"
license = "MIT"

View File

@ -49,7 +49,7 @@
statix = with final; pkgs.stdenv.mkDerivation {
pname = "statix";
version = "v0.2.2";
version = "v0.2.3";
src = builtins.path {
path = ./.;
name = "statix";

View File

@ -9,4 +9,7 @@ lint_map! {
collapsible_let_in,
eta_reduction,
useless_parens,
unquoted_splice,
empty_pattern,
redundant_pattern_bind,
}

View File

@ -0,0 +1,37 @@
use crate::{make, Lint, Metadata, Report, Rule, Suggestion};
use if_chain::if_chain;
use macros::lint;
use rnix::{
types::{Pattern, TypedNode},
NodeOrToken, SyntaxElement, SyntaxKind,
};
#[lint(
name = "empty pattern",
note = "Found empty pattern in function argument",
code = 10,
match_with = SyntaxKind::NODE_PATTERN
)]
struct EmptyPattern;
impl Rule for EmptyPattern {
fn validate(&self, node: &SyntaxElement) -> Option<Report> {
if_chain! {
if let NodeOrToken::Node(node) = node;
if let Some(pattern) = Pattern::cast(node.clone());
// no patterns within `{ }`
if pattern.entries().count() == 0;
// pattern is not bound
if pattern.at().is_none();
then {
let at = node.text_range();
let message = "This pattern is empty, use `_` instead";
let replacement = make::ident("_").node().clone();
Some(Self::report().suggest(at, message, Suggestion::new(at, replacement)))
} else {
None
}
}
}
}

View File

@ -0,0 +1,41 @@
use crate::{Lint, Metadata, Report, Rule, Suggestion};
use if_chain::if_chain;
use macros::lint;
use rnix::{
types::{Pattern, TokenWrapper, TypedNode},
NodeOrToken, SyntaxElement, SyntaxKind,
};
#[lint(
name = "redundant pattern bind",
note = "Found redundant pattern bind in function argument",
code = 10,
match_with = SyntaxKind::NODE_PATTERN
)]
struct RedundantPatternBind;
impl Rule for RedundantPatternBind {
fn validate(&self, node: &SyntaxElement) -> Option<Report> {
if_chain! {
if let NodeOrToken::Node(node) = node;
if let Some(pattern) = Pattern::cast(node.clone());
// no patterns within `{ }`
if pattern.entries().count() == 0;
// pattern is just ellipsis
if pattern.ellipsis();
// pattern is bound
if let Some(ident) = pattern.at();
then {
let at = node.text_range();
let message = format!("This pattern bind is redundant, use `{}` instead", ident.as_str());
let replacement = ident.node().clone();
Some(Self::report().suggest(at, message, Suggestion::new(at, replacement)))
} else {
None
}
}
}
}

View File

@ -0,0 +1,33 @@
use crate::{make, Lint, Metadata, Report, Rule, Suggestion};
use if_chain::if_chain;
use macros::lint;
use rnix::{
types::{Dynamic, TypedNode},
NodeOrToken, SyntaxElement, SyntaxKind,
};
#[lint(
name = "unquoted splice",
note = "Found unquoted splice expression",
code = 9,
match_with = SyntaxKind::NODE_DYNAMIC
)]
struct UnquotedSplice;
impl Rule for UnquotedSplice {
fn validate(&self, node: &SyntaxElement) -> Option<Report> {
if_chain! {
if let NodeOrToken::Node(node) = node;
if Dynamic::cast(node.clone()).is_some();
then {
let at = node.text_range();
let replacement = make::quote(&node).node().clone();
let message = "Consider quoting this splice expression";
Some(Self::report().suggest(at, message, Suggestion::new(at, replacement)))
} else {
None
}
}
}
}

View File

@ -24,6 +24,10 @@ pub fn parenthesize(node: &SyntaxNode) -> types::Paren {
ast_from_text(&format!("({})", node))
}
pub fn quote(node: &SyntaxNode) -> types::Str {
ast_from_text(&format!("\"{}\"", node))
}
pub fn unary_not(node: &SyntaxNode) -> types::UnaryOp {
ast_from_text(&format!("!{}", node))
}

View File

@ -40,6 +40,13 @@ Lint ideas
- manual map over list
- merge inherit
- merge inherit-from
- empty inherit
- useless antiquote/splice (where is antiquote truly
required?)
- useless variadic (things like `{...} : expr`, replace with
`_: expr`)
- redundant pattern `{...} @ inputs : expr`, replace with
`inputs: expr`
Extensions
----------