From 69216ee69c7172e847b64e0e934b5121a34d0ea3 Mon Sep 17 00:00:00 2001 From: Nitin Kumar Date: Thu, 3 Nov 2022 00:49:14 +0530 Subject: [PATCH] feat: no-empty suggest to add comment in empty BlockStatement (#16470) * feat: suggest to add comment in empty BlockStatements * test: update inavlid test cases with suggestions * test: more strict assertions * test: assert for suggestions Co-authored-by: Milos Djermanovic Co-authored-by: Milos Djermanovic --- docs/src/_data/rules.json | 2 +- docs/src/_data/rules_meta.json | 1 + lib/rules/no-empty.js | 21 +++- tests/lib/rules/no-empty.js | 177 ++++++++++++++++++++++++++++++--- 4 files changed, 185 insertions(+), 16 deletions(-) diff --git a/docs/src/_data/rules.json b/docs/src/_data/rules.json index c0f724ffaf7..48c2a9866ba 100644 --- a/docs/src/_data/rules.json +++ b/docs/src/_data/rules.json @@ -731,7 +731,7 @@ "description": "Disallow empty block statements", "recommended": true, "fixable": false, - "hasSuggestions": false + "hasSuggestions": true }, { "name": "no-empty-function", diff --git a/docs/src/_data/rules_meta.json b/docs/src/_data/rules_meta.json index 72044eb74ab..8f1f839e86f 100644 --- a/docs/src/_data/rules_meta.json +++ b/docs/src/_data/rules_meta.json @@ -938,6 +938,7 @@ }, "no-empty": { "type": "suggestion", + "hasSuggestions": true, "docs": { "description": "Disallow empty block statements", "recommended": true, diff --git a/lib/rules/no-empty.js b/lib/rules/no-empty.js index 459140a2e70..242e50efea4 100644 --- a/lib/rules/no-empty.js +++ b/lib/rules/no-empty.js @@ -17,6 +17,7 @@ const astUtils = require("./utils/ast-utils"); /** @type {import('../shared/types').Rule} */ module.exports = { meta: { + hasSuggestions: true, type: "suggestion", docs: { @@ -39,7 +40,8 @@ module.exports = { ], messages: { - unexpected: "Empty {{type}} statement." + unexpected: "Empty {{type}} statement.", + suggestComment: "Add comment inside empty {{type}} statement." } }, @@ -71,7 +73,22 @@ module.exports = { return; } - context.report({ node, messageId: "unexpected", data: { type: "block" } }); + context.report({ + node, + messageId: "unexpected", + data: { type: "block" }, + suggest: [ + { + messageId: "suggestComment", + data: { type: "block" }, + fix(fixer) { + const range = [node.range[0] + 1, node.range[1] - 1]; + + return fixer.replaceTextRange(range, " /* empty */ "); + } + } + ] + }); }, SwitchStatement(node) { diff --git a/tests/lib/rules/no-empty.js b/tests/lib/rules/no-empty.js index 98651a41256..812aa8de994 100644 --- a/tests/lib/rules/no-empty.js +++ b/tests/lib/rules/no-empty.js @@ -44,36 +44,187 @@ ruleTester.run("no-empty", rule, { { code: "try { foo(); } catch (ex) {} finally { bar(); }", options: [{ allowEmptyCatch: true }] } ], invalid: [ - { code: "try {} catch (ex) {throw ex}", errors: [{ messageId: "unexpected", data: { type: "block" }, type: "BlockStatement" }] }, - { code: "try { foo() } catch (ex) {}", errors: [{ messageId: "unexpected", data: { type: "block" }, type: "BlockStatement" }] }, - { code: "try { foo() } catch (ex) {throw ex} finally {}", errors: [{ messageId: "unexpected", data: { type: "block" }, type: "BlockStatement" }] }, - { code: "if (foo) {}", errors: [{ messageId: "unexpected", data: { type: "block" }, type: "BlockStatement" }] }, - { code: "while (foo) {}", errors: [{ messageId: "unexpected", data: { type: "block" }, type: "BlockStatement" }] }, - { code: "for (;foo;) {}", errors: [{ messageId: "unexpected", data: { type: "block" }, type: "BlockStatement" }] }, - { code: "switch(foo) {}", errors: [{ messageId: "unexpected", data: { type: "switch" }, type: "SwitchStatement" }] }, + { + code: "try {} catch (ex) {throw ex}", + errors: [{ + messageId: "unexpected", + data: { type: "block" }, + type: "BlockStatement", + suggestions: [{ + messageId: "suggestComment", + data: { type: "block" }, + output: "try { /* empty */ } catch (ex) {throw ex}" + }] + }] + }, + { + code: "try { foo() } catch (ex) {}", + errors: [{ + messageId: "unexpected", + data: { type: "block" }, + type: "BlockStatement", + suggestions: [{ + messageId: "suggestComment", + data: { type: "block" }, + output: "try { foo() } catch (ex) { /* empty */ }" + }] + }] + }, + { + code: "try { foo() } catch (ex) {throw ex} finally {}", + errors: [{ + messageId: "unexpected", + data: { type: "block" }, + type: "BlockStatement", + suggestions: [{ + messageId: "suggestComment", + data: { type: "block" }, + output: "try { foo() } catch (ex) {throw ex} finally { /* empty */ }" + }] + }] + }, + { + code: "if (foo) {}", + errors: [{ + messageId: "unexpected", + data: { type: "block" }, + type: "BlockStatement", + suggestions: [{ + messageId: "suggestComment", + data: { type: "block" }, + output: "if (foo) { /* empty */ }" + }] + }] + }, + { + code: "while (foo) {}", + errors: [{ + messageId: "unexpected", + data: { type: "block" }, + type: "BlockStatement", + suggestions: [{ + messageId: "suggestComment", + data: { type: "block" }, + output: "while (foo) { /* empty */ }" + }] + }] + }, + { + code: "for (;foo;) {}", + errors: [{ + messageId: "unexpected", + data: { type: "block" }, + type: "BlockStatement", + suggestions: [{ + messageId: "suggestComment", + data: { type: "block" }, + output: "for (;foo;) { /* empty */ }" + }] + }] + }, + { + code: "switch(foo) {}", + errors: [{ + messageId: "unexpected", + data: { type: "switch" }, + type: "SwitchStatement", + suggestions: null + }] + }, + { + code: "switch (foo) { /* empty */ }", + errors: [{ + messageId: "unexpected", + data: { type: "switch" }, + type: "SwitchStatement", + suggestions: null + }] + }, { code: "try {} catch (ex) {}", options: [{ allowEmptyCatch: true }], - errors: [{ messageId: "unexpected", data: { type: "block" }, type: "BlockStatement" }] + errors: [{ + messageId: "unexpected", + data: { type: "block" }, + type: "BlockStatement", + suggestions: [{ + messageId: "suggestComment", + data: { type: "block" }, + output: "try { /* empty */ } catch (ex) {}" + }] + }] }, { code: "try { foo(); } catch (ex) {} finally {}", options: [{ allowEmptyCatch: true }], - errors: [{ messageId: "unexpected", data: { type: "block" }, type: "BlockStatement" }] + errors: [{ + messageId: "unexpected", + data: { type: "block" }, + type: "BlockStatement", + suggestions: [{ + messageId: "suggestComment", + data: { type: "block" }, + output: "try { foo(); } catch (ex) {} finally { /* empty */ }" + }] + }] }, { code: "try {} catch (ex) {} finally {}", options: [{ allowEmptyCatch: true }], errors: [ - { messageId: "unexpected", data: { type: "block" }, type: "BlockStatement" }, - { messageId: "unexpected", data: { type: "block" }, type: "BlockStatement" } + { + messageId: "unexpected", + data: { type: "block" }, + type: "BlockStatement", + suggestions: [ + { + messageId: "suggestComment", + data: { type: "block" }, + output: "try { /* empty */ } catch (ex) {} finally {}" + } + ] + }, + { + messageId: "unexpected", + data: { type: "block" }, + type: "BlockStatement", + suggestions: [ + { + messageId: "suggestComment", + data: { type: "block" }, + output: "try {} catch (ex) {} finally { /* empty */ }" + } + ] + } ] }, { code: "try { foo(); } catch (ex) {} finally {}", errors: [ - { messageId: "unexpected", data: { type: "block" }, type: "BlockStatement" }, - { messageId: "unexpected", data: { type: "block" }, type: "BlockStatement" } + { + messageId: "unexpected", + data: { type: "block" }, + type: "BlockStatement", + suggestions: [ + { + messageId: "suggestComment", + data: { type: "block" }, + output: "try { foo(); } catch (ex) { /* empty */ } finally {}" + } + ] + }, + { + messageId: "unexpected", + data: { type: "block" }, + type: "BlockStatement", + suggestions: [ + { + messageId: "suggestComment", + data: { type: "block" }, + output: "try { foo(); } catch (ex) {} finally { /* empty */ }" + } + ] + } ] } ]