From d6974d4ff7264764ca3aaedaa2dfcc18bebef1c8 Mon Sep 17 00:00:00 2001 From: overlookmotel <557937+overlookmotel@users.noreply.github.com> Date: Mon, 29 Jul 2024 18:27:38 +0000 Subject: [PATCH] refactor(semantic): `AstNodeParentIter` fetch nodes lazily (#4533) Refactor `AstNodeParentIter`, which is used to iterate down node ancestry chain. Fetch `AstNode` objects lazily, only when they're required by a `next()` call. If caller doesn't iterate all the way down the chain, likely this will result in 1 less array lookup. --- crates/oxc_semantic/src/node.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/crates/oxc_semantic/src/node.rs b/crates/oxc_semantic/src/node.rs index 1ce686d90af61..5e60ce83cdb08 100644 --- a/crates/oxc_semantic/src/node.rs +++ b/crates/oxc_semantic/src/node.rs @@ -94,9 +94,9 @@ impl<'a> AstNodes<'a> { /// /// The first node produced by this iterator is the first parent of the node /// pointed to by `node_id`. The last node will usually be a `Program`. + #[inline] pub fn iter_parents(&self, node_id: AstNodeId) -> impl Iterator> + '_ { - let curr = Some(self.get_node(node_id)); - AstNodeParentIter { curr, nodes: self } + AstNodeParentIter { current_node_id: Some(node_id), nodes: self } } #[inline] @@ -197,7 +197,7 @@ impl<'a> AstNodes<'a> { #[derive(Debug)] pub struct AstNodeParentIter<'s, 'a> { - curr: Option<&'s AstNode<'a>>, + current_node_id: Option, nodes: &'s AstNodes<'a>, } @@ -205,9 +205,11 @@ impl<'s, 'a> Iterator for AstNodeParentIter<'s, 'a> { type Item = &'s AstNode<'a>; fn next(&mut self) -> Option { - let next = self.curr; - self.curr = self.curr.and_then(|curr| self.nodes.parent_node(curr.id())); - - next + if let Some(node_id) = self.current_node_id { + self.current_node_id = self.nodes.parent_ids[node_id]; + Some(self.nodes.get_node(node_id)) + } else { + None + } } }