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
Fix: curly errors with lexical and function declarations (fixes #11908) #11912
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -231,6 +231,100 @@ ruleTester.run("curly", rule, { | |
// https://github.com/feross/standard/issues/664 | ||
code: "if (true) foo()\n;[1, 2, 3].bar()", | ||
options: ["multi-line"] | ||
}, | ||
|
||
// https://github.com/eslint/eslint/issues/11908 (also in invalid) | ||
{ | ||
code: "if (true) { const a = 1; }", | ||
options: ["multi"], | ||
parserOptions: { ecmaVersion: 6 } | ||
}, | ||
{ | ||
code: "if (true) { let a; }", | ||
options: ["multi"], | ||
parserOptions: { ecmaVersion: 6 } | ||
}, | ||
{ | ||
code: "if (true) { class a{} }", | ||
options: ["multi"], | ||
parserOptions: { ecmaVersion: 6 } | ||
}, | ||
{ | ||
code: "if (true) { function a() {} }", | ||
options: ["multi"] | ||
}, | ||
"if (true) function a() {}", | ||
{ | ||
code: "if (true) \n function a() {}", | ||
options: ["multi-line"] | ||
}, | ||
{ | ||
code: "if (true) function a() \n {}", | ||
options: ["multi-line"] | ||
}, | ||
{ | ||
code: "if (true) function a() \n {}", | ||
options: ["multi-or-nest"] | ||
}, | ||
{ | ||
code: "if (true) { let a; } else { foo; }", | ||
options: ["multi", "consistent"], | ||
parserOptions: { ecmaVersion: 6 } | ||
}, | ||
{ | ||
code: "if (true) { function a() {} } else { foo; }", | ||
options: ["multi", "consistent"] | ||
}, | ||
{ | ||
code: "if (true) function a() {} else b;", | ||
options: ["multi", "consistent"] | ||
}, | ||
{ | ||
code: "if (true) function a() {} else { foo; bar; }", | ||
options: ["multi", "consistent"] | ||
}, | ||
{ | ||
code: "if (true) function a() {} else { let a }", | ||
options: ["multi", "consistent"], | ||
parserOptions: { ecmaVersion: 6 } | ||
}, | ||
{ | ||
code: "if (true) function a() {} else { function b() {} }", | ||
options: ["multi", "consistent"] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm confused. Why is it valid for the consequent section to have no block and the alternate section to have a block? Is it that this is really "invalid", but the block can't be removed in the alternate section because it would change the scope/hoisting of the function? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The idea is to treat both as 'valid', thus keep the scope of this rule to only whether the user should simply put or remove braces around certain statements. Cases like this would need additional steps if not a serious refactoring to fix the code (I meant user's code, not the code of this rule). This is in line with how the Also, this 'wrong' usage of function declarations will be reported by There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is how the rule already works with /*eslint curly: ["error", "multi-or-nest"]*/
// warning
if (foo) {
baz();
}
// no warning
if (foo) {
function x() {}
} The second block would be 'invalid' by this option because it's one statement in one line, but since it has a lexical declaration (the block cannot be removed) it is treated as 'valid' ( = no warning). I think it's okay to not report this block. When the /*eslint curly: ["error", "multi-or-nest", "consistent"]*/
// warning on `if`, not on `else`
if (foo)
baz();
else {
function x() {}
} auto-fixed to: /*eslint curly: ["error", "multi-or-nest", "consistent"]*/
if (foo)
{baz();}
else {
function x() {}
} This PR does the same with the In addition, this PR also fixes the behavior of this rule in cases when a function declaration is not in a block. The presumption is that these two statements are not equivalent: if (foo)
function x() {}
if (foo)
{function x() {}} so, to be consistent with the fact that 'unchangeable' statements shouldn't be reported, after this PR the rule will not report this: /*eslint curly: ["error"]*/
// default option, blocks are always required
// no warning
if (foo)
function x() {} currently, which I believe is not correct, the rule reports and fixes this code to: /*eslint curly: ["error"]*/
// default option, blocks are always required
if (foo)
{function x() {}} The problem with the /*eslint curly: ["error", "multi", "consistent"]*/
if (foo)
function x() {}
else {
function x() {}
} This isn't a |
||
}, | ||
{ | ||
code: "if (true) function a() {} else { foo; }", | ||
options: ["multi-line", "consistent"] | ||
}, | ||
{ | ||
code: "if (true) { let a; } else { foo; }", | ||
options: ["multi-or-nest", "consistent"], | ||
parserOptions: { ecmaVersion: 6 } | ||
}, | ||
{ | ||
code: "if (true) { function a() {} } else { foo; }", | ||
options: ["multi-or-nest", "consistent"] | ||
}, | ||
{ | ||
code: "if (true) function a() {} else { foo; bar; }", | ||
options: ["multi-or-nest", "consistent"] | ||
}, | ||
{ | ||
code: "if (true) function a() \n {} else { foo; bar; }", | ||
options: ["multi-or-nest", "consistent"] | ||
}, | ||
{ | ||
code: "if (true) function a() {} else { function b() \n {} }", | ||
options: ["multi-or-nest", "consistent"] | ||
}, | ||
{ | ||
code: "if (true) function a() {} else { let a }", | ||
options: ["multi-or-nest", "consistent"], | ||
parserOptions: { ecmaVersion: 6 } | ||
}, | ||
{ | ||
code: "if (true) function a() {} else { function b() {} }", | ||
options: ["multi-or-nest", "consistent"] | ||
} | ||
], | ||
invalid: [ | ||
|
@@ -897,6 +991,100 @@ ruleTester.run("curly", rule, { | |
output: "if (true)\n{foo()\n;}[1, 2, 3].bar()", | ||
options: ["multi-line"], | ||
errors: [{ messageId: "missingCurlyAfterCondition", data: { name: "if" }, type: "IfStatement" }] | ||
}, | ||
|
||
// https://github.com/eslint/eslint/issues/11908 (also in valid) | ||
{ | ||
code: "if (foo) { let a; } else b;", | ||
output: "if (foo) { let a; } else {b;}", | ||
parserOptions: { ecmaVersion: 6 }, | ||
errors: [{ messageId: "missingCurlyAfter", data: { name: "else" }, type: "IfStatement" }] | ||
}, | ||
{ | ||
code: "if (foo) a; else { const b = 1; }", | ||
output: "if (foo) {a;} else { const b = 1; }", | ||
parserOptions: { ecmaVersion: 6 }, | ||
errors: [{ messageId: "missingCurlyAfterCondition", data: { name: "if" }, type: "IfStatement" }] | ||
}, | ||
{ | ||
code: "if (foo) function a() {} else b;", | ||
output: "if (foo) function a() {} else {b;}", | ||
errors: [{ messageId: "missingCurlyAfter", data: { name: "else" }, type: "IfStatement" }] | ||
}, | ||
{ | ||
code: "if (foo) { let a; } else b;", | ||
output: "if (foo) { let a; } else {b;}", | ||
options: ["multi", "consistent"], | ||
parserOptions: { ecmaVersion: 6 }, | ||
errors: [{ messageId: "missingCurlyAfter", data: { name: "else" }, type: "IfStatement" }] | ||
}, | ||
{ | ||
code: "if (foo) a; else { const b = 1; }", | ||
output: "if (foo) {a;} else { const b = 1; }", | ||
options: ["multi", "consistent"], | ||
parserOptions: { ecmaVersion: 6 }, | ||
errors: [{ messageId: "missingCurlyAfterCondition", data: { name: "if" }, type: "IfStatement" }] | ||
}, | ||
{ | ||
code: "if (foo) a; else if (bar) { class b {} } else function c() {}", | ||
output: "if (foo) {a;} else if (bar) { class b {} } else function c() {}", | ||
options: ["multi", "consistent"], | ||
parserOptions: { ecmaVersion: 6 }, | ||
errors: [{ messageId: "missingCurlyAfterCondition", data: { name: "if" }, type: "IfStatement" }] | ||
}, | ||
{ | ||
code: "if (foo) { a; } else function b() {}", | ||
output: "if (foo) a; else function b() {}", | ||
options: ["multi", "consistent"], | ||
errors: [{ messageId: "unexpectedCurlyAfterCondition", data: { name: "if" }, type: "IfStatement" }] | ||
}, | ||
{ | ||
code: "if (foo) { let a; } else b;", | ||
output: "if (foo) { let a; } else {b;}", | ||
options: ["multi-line", "consistent"], | ||
parserOptions: { ecmaVersion: 6 }, | ||
errors: [{ messageId: "missingCurlyAfter", data: { name: "else" }, type: "IfStatement" }] | ||
}, | ||
{ | ||
code: "if (foo) a; else { const b = 1; }", | ||
output: "if (foo) {a;} else { const b = 1; }", | ||
options: ["multi-line", "consistent"], | ||
parserOptions: { ecmaVersion: 6 }, | ||
errors: [{ messageId: "missingCurlyAfterCondition", data: { name: "if" }, type: "IfStatement" }] | ||
}, | ||
{ | ||
code: "if (foo) a; else if (bar) { class b {} } else function c() {}", | ||
output: "if (foo) {a;} else if (bar) { class b {} } else function c() {}", | ||
options: ["multi-line", "consistent"], | ||
parserOptions: { ecmaVersion: 6 }, | ||
errors: [{ messageId: "missingCurlyAfterCondition", data: { name: "if" }, type: "IfStatement" }] | ||
}, | ||
{ | ||
code: "if (foo) { let a; } else b;", | ||
output: "if (foo) { let a; } else {b;}", | ||
options: ["multi-or-nest", "consistent"], | ||
parserOptions: { ecmaVersion: 6 }, | ||
errors: [{ messageId: "missingCurlyAfter", data: { name: "else" }, type: "IfStatement" }] | ||
}, | ||
{ | ||
code: "if (foo) a; else { const b = 1; }", | ||
output: "if (foo) {a;} else { const b = 1; }", | ||
options: ["multi-or-nest", "consistent"], | ||
parserOptions: { ecmaVersion: 6 }, | ||
errors: [{ messageId: "missingCurlyAfterCondition", data: { name: "if" }, type: "IfStatement" }] | ||
}, | ||
{ | ||
code: "if (foo) a; else if (bar) { class b {} } else function c() {}", | ||
output: "if (foo) {a;} else if (bar) { class b {} } else function c() {}", | ||
options: ["multi-or-nest", "consistent"], | ||
parserOptions: { ecmaVersion: 6 }, | ||
errors: [{ messageId: "missingCurlyAfterCondition", data: { name: "if" }, type: "IfStatement" }] | ||
}, | ||
{ | ||
code: "if (foo) { a; } else function b() {}", | ||
output: "if (foo) a; else function b() {}", | ||
options: ["multi-or-nest", "consistent"], | ||
errors: [{ messageId: "unexpectedCurlyAfterCondition", data: { name: "if" }, type: "IfStatement" }] | ||
} | ||
] | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if this is correct. I feel that all clauses should be blocks.