From fdf14b08ce690416bd892c39100dcfc4f5720baa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milo=C5=A1=20Lajtman?= Date: Thu, 8 Feb 2024 10:23:35 +0100 Subject: [PATCH] Add support for `prefer-early-return` to detect when "if" statement is the last one in function body Sometimes we assign a conditions used in "if" test to a variable before "if" statement. In such case it's not the only statement in the block, but it should be detected anyway. closes #314 --- .../lib/rules/prefer-early-return.js | 26 +++++++++++++------ .../lib/rules/prefer-early-return.test.js | 12 ++++++++- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/packages/eslint-plugin/lib/rules/prefer-early-return.js b/packages/eslint-plugin/lib/rules/prefer-early-return.js index a8bf0790..c565c113 100644 --- a/packages/eslint-plugin/lib/rules/prefer-early-return.js +++ b/packages/eslint-plugin/lib/rules/prefer-early-return.js @@ -50,20 +50,20 @@ module.exports = { } function hasSimplifiableConditionalBody(functionBody) { - const body = functionBody.body; - return ( - functionBody.type === 'BlockStatement' && - body.length === 1 && - isOffendingIfStatement(body[0]) - ); + if (!isBlockStatement(functionBody)) { + return false; + } + + const lastStatement = getLastStatement(functionBody); + return Boolean(lastStatement) && isOffendingIfStatement(lastStatement); } function checkFunctionBody(functionNode) { const body = functionNode.body; - if (hasSimplifiableConditionalBody(body)) { + if (isBlockStatement(body) && hasSimplifiableConditionalBody(body)) { context.report( - body, + getLastStatement(body), 'Prefer an early return to a conditionally-wrapped function body', ); } @@ -76,3 +76,13 @@ module.exports = { }; }, }; + +function getLastStatement(statement) { + return 'body' in statement && statement.body.length > 0 + ? statement.body[statement.body.length - 1] + : undefined; +} + +function isBlockStatement(statement) { + return statement?.type === 'BlockStatement'; +} diff --git a/packages/eslint-plugin/tests/lib/rules/prefer-early-return.test.js b/packages/eslint-plugin/tests/lib/rules/prefer-early-return.test.js index b03cf5ef..35dd0ddf 100644 --- a/packages/eslint-plugin/tests/lib/rules/prefer-early-return.test.js +++ b/packages/eslint-plugin/tests/lib/rules/prefer-early-return.test.js @@ -6,7 +6,7 @@ const ruleTester = new RuleTester(); const error = { message: 'Prefer an early return to a conditionally-wrapped function body', - type: 'BlockStatement', + type: 'IfStatement', }; ruleTester.run('prefer-early-return', rule, { @@ -144,5 +144,15 @@ ruleTester.run('prefer-early-return', rule, { })`, errors: [error], }, + { + code: `function foo() { + var bool = a && b; + if (bool) { + doSomething(); + doSomethingElse(); + } + }`, + errors: [error], + }, ], });