From ada4aa4fabca5cc0402aac58b47b58a1b80cbe09 Mon Sep 17 00:00:00 2001 From: tanujkanti4441 Date: Thu, 14 Sep 2023 17:19:28 +0530 Subject: [PATCH] feat: allowVoid option in array-callback-return --- lib/rules/array-callback-return.js | 14 +++++++++++++- tests/lib/rules/array-callback-return.js | 8 ++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/rules/array-callback-return.js b/lib/rules/array-callback-return.js index 24a33d16c99..68b571baaf6 100644 --- a/lib/rules/array-callback-return.js +++ b/lib/rules/array-callback-return.js @@ -162,6 +162,10 @@ module.exports = { checkForEach: { type: "boolean", default: false + }, + allowVoid: { + type: "boolean", + default: false } }, additionalProperties: false @@ -178,7 +182,7 @@ module.exports = { create(context) { - const options = context.options[0] || { allowImplicit: false, checkForEach: false }; + const options = context.options[0] || { allowImplicit: false, checkForEach: false, allowVoid: false }; const sourceCode = context.sourceCode; let funcInfo = { @@ -211,6 +215,14 @@ module.exports = { if (options.checkForEach && node.type === "ArrowFunctionExpression" && node.expression) { messageId = "expectedNoReturnValue"; } + + if (options.checkForEach && + options.allowVoid && + node.type === "ArrowFunctionExpression" && + node.body.type === "UnaryExpression" && + node.body.operator === "void") { + return; + } } else { if (node.body.type === "BlockStatement" && isAnySegmentReachable(funcInfo.currentSegments)) { messageId = funcInfo.hasReturn ? "expectedAtEnd" : "expectedInside"; diff --git a/tests/lib/rules/array-callback-return.js b/tests/lib/rules/array-callback-return.js index 6343d3e4027..fa554cb5165 100644 --- a/tests/lib/rules/array-callback-return.js +++ b/tests/lib/rules/array-callback-return.js @@ -24,6 +24,8 @@ const checkForEachOptions = [{ checkForEach: true }]; const allowImplicitCheckForEach = [{ allowImplicit: true, checkForEach: true }]; +const checkForEachAllowVoid = [{ checkForEach: true, allowVoid: true }]; + ruleTester.run("array-callback-return", rule, { valid: [ @@ -114,6 +116,10 @@ ruleTester.run("array-callback-return", rule, { { code: "foo.every(function() { try { bar(); } finally { return 1; } })", options: checkForEachOptions }, { code: "foo.every(function() { return; })", options: allowImplicitCheckForEach }, + // options: { checkForEach: true, allowVoid: true } + { code: "foo.forEach((x) => void x)", options: checkForEachAllowVoid, parserOptions: { ecmaVersion: 6 } }, + { code: "foo.forEach((x) => void bar(x))", options: checkForEachAllowVoid, parserOptions: { ecmaVersion: 6 } }, + "Arrow.from(x, function() {})", "foo.abc(function() {})", "every(function() {})", @@ -217,6 +223,8 @@ ruleTester.run("array-callback-return", rule, { { code: "foo.filter(function foo() {})", options: checkForEachOptions, errors: [{ messageId: "expectedInside", data: { name: "function 'foo'", arrayMethodName: "Array.prototype.filter" } }] }, { code: "foo.filter(function foo() { return; })", options: checkForEachOptions, errors: [{ messageId: "expectedReturnValue", data: { name: "function 'foo'", arrayMethodName: "Array.prototype.filter" } }] }, { code: "foo.every(cb || function() {})", options: checkForEachOptions, errors: ["Array.prototype.every() expects a return value from function."] }, + { code: "foo.forEach(() => void x)", options: checkForEachOptions, parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "expectedNoReturnValue" }] }, + { code: "foo.forEach(() => void bar(x))", options: checkForEachOptions, parserOptions: { ecmaVersion: 6 }, errors: [{ messageId: "expectedNoReturnValue" }] }, // full location tests {