From 011a0179d953e3970a1d56c833c3b20503ad2db5 Mon Sep 17 00:00:00 2001 From: Cameron Clark Date: Mon, 2 Dec 2024 17:17:13 +0000 Subject: [PATCH] fix(linter): no-unused-expressions false positive with arrow fn expressions --- .../rules/typescript/no_unused_expressions.rs | 20 ++++++++++++++++++- .../typescript_no_unused_expressions.snap | 7 +++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/crates/oxc_linter/src/rules/typescript/no_unused_expressions.rs b/crates/oxc_linter/src/rules/typescript/no_unused_expressions.rs index ad293e5a94bff..374b4e30e4185 100644 --- a/crates/oxc_linter/src/rules/typescript/no_unused_expressions.rs +++ b/crates/oxc_linter/src/rules/typescript/no_unused_expressions.rs @@ -58,7 +58,9 @@ impl Rule for NoUnusedExpressions { return; }; - if self.is_disallowed(&expression_stmt.expression) { + if self.is_disallowed(&expression_stmt.expression) + && !is_parent_arrow_function_expression(node, ctx) + { ctx.diagnostic(no_unused_expressions_diagnostic(expression_stmt.span)); } } @@ -89,6 +91,20 @@ impl Rule for NoUnusedExpressions { } } +fn is_parent_arrow_function_expression<'a>(node: &AstNode<'a>, ctx: &LintContext<'a>) -> bool { + let Some(parent) = ctx.nodes().parent_node(node.id()) else { return false }; + + let AstKind::FunctionBody(_) = parent.kind() else { return false }; + + let Some(grand_parent) = ctx.nodes().parent_node(parent.id()) else { return false }; + + let AstKind::ArrowFunctionExpression(arrow_function_expression) = grand_parent.kind() else { + return false; + }; + + arrow_function_expression.expression +} + impl NoUnusedExpressions { fn is_disallowed(&self, expr: &Expression) -> bool { match expr { @@ -265,6 +281,7 @@ fn test() { "foo ? import('./foo') : import('./bar');", Some(serde_json::json!([{ "allowTernary": true }])), ), + ("const _func = (value: number) => value + 1;", None), ]; let fail = vec![ @@ -411,6 +428,7 @@ fn test() { ", None, ), + ("const _func = (value: number) => { value + 1; }", None), ]; Tester::new(NoUnusedExpressions::NAME, NoUnusedExpressions::CATEGORY, pass, fail) diff --git a/crates/oxc_linter/src/snapshots/typescript_no_unused_expressions.snap b/crates/oxc_linter/src/snapshots/typescript_no_unused_expressions.snap index 99a941bac194a..d06ee11f31264 100644 --- a/crates/oxc_linter/src/snapshots/typescript_no_unused_expressions.snap +++ b/crates/oxc_linter/src/snapshots/typescript_no_unused_expressions.snap @@ -200,3 +200,10 @@ source: crates/oxc_linter/src/tester.rs 4 │ ╰──── help: Consider removing this expression + + ⚠ typescript-eslint(no-unused-expressions): Disallow unused expressions + ╭─[no_unused_expressions.tsx:1:36] + 1 │ const _func = (value: number) => { value + 1; } + · ────────── + ╰──── + help: Consider removing this expression