From 3b99fe6d5933350ca7dac77164a8d4bfe0727529 Mon Sep 17 00:00:00 2001 From: overlookmotel <557937+overlookmotel@users.noreply.github.com> Date: Thu, 24 Oct 2024 06:19:39 +0000 Subject: [PATCH] refactor(traverse): move `generate_binding` to `TraverseScoping` (#6831) Follow-up after #6830. Now that `generate_binding` doesn't need access to `AstBuilder`, it can move into `TraverseScoping`. Occasionally this is helpful when you need to borrows 2 parts of `TraverseCtx` simultaneously. e.g.: ```rs // This fails to compile because we try to mutably borrow `TraverseCtx` // while it's already borrowed if let Ancestor::ProgramBody(body) = ctx.parent() { // ^^^ immutable borrow let binding = ctx.generate_binding(name, scope_id, flags); // ^^^ mutable borrow } // Borrow-checker allows this because we borrow fields of `TraverseCtx` separately if let Ancestor::ProgramBody(body) = ctx.ancestry.parent() { let binding = ctx.scoping.generate_binding(name, scope_id, flags); } ``` --- crates/oxc_traverse/src/context/mod.rs | 20 ++++-------- crates/oxc_traverse/src/context/scoping.rs | 36 ++++++++++++++++++++-- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/crates/oxc_traverse/src/context/mod.rs b/crates/oxc_traverse/src/context/mod.rs index 3ef056d70cade..ca3981ac3cc4e 100644 --- a/crates/oxc_traverse/src/context/mod.rs +++ b/crates/oxc_traverse/src/context/mod.rs @@ -304,36 +304,28 @@ impl<'a> TraverseCtx<'a> { /// Generate binding. /// /// Creates a symbol with the provided name and flags and adds it to the specified scope. + /// + /// This is a shortcut for `ctx.scoping.generate_binding`. pub fn generate_binding( &mut self, name: Atom<'a>, scope_id: ScopeId, flags: SymbolFlags, ) -> BoundIdentifier<'a> { - let owned_name = name.to_compact_str(); - - // Add binding to scope - let symbol_id = self.symbols_mut().create_symbol( - SPAN, - owned_name.clone(), - flags, - scope_id, - NodeId::DUMMY, - ); - self.scopes_mut().add_binding(scope_id, owned_name, symbol_id); - - BoundIdentifier::new(name, symbol_id) + self.scoping.generate_binding(name, scope_id, flags) } /// Generate binding in current scope. /// /// Creates a symbol with the provided name and flags and adds it to the current scope. + /// + /// This is a shortcut for `ctx.scoping.generate_in_current_scope`. pub fn generate_in_current_scope( &mut self, name: Atom<'a>, flags: SymbolFlags, ) -> BoundIdentifier<'a> { - self.generate_binding(name, self.current_scope_id(), flags) + self.scoping.generate_in_current_scope(name, flags) } /// Generate UID var name. diff --git a/crates/oxc_traverse/src/context/scoping.rs b/crates/oxc_traverse/src/context/scoping.rs index 6ef30004c0cd1..9ca509b07b6d9 100644 --- a/crates/oxc_traverse/src/context/scoping.rs +++ b/crates/oxc_traverse/src/context/scoping.rs @@ -7,14 +7,14 @@ use rustc_hash::FxHashSet; #[allow(clippy::wildcard_imports)] use oxc_ast::{ast::*, visit::Visit}; use oxc_semantic::{NodeId, Reference, ScopeTree, SymbolTable}; -use oxc_span::CompactStr; +use oxc_span::{CompactStr, SPAN}; use oxc_syntax::{ reference::{ReferenceFlags, ReferenceId}, scope::{ScopeFlags, ScopeId}, - symbol::SymbolId, + symbol::{SymbolFlags, SymbolId}, }; -use crate::scopes_collector::ChildScopeCollector; +use crate::{scopes_collector::ChildScopeCollector, BoundIdentifier}; /// Traverse scope context. /// @@ -165,6 +165,36 @@ impl TraverseScoping { self.scopes.delete_scope(scope_id); } + /// Generate binding. + /// + /// Creates a symbol with the provided name and flags and adds it to the specified scope. + pub fn generate_binding<'a>( + &mut self, + name: Atom<'a>, + scope_id: ScopeId, + flags: SymbolFlags, + ) -> BoundIdentifier<'a> { + let owned_name = name.to_compact_str(); + + // Add binding to scope + let symbol_id = + self.symbols.create_symbol(SPAN, owned_name.clone(), flags, scope_id, NodeId::DUMMY); + self.scopes.add_binding(scope_id, owned_name, symbol_id); + + BoundIdentifier::new(name, symbol_id) + } + + /// Generate binding in current scope. + /// + /// Creates a symbol with the provided name and flags and adds it to the current scope. + pub fn generate_in_current_scope<'a>( + &mut self, + name: Atom<'a>, + flags: SymbolFlags, + ) -> BoundIdentifier<'a> { + self.generate_binding(name, self.current_scope_id, flags) + } + /// Generate UID var name. /// /// Finds a unique variable name which does clash with any other variables used in the program.