From a36d5a6ba8c24c72d15149697a7d2223c0e32960 Mon Sep 17 00:00:00 2001 From: Sergei Zharinov Date: Mon, 29 Dec 2025 23:35:56 -0300 Subject: [PATCH] refactor(dependencies): consolidate RefFinder structs --- crates/plotnik-lib/src/query/dependencies.rs | 70 +++++++++----------- 1 file changed, 32 insertions(+), 38 deletions(-) diff --git a/crates/plotnik-lib/src/query/dependencies.rs b/crates/plotnik-lib/src/query/dependencies.rs index 1bc73481..343dd14c 100644 --- a/crates/plotnik-lib/src/query/dependencies.rs +++ b/crates/plotnik-lib/src/query/dependencies.rs @@ -515,9 +515,19 @@ fn collect_refs<'a>(expr: &Expr, symbol_table: &'a SymbolTable) -> IndexSet<&'a refs } +/// Whether to search for any reference or only unguarded ones. +#[derive(Clone, Copy, PartialEq, Eq)] +enum RefSearchMode { + /// Find any reference to the target. + Any, + /// Find only unguarded references (not inside a NamedNode/AnonymousNode). + Unguarded, +} + struct RefFinder<'a> { target: &'a str, found: Option, + mode: RefSearchMode, } impl Visitor for RefFinder<'_> { @@ -528,49 +538,22 @@ impl Visitor for RefFinder<'_> { walk_expr(self, expr); } - fn visit_ref(&mut self, r: &Ref) { - if self.found.is_some() { - return; - } - if let Some(name) = r.name() - && name.text() == self.target - { - self.found = Some(name.text_range()); - } - } -} - -fn find_ref_range(expr: &Expr, target: &str) -> Option { - let mut visitor = RefFinder { - target, - found: None, - }; - visitor.visit_expr(expr); - visitor.found -} - -struct UnguardedRefFinder<'a> { - target: &'a str, - found: Option, -} - -impl Visitor for UnguardedRefFinder<'_> { - fn visit_expr(&mut self, expr: &Expr) { - if self.found.is_some() { - return; + fn visit_named_node(&mut self, node: &NamedNode) { + if self.mode == RefSearchMode::Unguarded { + return; // Guarded: stop recursion } - walk_expr(self, expr); - } - - fn visit_named_node(&mut self, _node: &NamedNode) { - // Guarded: stop recursion + super::visitor::walk_named_node(self, node); } fn visit_anonymous_node(&mut self, _node: &AnonymousNode) { - // Guarded: stop recursion + // AnonymousNode has no child expressions, so nothing to walk. + // In Unguarded mode this also acts as a guard (stops recursion). } fn visit_ref(&mut self, r: &Ref) { + if self.found.is_some() { + return; + } if let Some(name) = r.name() && name.text() == self.target { @@ -584,17 +567,28 @@ impl Visitor for UnguardedRefFinder<'_> { if self.found.is_some() { return; } - if expr_guarantees_consumption(&child) { + if self.mode == RefSearchMode::Unguarded && expr_guarantees_consumption(&child) { return; } } } } +fn find_ref_range(expr: &Expr, target: &str) -> Option { + let mut visitor = RefFinder { + target, + found: None, + mode: RefSearchMode::Any, + }; + visitor.visit_expr(expr); + visitor.found +} + fn find_unguarded_ref_range(expr: &Expr, target: &str) -> Option { - let mut visitor = UnguardedRefFinder { + let mut visitor = RefFinder { target, found: None, + mode: RefSearchMode::Unguarded, }; visitor.visit_expr(expr); visitor.found