Skip to content

Commit 17956c1

Browse files
committed
perf(linter): skip running node-specific rule if file contains no relevant nodes (#14457)
Finally making use of the optimizations enabled by #13137. We can use the AST type bitset for each file to skip rules that only care about specific node types if the file has none of those node types.
1 parent d21833b commit 17956c1

File tree

1 file changed

+16
-2
lines changed

1 file changed

+16
-2
lines changed

crates/oxc_linter/src/lib.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ impl Linter {
173173
.is_some_and(|ext| LINT_PARTIAL_LOADER_EXTENSIONS.contains(&ext));
174174

175175
loop {
176-
let rules = rules
176+
let mut rules = rules
177177
.iter()
178178
.filter(|(rule, _)| rule.should_run(&ctx_host) && !rule.is_tsgolint_rule())
179179
.map(|(rule, severity)| (rule, Rc::clone(&ctx_host).spawn(rule, *severity)))
@@ -184,7 +184,21 @@ impl Linter {
184184
let should_run_on_jest_node =
185185
ctx_host.plugins().has_test() && ctx_host.frameworks().is_test();
186186

187-
let execute_rules = |with_runtime_optimization: bool| {
187+
let mut execute_rules = |with_runtime_optimization: bool| {
188+
// If only the `run` function is implemented, we can skip running the file entirely if the current
189+
// file does not contain any of the relevant AST node types.
190+
if with_runtime_optimization {
191+
rules.retain(|(rule, _)| {
192+
let run_info = rule.run_info();
193+
if run_info == RuleRunFunctionsImplemented::Run
194+
&& let Some(ast_types) = rule.types_info()
195+
{
196+
semantic.nodes().contains_any(ast_types)
197+
} else {
198+
true
199+
}
200+
});
201+
}
188202
// IMPORTANT: We have two branches here for performance reasons:
189203
//
190204
// 1) Branch where we iterate over each node, then each rule

0 commit comments

Comments
 (0)