Skip to content

Commit b393430

Browse files
committed
fix(linter/curly): fix multi-or-nest and consistent conflict (#18660)
Skip else-if statements when running the curly rule, as they are already handled as part of the parent if-else chain. This prevents duplicate diagnostics and fixes the conflict where multi-or-nest would suggest removing braces while consistent would require them. fixes #18566
1 parent ee30de9 commit b393430

2 files changed

Lines changed: 23 additions & 67 deletions

File tree

crates/oxc_linter/src/rules/eslint/curly.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,9 @@ impl Rule for Curly {
278278

279279
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
280280
match node.kind() {
281-
AstKind::IfStatement(stmt) => self.run_for_if_statement(stmt, ctx),
281+
AstKind::IfStatement(stmt) if !is_else_if(node, stmt, ctx) => {
282+
self.run_for_if_statement(stmt, ctx);
283+
}
282284
AstKind::ForStatement(stmt) => self.run_for_loop("for", &stmt.body, ctx),
283285
AstKind::ForInStatement(stmt) => self.run_for_loop("for-in", &stmt.body, ctx),
284286
AstKind::ForOfStatement(stmt) => self.run_for_loop("for-of", &stmt.body, ctx),
@@ -360,6 +362,15 @@ fn get_if_else_keyword(is_else: bool) -> &'static str {
360362
if is_else { "else" } else { "if" }
361363
}
362364

365+
fn is_else_if(node: &AstNode, stmt: &IfStatement, ctx: &LintContext) -> bool {
366+
if let AstKind::IfStatement(parent_if) = ctx.nodes().parent_kind(node.id())
367+
&& parent_if.alternate.as_ref().is_some_and(|alt| alt.span() == stmt.span)
368+
{
369+
return true;
370+
}
371+
false
372+
}
373+
363374
fn has_braces(body: &Statement) -> bool {
364375
matches!(body, Statement::BlockStatement(_))
365376
}
@@ -885,6 +896,17 @@ fn test() {
885896
"if (a) { if (b) foo(); } else { bar(); }",
886897
Some(serde_json::json!(["multi-or-nest", "consistent"])),
887898
),
899+
(
900+
"if (dividerPosition) {
901+
if (condition1 && condition2) {
902+
closePos = state.pos;
903+
const y = closePos;
904+
}
905+
} else if (condition3 && condition4) {
906+
dividerPosition = state.pos;
907+
}",
908+
Some(serde_json::json!(["multi-or-nest", "consistent"])),
909+
),
888910
("if (a) { if (b) { foo(); bar(); } } else baz();", Some(serde_json::json!(["multi"]))),
889911
(
890912
"if (a) foo(); else if (b) { if (c) bar(); } else baz();",

crates/oxc_linter/src/snapshots/eslint_curly.snap

Lines changed: 0 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,6 @@ source: crates/oxc_linter/src/tester.rs
3030
╰────
3131
help: Replace `baz()` with `{baz()}`.
3232

33-
eslint(curly): Expected { after 'if' condition.
34-
╭─[curly.tsx:1:34]
35-
1if (foo) { bar() } else if (faa) baz()
36-
· ─────
37-
╰────
38-
help: Replace `baz()` with `{baz()}`.
39-
4033
eslint(curly): Expected { after 'while' condition.
4134
╭─[curly.tsx:1:13]
4235
1while (foo) bar()
@@ -161,13 +154,6 @@ source: crates/oxc_linter/src/tester.rs
161154
╰────
162155
help: Replace `{ quuux(); }` with ` quuux(); `.
163156

164-
eslint(curly): Unexpected { after 'if' condition.
165-
╭─[curly.tsx:1:41]
166-
1if (foo) if (bar) baz(); else if (quux) { quuux(); }
167-
· ────────────
168-
╰────
169-
help: Replace `{ quuux(); }` with ` quuux(); `.
170-
171157
eslint(curly): Unexpected { after 'while' condition.
172158
╭─[curly.tsx:1:13]
173159
1while (foo) { bar() }
@@ -211,28 +197,6 @@ source: crates/oxc_linter/src/tester.rs
211197
8 │ │ console.log(2)
212198
9 │ │ else
213199
10 │ │ console.log(3)
214-
11 │ ╰─▶ }
215-
╰────
216-
help: Replace `{
217-
if (2)
218-
console.log(2)
219-
else
220-
console.log(3)
221-
}` with `
222-
if (2)
223-
console.log(2)
224-
else
225-
console.log(3)
226-
`.
227-
228-
eslint(curly): Unexpected { after 'else'.
229-
╭─[curly.tsx:6:11]
230-
5console.log(1)
231-
6 │ ╭─▶ } else {
232-
7 │ │ if (2)
233-
8 │ │ console.log(2)
234-
9 │ │ else
235-
10 │ │ console.log(3)
236200
11 │ ╰─▶ }
237201
╰────
238202
help: Replace `{
@@ -560,13 +524,6 @@ source: crates/oxc_linter/src/tester.rs
560524
╰────
561525
help: Replace `faa();` with `{faa();}`.
562526

563-
eslint(curly): Expected { after 'if' condition.
564-
╭─[curly.tsx:1:33]
565-
1if (true) foo(); else if (true) faa(); else { bar(); baz(); }
566-
· ──────
567-
╰────
568-
help: Replace `faa();` with `{faa();}`.
569-
570527
eslint(curly): Expected { after 'if' condition.
571528
╭─[curly.tsx:1:21]
572529
1if (true) if (true) foo(); else { bar(); baz(); }
@@ -749,22 +706,6 @@ source: crates/oxc_linter/src/tester.rs
749706
2 │ ╭─▶ else if (bar) {
750707
3 │ │ doSomethingElse()
751708
4 │ │ ;
752-
5 │ ╰─▶ }
753-
╰────
754-
help: Replace `{
755-
doSomethingElse()
756-
;
757-
}` with `
758-
doSomethingElse()
759-
;
760-
`.
761-
762-
eslint(curly): Unexpected { after 'if' condition.
763-
╭─[curly.tsx:2:18]
764-
1if (foo) doSomething();
765-
2 │ ╭─▶ else if (bar) {
766-
3 │ │ doSomethingElse()
767-
4 │ │ ;
768709
5 │ ╰─▶ }
769710
╰────
770711
help: Replace `{
@@ -1016,13 +957,6 @@ source: crates/oxc_linter/src/tester.rs
1016957
╰────
1017958
help: Replace `{bar();}` with `bar();`.
1018959

1019-
eslint(curly): Unexpected { after 'if' condition.
1020-
╭─[curly.tsx:1:51]
1021-
1if(a) { if (b) foo(); } if (c) bar(); else if(foo){bar();}
1022-
· ────────
1023-
╰────
1024-
help: Replace `{bar();}` with `bar();`.
1025-
1026960
eslint(curly): Expected { after 'if' condition.
1027961
╭─[curly.tsx:1:11]
1028962
1 │ ╭─▶ if (true) [1, 2, 3]

0 commit comments

Comments
 (0)