From b1e55df85ac6051b59b1b4f4254cc885806980af Mon Sep 17 00:00:00 2001 From: rzvxa Date: Tue, 28 May 2024 16:57:01 +0330 Subject: [PATCH] improvement(linter/react): use CFG for detecting cyclic subgraphs in `rules-of-hooks`. --- .../src/rules/react/rules_of_hooks.rs | 29 ++++--------------- 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/crates/oxc_linter/src/rules/react/rules_of_hooks.rs b/crates/oxc_linter/src/rules/react/rules_of_hooks.rs index 4f6dceed3296d4..a440e6d677831b 100644 --- a/crates/oxc_linter/src/rules/react/rules_of_hooks.rs +++ b/crates/oxc_linter/src/rules/react/rules_of_hooks.rs @@ -242,12 +242,12 @@ impl Rule for RulesOfHooks { } // Is this node cyclic? - if self.is_cyclic(ctx, node, parent_func) { + if semantic.cfg().is_cyclic(node_cfg_id) { return ctx.diagnostic(diagnostics::loop_hook(span, hook_name)); } - if self.is_conditional(ctx, func_cfg_id, node_cfg_id) - || self.breaks_early(ctx, func_cfg_id, node_cfg_id) + if Self::is_conditional(ctx, func_cfg_id, node_cfg_id) + || Self::breaks_early(ctx, func_cfg_id, node_cfg_id) { #[allow(clippy::needless_return)] return ctx.diagnostic(diagnostics::conditional_hook(span, hook_name)); @@ -257,26 +257,8 @@ impl Rule for RulesOfHooks { // TODO: all `dijkstra` algorithms can be merged together for better performance. impl RulesOfHooks { - #![allow(clippy::unused_self, clippy::inline_always)] - #[inline(always)] - fn is_cyclic(&self, ctx: &LintContext, node: &AstNode, func: &AstNode) -> bool { - // TODO: use cfg instead - ctx.nodes().ancestors(node.id()).take_while(|id| *id != func.id()).any(|id| { - let maybe_loop = ctx.nodes().kind(id); - matches! { - maybe_loop, - | AstKind::DoWhileStatement(_) - | AstKind::ForInStatement(_) - | AstKind::ForOfStatement(_) - | AstKind::ForStatement(_) - | AstKind::WhileStatement(_) - } - }) - } - - #[inline(always)] + #[inline] fn is_conditional( - &self, ctx: &LintContext, func_cfg_id: BasicBlockId, node_cfg_id: BasicBlockId, @@ -293,9 +275,8 @@ impl RulesOfHooks { .any(|(f, _)| !cfg.is_reachabale(f, node_cfg_id)) } - #[inline(always)] + #[inline] fn breaks_early( - &self, ctx: &LintContext, func_cfg_id: BasicBlockId, node_cfg_id: BasicBlockId,