From c6ea58410cb6145cf2791f0ae0d1918cf0d5bc62 Mon Sep 17 00:00:00 2001 From: Akshay Date: Fri, 8 Oct 2021 21:47:07 +0530 Subject: new lint: eta_reduction --- lib/src/lints.rs | 1 + lib/src/lints/eta_reduction.rs | 51 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 lib/src/lints/eta_reduction.rs diff --git a/lib/src/lints.rs b/lib/src/lints.rs index 7da4933..868cd26 100644 --- a/lib/src/lints.rs +++ b/lib/src/lints.rs @@ -7,4 +7,5 @@ lint_map! { manual_inherit_from, legacy_let_syntax, collapsible_let_in, + eta_reduction, } diff --git a/lib/src/lints/eta_reduction.rs b/lib/src/lints/eta_reduction.rs new file mode 100644 index 0000000..8c34205 --- /dev/null +++ b/lib/src/lints/eta_reduction.rs @@ -0,0 +1,51 @@ +use crate::{Lint, Metadata, Report, Rule, Suggestion}; + +use if_chain::if_chain; +use macros::lint; +use rnix::{ + types::{Lambda, Ident, Apply, TypedNode, TokenWrapper}, + NodeOrToken, SyntaxElement, SyntaxKind, +}; + +#[lint( + name = "eta reduction", + note = "This function expression is eta reducible", + code = 7, + match_with = SyntaxKind::NODE_LAMBDA +)] +struct EtaReduction; + +impl Rule for EtaReduction { + fn validate(&self, node: &SyntaxElement) -> Option { + if_chain! { + if let NodeOrToken::Node(node) = node; + if let Some(lambda_expr) = Lambda::cast(node.clone()); + + if let Some(arg_node) = lambda_expr.arg(); + if let Some(arg) = Ident::cast(arg_node); + + if let Some(body_node) = lambda_expr.body(); + if let Some(body) = Apply::cast(body_node); + + if let Some(value_node) = body.value(); + if let Some(value) = Ident::cast(value_node); + + if arg.as_str() == value.as_str() ; + + then { + let at = node.text_range(); + let replacement = body.lambda()?; + let message = + format!( + "Found eta-reduction: `{}`", + replacement.text().to_string() + ); + Some(Self::report().suggest(at, message, Suggestion::new(at, replacement))) + } else { + None + } + } + } +} + + -- cgit v1.2.3