Skip to content

Commit

Permalink
refactor(linter): improve eslint/no-lone-blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
shulaoda committed Jan 18, 2025
1 parent c15af02 commit 0c7f09d
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 47 deletions.
83 changes: 36 additions & 47 deletions crates/oxc_linter/src/rules/eslint/no_lone_blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,58 +61,55 @@ impl Rule for NoLoneBlocks {
return;
};

let body = &stmt.body;
if body.is_empty() {
if stmt.body.is_empty() {
if !matches!(parent_node.kind(), AstKind::TryStatement(_) | AstKind::CatchClause(_)) {
report(ctx, node, parent_node);
}
return;
}

if body.len() == 1
&& matches!(parent_node.kind(), AstKind::FunctionBody(parent) if parent.statements.len() == 1)
{
report(ctx, node, parent_node);
}

let mut lone_blocks = Vec::new();
if is_lone_block(node, parent_node) {
lone_blocks.push(node);
}
let mut is_lone_blocks = is_lone_block(node, parent_node);

for child in &stmt.body {
match child.as_declaration() {
Some(Declaration::VariableDeclaration(decl))
if decl.kind != VariableDeclarationKind::Var =>
{
mark_lone_block(node, &mut lone_blocks);
}
Some(Declaration::ClassDeclaration(_) | Declaration::FunctionDeclaration(_)) => {
mark_lone_block(node, &mut lone_blocks);
if is_lone_blocks {
for child in &stmt.body {
match child.as_declaration() {
Some(Declaration::VariableDeclaration(decl))
if decl.kind != VariableDeclarationKind::Var =>
{
is_lone_blocks = false;
}
Some(
Declaration::ClassDeclaration(_) | Declaration::FunctionDeclaration(_),
) => {
is_lone_blocks = false;
}
_ => {}
}
_ => {}
}
}

if let Some(last) = lone_blocks.last() {
if last.id() == node.id() {
lone_blocks.pop();
if is_lone_blocks {
report(ctx, node, parent_node);
return;
}
} else {
match parent_node.kind() {
AstKind::BlockStatement(parent_statement) => {
if parent_statement.body.len() == 1 {
report(ctx, node, parent_node);
}
}

match parent_node.kind() {
AstKind::FunctionBody(parent) => {
if parent.statements.len() == 1 && stmt.body.len() == 1 {
report(ctx, node, parent_node);
}
AstKind::StaticBlock(parent_statement) => {
if parent_statement.body.len() == 1 {
report(ctx, node, parent_node);
}
}
AstKind::BlockStatement(parent_statement) => {
if parent_statement.body.len() == 1 {
report(ctx, node, parent_node);
}
_ => {}
}
AstKind::StaticBlock(parent_statement) => {
if parent_statement.body.len() == 1 {
report(ctx, node, parent_node);
}
}
_ => {}
}
}
}
Expand Down Expand Up @@ -142,16 +139,6 @@ fn is_lone_block(node: &AstNode, parent_node: &AstNode) -> bool {
}
}

fn mark_lone_block(parent_node: &AstNode, lone_blocks: &mut Vec<&AstNode>) {
if lone_blocks.is_empty() {
return;
}

if lone_blocks.last().is_some_and(|last| last.id() == parent_node.id()) {
lone_blocks.pop();
}
}

#[test]
fn test() {
use crate::tester::Tester;
Expand All @@ -160,6 +147,7 @@ fn test() {
"if (foo) { if (bar) { baz(); } }",
"do { bar(); } while (foo)",
"function foo() { while (bar) { baz() } }",
"function test() { { console.log(6); console.log(6) } }",
"{ let x = 1; }", // { "ecmaVersion": 6 },
"{ const x = 1; }", // { "ecmaVersion": 6 },
"'use strict'; { function bar() {} }", // { "ecmaVersion": 6 },
Expand Down Expand Up @@ -216,6 +204,7 @@ fn test() {
"{}",
"{var x = 1;}",
"foo(); {} bar();",
"function test() { { console.log(6); } }",
"if (foo) { bar(); {} baz(); }",
"{
{ } }",
Expand Down
6 changes: 6 additions & 0 deletions crates/oxc_linter/src/snapshots/eslint_no_lone_blocks.snap
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ source: crates/oxc_linter/src/tester.rs
· ──
╰────

eslint(no-lone-blocks): Block is unnecessary.
╭─[no_lone_blocks.tsx:1:19]
1function test() { { console.log(6); } }
· ───────────────────
╰────

eslint(no-lone-blocks): Nested block is redundant.
╭─[no_lone_blocks.tsx:1:19]
1if (foo) { bar(); {} baz(); }
Expand Down

0 comments on commit 0c7f09d

Please sign in to comment.