Skip to content

Commit 855b451

Browse files
authored
perf(noEmptyBlockStatements): short circuit to avoid traversing descendants for comments (#9329)
1 parent c3ec092 commit 855b451

2 files changed

Lines changed: 24 additions & 12 deletions

File tree

.changeset/nine-sides-wish.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@biomejs/biome": patch
3+
---
4+
5+
Improved performance of [`noEmptyBlockStatements`](https://biomejs.dev/linter/rules/no-empty-block-statements/). The rule is now smarter about short-circuiting its logic.

crates/biome_js_analyze/src/lint/suspicious/no_empty_block_statements.rs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,17 @@ impl Rule for NoEmptyBlockStatements {
8383

8484
fn run(ctx: &RuleContext<Self>) -> Self::Signals {
8585
let query = ctx.query();
86-
let is_empty = is_empty(query);
87-
let has_comments = query.syntax().has_comments_descendants();
88-
let is_constructor_with_ts_param_props_or_private =
89-
is_constructor_with_ts_param_props_or_private(query);
86+
if !is_empty(query) {
87+
return None;
88+
}
89+
if is_constructor_with_ts_param_props_or_private(query) {
90+
return None;
91+
}
92+
if query.syntax().has_comments_descendants() {
93+
return None;
94+
}
9095

91-
(is_empty && !has_comments && !is_constructor_with_ts_param_props_or_private).then_some(())
96+
Some(())
9297
}
9398

9499
fn diagnostic(ctx: &RuleContext<Self>, _: &Self::State) -> Option<RuleDiagnostic> {
@@ -111,10 +116,10 @@ impl Rule for NoEmptyBlockStatements {
111116
fn is_empty(query: &Query) -> bool {
112117
use Query::*;
113118
match query {
114-
JsFunctionBody(body) => body.directives().len() == 0 && body.statements().len() == 0,
115-
JsBlockStatement(block) => block.statements().len() == 0,
116-
JsStaticInitializationBlockClassMember(block) => block.statements().len() == 0,
117-
JsSwitchStatement(statement) => statement.cases().len() == 0,
119+
JsFunctionBody(body) => body.directives().is_empty() && body.statements().is_empty(),
120+
JsBlockStatement(block) => block.statements().is_empty(),
121+
JsStaticInitializationBlockClassMember(block) => block.statements().is_empty(),
122+
JsSwitchStatement(statement) => statement.cases().is_empty(),
118123
}
119124
}
120125

@@ -141,9 +146,11 @@ fn is_constructor_with_ts_param_props_or_private(query: &Query) -> bool {
141146
.parameters()
142147
.into_iter()
143148
.any(|param| matches!(param, Ok(AnyJsConstructorParameter::TsPropertyParameter(_))));
144-
let is_private = constructor
149+
if is_param_props {
150+
return true;
151+
}
152+
constructor
145153
.modifiers()
146154
.into_iter()
147-
.any(|modifier| modifier.is_private() || modifier.is_protected());
148-
is_param_props || is_private
155+
.any(|modifier| modifier.is_private() || modifier.is_protected())
149156
}

0 commit comments

Comments
 (0)