From d5948187018cdb447c3280c6d7c0878a406cfc76 Mon Sep 17 00:00:00 2001 From: overlookmotel <557937+overlookmotel@users.noreply.github.com> Date: Tue, 3 Sep 2024 00:57:12 +0000 Subject: [PATCH] fix(traverse): `insert_scope_below` update child scopes records (#5409) Follow on after #5403. Make `Traverse` update child scope IDs when inserting new scope. These lines were removed in #5232, but not reinstated in #5403. --- crates/oxc_semantic/src/scope.rs | 13 +++++++++++++ crates/oxc_traverse/src/context/scoping.rs | 6 ++++++ 2 files changed, 19 insertions(+) diff --git a/crates/oxc_semantic/src/scope.rs b/crates/oxc_semantic/src/scope.rs index 56498c12f3290..be50b57fba912 100644 --- a/crates/oxc_semantic/src/scope.rs +++ b/crates/oxc_semantic/src/scope.rs @@ -165,6 +165,7 @@ impl ScopeTree { pub fn set_parent_id(&mut self, scope_id: ScopeId, parent_id: Option) { self.parent_ids[scope_id] = parent_id; if self.build_child_ids { + // Set this scope as child of parent scope if let Some(parent_id) = parent_id { self.child_ids[parent_id].push(scope_id); } @@ -247,12 +248,24 @@ impl ScopeTree { &mut self.bindings[scope_id] } + /// Return whether this `ScopeTree` has child IDs recorded + #[inline] + pub fn has_child_ids(&self) -> bool { + self.build_child_ids + } + /// Get the child scopes of a scope #[inline] pub fn get_child_ids(&self, scope_id: ScopeId) -> &[ScopeId] { &self.child_ids[scope_id] } + /// Get a mutable reference to a scope's children + #[inline] + pub fn get_child_ids_mut(&mut self, scope_id: ScopeId) -> &mut Vec { + &mut self.child_ids[scope_id] + } + /// Create a scope. #[inline] pub fn add_scope( diff --git a/crates/oxc_traverse/src/context/scoping.rs b/crates/oxc_traverse/src/context/scoping.rs index 05f54633b4cf8..2ad9c60b26800 100644 --- a/crates/oxc_traverse/src/context/scoping.rs +++ b/crates/oxc_traverse/src/context/scoping.rs @@ -119,6 +119,12 @@ impl TraverseScoping { } fn insert_scope_below(&mut self, child_scope_ids: &[ScopeId], flags: ScopeFlags) -> ScopeId { + // Remove these scopes from parent's children + if self.scopes.has_child_ids() { + let current_child_scope_ids = self.scopes.get_child_ids_mut(self.current_scope_id); + current_child_scope_ids.retain(|scope_id| !child_scope_ids.contains(scope_id)); + } + // Create new scope as child of parent let new_scope_id = self.create_child_scope_of_current(flags);