mirror of
https://github.com/nerdypepper/statix.git
synced 2024-09-11 13:45:32 +03:00
add 3 new lints, bump to v0.2.3
- empty_pattern - redundant_pattern_bind - unquoted_splice
This commit is contained in:
parent
f909b20c54
commit
8eccf15964
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -388,7 +388,7 @@ checksum = "b203e79e90905594272c1c97c7af701533d42adaab0beb3859018e477d54a3b0"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "statix"
|
name = "statix"
|
||||||
version = "0.2.0"
|
version = "0.2.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ariadne",
|
"ariadne",
|
||||||
"clap",
|
"clap",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "statix"
|
name = "statix"
|
||||||
version = "0.2.2"
|
version = "0.2.3"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
|
|
||||||
statix = with final; pkgs.stdenv.mkDerivation {
|
statix = with final; pkgs.stdenv.mkDerivation {
|
||||||
pname = "statix";
|
pname = "statix";
|
||||||
version = "v0.2.2";
|
version = "v0.2.3";
|
||||||
src = builtins.path {
|
src = builtins.path {
|
||||||
path = ./.;
|
path = ./.;
|
||||||
name = "statix";
|
name = "statix";
|
||||||
|
@ -9,4 +9,7 @@ lint_map! {
|
|||||||
collapsible_let_in,
|
collapsible_let_in,
|
||||||
eta_reduction,
|
eta_reduction,
|
||||||
useless_parens,
|
useless_parens,
|
||||||
|
unquoted_splice,
|
||||||
|
empty_pattern,
|
||||||
|
redundant_pattern_bind,
|
||||||
}
|
}
|
||||||
|
37
lib/src/lints/empty_pattern.rs
Normal file
37
lib/src/lints/empty_pattern.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
41
lib/src/lints/redundant_pattern_bind.rs
Normal file
41
lib/src/lints/redundant_pattern_bind.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
33
lib/src/lints/unquoted_splice.rs
Normal file
33
lib/src/lints/unquoted_splice.rs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -24,6 +24,10 @@ pub fn parenthesize(node: &SyntaxNode) -> types::Paren {
|
|||||||
ast_from_text(&format!("({})", node))
|
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 {
|
pub fn unary_not(node: &SyntaxNode) -> types::UnaryOp {
|
||||||
ast_from_text(&format!("!{}", node))
|
ast_from_text(&format!("!{}", node))
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,13 @@ Lint ideas
|
|||||||
- manual map over list
|
- manual map over list
|
||||||
- merge inherit
|
- merge inherit
|
||||||
- merge inherit-from
|
- 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
|
Extensions
|
||||||
----------
|
----------
|
||||||
|
Loading…
Reference in New Issue
Block a user