Skip to content

Commit

Permalink
feat: add allowEmptyCase option to no-fallthrough rule (#15887)
Browse files Browse the repository at this point in the history
* feat: allow empty case in switch

* feat: add test case with semicolon

* docs:add allow emtpy case option in docs

* feat: disallow switch case with ;

* feat: disallow empty statement

* chore: lint .md file

* remove redundant logic
  • Loading branch information
amareshsm committed Aug 26, 2022
1 parent ed26229 commit 30b1a2d
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 5 deletions.
33 changes: 31 additions & 2 deletions docs/src/rules/no-fallthrough.md
Expand Up @@ -168,9 +168,11 @@ Note that the last `case` statement in these examples does not cause a warning b

## Options

This rule accepts a single options argument:
This rule has an object option:

* Set the `commentPattern` option to a regular expression string to change the test for intentional fallthrough comment
* Set the `commentPattern` option to a regular expression string to change the test for intentional fallthrough comment.

* Set the `allowEmptyCase` option to `true` to allow empty cases regardless of the layout. By default, this rule does not require a fallthrough comment after an empty `case` only if the empty `case` and the next `case` are on the same line or on consecutive lines.

### commentPattern

Expand Down Expand Up @@ -202,6 +204,33 @@ switch(foo) {

:::

### allowEmptyCase

Examples of **correct** code for the `{ "allowEmptyCase": true }` option:

::: correct

```js
/* eslint no-fallthrough: ["error", { "allowEmptyCase": true }] */

switch(foo){
case 1:

case 2: doSomething();
}

switch(foo){
case 1:
/*
Put a message here
*/
case 2: doSomething();
}

```

:::

## When Not To Use It

If you don't want to enforce that each `case` statement should end with a `throw`, `return`, `break`, or comment, then you can safely turn this rule off.
11 changes: 8 additions & 3 deletions lib/rules/no-fallthrough.js
Expand Up @@ -76,6 +76,10 @@ module.exports = {
commentPattern: {
type: "string",
default: ""
},
allowEmptyCase: {
type: "boolean",
default: false
}
},
additionalProperties: false
Expand All @@ -91,6 +95,7 @@ module.exports = {
const options = context.options[0] || {};
let currentCodePath = null;
const sourceCode = context.getSourceCode();
const allowEmptyCase = options.allowEmptyCase || false;

/*
* We need to use leading comments of the next SwitchCase node because
Expand All @@ -104,7 +109,6 @@ module.exports = {
} else {
fallthroughCommentPattern = DEFAULT_FALLTHROUGH_COMMENT;
}

return {
onCodePathStart(codePath) {
currentCodePath = codePath;
Expand All @@ -119,7 +123,8 @@ module.exports = {
* Checks whether or not there is a fallthrough comment.
* And reports the previous fallthrough node if that does not exist.
*/
if (fallthroughCase && !hasFallthroughComment(fallthroughCase, node, context, fallthroughCommentPattern)) {

if (fallthroughCase && (!hasFallthroughComment(fallthroughCase, node, context, fallthroughCommentPattern))) {
context.report({
messageId: node.test ? "case" : "default",
node
Expand All @@ -137,7 +142,7 @@ module.exports = {
* And allows empty cases and the last case.
*/
if (currentCodePath.currentSegments.some(isReachable) &&
(node.consequent.length > 0 || hasBlankLinesBetween(node, nextToken)) &&
(node.consequent.length > 0 || (!allowEmptyCase && hasBlankLinesBetween(node, nextToken))) &&
node.parent.cases[node.parent.cases.length - 1] !== node) {
fallthroughCase = node;
}
Expand Down
83 changes: 83 additions & 0 deletions tests/lib/rules/no-fallthrough.js
Expand Up @@ -92,6 +92,22 @@ ruleTester.run("no-fallthrough", rule, {
options: [{
commentPattern: "break[\\s\\w]+omitted"
}]
},
{
code: "switch(foo) { case 0: \n\n\n case 1: b(); }",
options: [{ allowEmptyCase: true }]
},
{
code: "switch(foo) { case 0: \n /* with comments */ \n case 1: b(); }",
options: [{ allowEmptyCase: true }]
},
{
code: "switch (a) {\n case 1: ; break; \n case 3: }",
options: [{ allowEmptyCase: true }]
},
{
code: "switch (a) {\n case 1: ; break; \n case 3: }",
options: [{ allowEmptyCase: false }]
}
],
invalid: [
Expand Down Expand Up @@ -214,6 +230,73 @@ ruleTester.run("no-fallthrough", rule, {
column: 1
}
]
},
{
code: "switch(foo) { case 0: \n /* with comments */ \ncase 1: b(); }",
errors: [
{
messageId: "case",
type: "SwitchCase",
line: 3,
column: 1
}
]
},
{
code: "switch(foo) { case 0:\n\ncase 1: b(); }",
options: [{
allowEmptyCase: false
}],
errors: [
{
messageId: "case",
type: "SwitchCase",
line: 3,
column: 1
}
]
},
{
code: "switch(foo) { case 0:\n\ncase 1: b(); }",
options: [{}],
errors: [
{
messageId: "case",
type: "SwitchCase",
line: 3,
column: 1
}
]
},
{
code: "switch (a) { case 1: \n ; case 2: }",
options: [{ allowEmptyCase: false }],
errors: [
{
messageId: "case",
type: "SwitchCase",
line: 2,
column: 4
}
]
},
{
code: "switch (a) { case 1: ; case 2: ; case 3: }",
options: [{ allowEmptyCase: true }],
errors: [
{
messageId: "case",
type: "SwitchCase",
line: 1,
column: 24
},
{
messageId: "case",
type: "SwitchCase",
line: 1,
column: 34
}
]
}
]
});

0 comments on commit 30b1a2d

Please sign in to comment.