New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Request: add option for no-fallthrough with newlines #15703
Comments
Thanks for the report. I’m curious why you believe this is a bug? ESLint is reporting that there should be a break before |
https://eslint.org/docs/rules/no-fallthrough does not actually define "unintentional fallthrough", but each of the bad examples look like switch(x) {
case 1:
// ...
doSomething(); // there is at least one statement
case 2:
// ...
} There is no example in the docs page with zero statements in a case clause and blank lines before the next statement, so this question focuses on an undocumented corner case. IMHO "unintentional fallthrough" requires at least one statement in the case clause. The spec does not use the phrase "fall through", but other languages do have definitions for this. C++17 / C23 formalized the "fallthrough attribute" and GCC/Clang support int main() {
int i = 0;
switch(3) {
case 0:
case 1:
break;
/* one blank line */
case 2:
case 3:
break;
/* two blank lines */
case 4:
case 5:
break;
/* one statement */
case 6:
i = 1;
case 7: break;
}
return 0;
} Running this through % clang++ -Wimplicit-fallthrough test.cc
test.cc:26:5: warning: unannotated fall-through between switch labels [-Wimplicit-fallthrough]
case 7: break;
^
test.cc:26:5: note: insert 'break;' to avoid fall-through
case 7: break;
^
break; |
In all of the cases mentioned, the rule is behaving as expected. Only cases without empty lines or comments between them are considered valid. As soon as they are separated, this will trigger the warning. We can update the docs to show these examples. |
Just for trackback, there are bunch of old locked issues about inconsistent no-fallthrough behavior: #6741 I came here looking for a way to handle IMHO, it would be an objective improvement to the rule to strictly define fallthrough as a |
Coming from other programming languages, ESLint's current definition of fallthrough is inconsistent. @SheetJSDev talked about C/C++. Other languages: PHP: PSR2 guidelines define fallthrough as requiring at least one statement. This is the same as C/C++ Java: Sun style defines a fallthrough as "doesn't include a break statement", so technically you always need a fallthrough comment between cases, no matter how much whitespace is in between. Go: forced breaks at the end of each case clause, even if there is no whitespace. Special keyword Perl: C#: compilation error if there is no break between case clauses, irrespective of the number of lines. Special statement Ruby: Rust: Pascal: In summary, "everything but eslint" defines fallthrough in one of two ways: "intrinsic": each case is separate. "statement": at least one statement between case clauses with no final break. ESLint's behavior is surprising and feels inconsistent. |
i hope there's a way to tell the linter that the passthrough is intentional tho? for example in the Eclipse Java linter, case FIOC_READ:
is_read = 1;
case FIOC_WRITE:
fioc_do_rw(req, arg, in_buf, in_bufsz, out_bufsz, is_read);
break; will cause a linter warning, but case FIOC_READ:
is_read = 1;
/* no break */
case FIOC_WRITE:
fioc_do_rw(req, arg, in_buf, in_bufsz, out_bufsz, is_read);
break; tells the linter that the passthru is intentional |
@divinity76 please check out the documentation for the rule: |
@LvChengbin Here's a truly funny workaround that passes eslint: switch( true ) {
case 'a' /*
Put a message here
*/:
case 'b' : break;
case 'c':
case /*
Put a message here
*/ 'd':
} Both workarounds pass because eslint does not check whitespace between Is this more readable / less bug prone? IMHO no but it at least passes the rule check |
This works as intended. The rule considers only cases that appear in consecutive lines as an intentional fallthrough. I don't think we should change the default behavior because we don't know if most users would really prefer the suggested one. However, since there are different opinions on what looks and what does not look like intentional fallthrough, I wouldn't mind adding an option to change the behavior. The new option, when enabled, would allow empty cases regardless of blank lines and comments inside. |
Linters are always going to wind up favoring one style or construct over another. I agree that knowing what "most users would prefer" sounds useful, but also difficult to achieve in practice. How does the team make decisions like this, in the absence of a poll of X number of ES programmers? Maybe the standard should be like Wikipedia, "no original research" -- if you want to make an assertion (like "fallthrough should only include case-statements on consecutive lines", or "fallthrough can include whitespace"), you need to bring a citation from a reputable source backing it up. A few posts back, @reviewher did a pretty good job of covering how other languages define fallthrough, which I think makes a good case for making whitespace-counts as default behavior. Has anyone put together a counter-argument in favor of the current (no-whitespace) behavior, perhaps when the rule was originally added? |
I genuinely tried to find an example outside of ESLint and came up short. Even in JS land: JSHint takes the "statement" interpretation (you can verify on https://jshint.com/ ) JSLint takes the "statement" interpretation (you can verify on https://www.jslint.com/ ) ESLint "blazing a new trail" is not inherently bad, but there arguably should be a very compelling reason. |
@mdjermanovic "most users" probably never use switch statements, and "most switch users" probably never use the fallthrough behavior intentionally (commented or otherwise). The users who do use switch statements liberally in JS (the relevant demographic for the rule) likely have deep experience with system languages like C and expect the concept to work in the same way. That said, as discussed in this thread, ESLint stands alone in the current behavior. IMHO the current behavior encourages unreadable patterns. |
The team is in agreement that we can add a new option for this behavior but we won’t be changing the default behavior. Anyone is free to submit a pull request for this change. |
I would like to work on this issue. |
@Gautam-Arora24 go for it 👍 |
I am interested to work on this issue and i am looking into it. |
@amareshsm Go for it :) |
@amareshsm Can I finish this if you are not working on it actively? |
@snitin315 Yes, I will complete this today. |
Environment
Node version: v16.14.0
npm version: v8.3.1
Local ESLint version: v8.11.0 (Currently used)
Global ESLint version: v7.23.0
Operating System: darwin 21.1.0
What parser are you using?
Default (Espree)
What did you do?
ESLint Demo Link
What did you expect to happen?
No errors
What actually happened?
Participation
Additional comments
It might also make sense to support comments:
The text was updated successfully, but these errors were encountered: