From 409dffc8aba0736fc9a6e055d0f1d9a777eceda5 Mon Sep 17 00:00:00 2001 From: overlookmotel <557937+overlookmotel@users.noreply.github.com> Date: Sat, 5 Oct 2024 16:00:50 +0000 Subject: [PATCH] refactor(traverse)!: `generate_uid` return a `BoundIdentifier` (#6294) Closes #5020. `TraverseCtx::generate_uid` and associated methods return a `BoundIdentifier`, containing both symbol ID and name. This reduces boilerplate code for the caller and avoids and unnecessary lookup to get the name. Also add a couple of helper methods to `BoundIdentifier` to reduce boilerplate further. --- .../src/common/var_declarations.rs | 10 +-- .../src/es2015/arrow_functions.rs | 8 +- .../src/es2016/exponentiation_operator.rs | 15 ++-- .../src/es2019/optional_catch_binding.rs | 13 +-- .../src/es2020/nullish_coalescing_operator.rs | 11 +-- .../es2021/logical_assignment_operators.rs | 10 +-- crates/oxc_transformer/src/react/jsx.rs | 17 ++-- .../oxc_transformer/src/react/jsx_source.rs | 12 ++- crates/oxc_transformer/src/react/refresh.rs | 15 ++-- .../src/typescript/namespace.rs | 4 +- .../src/context/bound_identifier.rs | 60 +++++--------- crates/oxc_traverse/src/context/mod.rs | 68 +++++++++++----- crates/oxc_traverse/src/context/scoping.rs | 80 +------------------ .../snapshots/babel.snap.md | 2 +- 14 files changed, 111 insertions(+), 214 deletions(-) diff --git a/crates/oxc_transformer/src/common/var_declarations.rs b/crates/oxc_transformer/src/common/var_declarations.rs index 1258f2ff74d12..e33add93744e9 100644 --- a/crates/oxc_transformer/src/common/var_declarations.rs +++ b/crates/oxc_transformer/src/common/var_declarations.rs @@ -18,8 +18,7 @@ use oxc_allocator::Vec; use oxc_ast::{ast::*, NONE}; use oxc_data_structures::stack::SparseStack; use oxc_span::SPAN; -use oxc_syntax::symbol::SymbolId; -use oxc_traverse::{Ancestor, Traverse, TraverseCtx}; +use oxc_traverse::{Ancestor, BoundIdentifier, Traverse, TraverseCtx}; use crate::TransformCtx; @@ -68,15 +67,14 @@ impl<'a> VarDeclarationsStore<'a> { } /// Add a `VariableDeclarator` to be inserted at top of current enclosing statement block, - /// given `name` and `symbol_id`. + /// given a `BoundIdentifier`. pub fn insert( &self, - name: Atom<'a>, - symbol_id: SymbolId, + binding: &BoundIdentifier<'a>, init: Option>, ctx: &mut TraverseCtx<'a>, ) { - let ident = BindingIdentifier::new_with_symbol_id(SPAN, name, symbol_id); + let ident = binding.create_binding_identifier(); let ident = ctx.ast.binding_pattern_kind_from_binding_identifier(ident); let ident = ctx.ast.binding_pattern(ident, NONE, false); self.insert_binding_pattern(ident, init, ctx); diff --git a/crates/oxc_transformer/src/es2015/arrow_functions.rs b/crates/oxc_transformer/src/es2015/arrow_functions.rs index b8e185d0ae311..d0370e508ccb9 100644 --- a/crates/oxc_transformer/src/es2015/arrow_functions.rs +++ b/crates/oxc_transformer/src/es2015/arrow_functions.rs @@ -284,13 +284,7 @@ impl<'a> ArrowFunctions<'a> { ) && !scope_flags.contains(ScopeFlags::Arrow) }) .unwrap(); - - BoundIdentifier::new_uid( - "this", - target_scope_id, - SymbolFlags::FunctionScopedVariable, - ctx, - ) + ctx.generate_uid("this", target_scope_id, SymbolFlags::FunctionScopedVariable) }); Some(this_var.create_spanned_read_reference(span, ctx)) } diff --git a/crates/oxc_transformer/src/es2016/exponentiation_operator.rs b/crates/oxc_transformer/src/es2016/exponentiation_operator.rs index fdb40d8efe8e0..d488d5e65e3bd 100644 --- a/crates/oxc_transformer/src/es2016/exponentiation_operator.rs +++ b/crates/oxc_transformer/src/es2016/exponentiation_operator.rs @@ -290,23 +290,18 @@ impl<'a, 'ctx> ExponentiationOperator<'a, 'ctx> { _ => "ref", }; - let symbol_id = - ctx.generate_uid_in_current_scope(name, SymbolFlags::FunctionScopedVariable); - let symbol_name = ctx.ast.atom(ctx.symbols().get_name(symbol_id)); + let binding = ctx.generate_uid_in_current_scope(name, SymbolFlags::FunctionScopedVariable); // var _name; - self.ctx.var_declarations.insert(symbol_name.clone(), symbol_id, None, ctx); + self.ctx.var_declarations.insert(&binding, None, ctx); - let ident = - ctx.create_bound_reference_id(SPAN, symbol_name, symbol_id, ReferenceFlags::Read); - - // let ident = self.create_new_var_with_expression(&expr); // Add new reference `_name = name` to nodes let left = ctx.ast.simple_assignment_target_from_identifier_reference( - ctx.clone_identifier_reference(&ident, ReferenceFlags::Write), + binding.create_write_reference(ctx), ); let op = AssignmentOperator::Assign; nodes.push(ctx.ast.expression_assignment(SPAN, op, AssignmentTarget::from(left), expr)); - ctx.ast.expression_from_identifier_reference(ident) + + ctx.ast.expression_from_identifier_reference(binding.create_read_reference(ctx)) } } diff --git a/crates/oxc_transformer/src/es2019/optional_catch_binding.rs b/crates/oxc_transformer/src/es2019/optional_catch_binding.rs index 337a36a5f5830..deff5ec043643 100644 --- a/crates/oxc_transformer/src/es2019/optional_catch_binding.rs +++ b/crates/oxc_transformer/src/es2019/optional_catch_binding.rs @@ -32,7 +32,7 @@ //! * Babel plugin implementation: //! * Optional catch binding TC39 proposal: -use oxc_ast::{ast::*, NONE}; +use oxc_ast::ast::*; use oxc_semantic::SymbolFlags; use oxc_span::SPAN; use oxc_traverse::{Traverse, TraverseCtx}; @@ -53,17 +53,12 @@ impl<'a> Traverse<'a> for OptionalCatchBinding { return; } - let block_scope_id = clause.body.scope_id.get().unwrap(); - let symbol_id = ctx.generate_uid( + let binding = ctx.generate_uid( "unused", - block_scope_id, + clause.body.scope_id.get().unwrap(), SymbolFlags::CatchVariable | SymbolFlags::FunctionScopedVariable, ); - let name = ctx.ast.atom(ctx.symbols().get_name(symbol_id)); - let binding_identifier = BindingIdentifier::new_with_symbol_id(SPAN, name, symbol_id); - let binding_pattern_kind = - ctx.ast.binding_pattern_kind_from_binding_identifier(binding_identifier); - let binding_pattern = ctx.ast.binding_pattern(binding_pattern_kind, NONE, false); + let binding_pattern = binding.create_binding_pattern(ctx); let param = ctx.ast.catch_parameter(SPAN, binding_pattern); clause.param = Some(param); } diff --git a/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs b/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs index 979ad2d50d787..c1d547dbf1742 100644 --- a/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs +++ b/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs @@ -148,21 +148,16 @@ impl<'a, 'ctx> NullishCoalescingOperator<'a, 'ctx> { ctx: &mut TraverseCtx<'a>, ) -> (BindingPattern<'a>, IdentifierReference<'a>) { // Add `var name` to scope - let symbol_id = ctx.generate_uid_based_on_node( + let binding = ctx.generate_uid_based_on_node( expr, current_scope_id, SymbolFlags::FunctionScopedVariable, ); - let symbol_name = ctx.ast.atom(ctx.symbols().get_name(symbol_id)); // var _name; - let binding_identifier = - BindingIdentifier::new_with_symbol_id(SPAN, symbol_name.clone(), symbol_id); - let id = ctx.ast.binding_pattern_kind_from_binding_identifier(binding_identifier); - let id = ctx.ast.binding_pattern(id, NONE, false); - let reference = - ctx.create_bound_reference_id(SPAN, symbol_name, symbol_id, ReferenceFlags::Read); + let id = binding.create_binding_pattern(ctx); + let reference = binding.create_read_reference(ctx); (id, reference) } diff --git a/crates/oxc_transformer/src/es2021/logical_assignment_operators.rs b/crates/oxc_transformer/src/es2021/logical_assignment_operators.rs index 07215bedde2b7..006393afdc153 100644 --- a/crates/oxc_transformer/src/es2021/logical_assignment_operators.rs +++ b/crates/oxc_transformer/src/es2021/logical_assignment_operators.rs @@ -342,13 +342,11 @@ impl<'a, 'ctx> LogicalAssignmentOperators<'a, 'ctx> { return None; } - let symbol_id = ctx - .generate_uid_in_current_scope_based_on_node(expr, SymbolFlags::FunctionScopedVariable); - let name = ctx.ast.atom(ctx.symbols().get_name(symbol_id)); - // var _name; - self.ctx.var_declarations.insert(name.clone(), symbol_id, None, ctx); + let binding = ctx + .generate_uid_in_current_scope_based_on_node(expr, SymbolFlags::FunctionScopedVariable); + self.ctx.var_declarations.insert(&binding, None, ctx); - Some(BoundIdentifier::new(name, symbol_id)) + Some(binding) } } diff --git a/crates/oxc_transformer/src/react/jsx.rs b/crates/oxc_transformer/src/react/jsx.rs index c48b952f76148..483cc8bfb7c55 100644 --- a/crates/oxc_transformer/src/react/jsx.rs +++ b/crates/oxc_transformer/src/react/jsx.rs @@ -195,13 +195,11 @@ impl<'a, 'ctx> AutomaticScriptBindings<'a, 'ctx> { front: bool, ctx: &mut TraverseCtx<'a>, ) -> BoundIdentifier<'a> { - let symbol_id = + let binding = ctx.generate_uid_in_root_scope(variable_name, SymbolFlags::FunctionScopedVariable); - let variable_name = ctx.ast.atom(&ctx.symbols().names[symbol_id]); - - let import = NamedImport::new(variable_name.clone(), None, symbol_id); + let import = NamedImport::new(binding.name.clone(), None, binding.symbol_id); self.ctx.module_imports.add_import(source, import, front); - BoundIdentifier { name: variable_name, symbol_id } + binding } } @@ -297,12 +295,11 @@ impl<'a, 'ctx> AutomaticModuleBindings<'a, 'ctx> { source: Atom<'a>, ctx: &mut TraverseCtx<'a>, ) -> BoundIdentifier<'a> { - let symbol_id = ctx.generate_uid_in_root_scope(name, SymbolFlags::Import); - let local = ctx.ast.atom(&ctx.symbols().names[symbol_id]); - - let import = NamedImport::new(Atom::from(name), Some(local.clone()), symbol_id); + let binding = ctx.generate_uid_in_root_scope(name, SymbolFlags::Import); + let import = + NamedImport::new(Atom::from(name), Some(binding.name.clone()), binding.symbol_id); self.ctx.module_imports.add_import(source, import, false); - BoundIdentifier { name: local, symbol_id } + binding } } diff --git a/crates/oxc_transformer/src/react/jsx_source.rs b/crates/oxc_transformer/src/react/jsx_source.rs index 7bb84e5d6311b..411016e75d1be 100644 --- a/crates/oxc_transformer/src/react/jsx_source.rs +++ b/crates/oxc_transformer/src/react/jsx_source.rs @@ -220,14 +220,12 @@ impl<'a, 'ctx> ReactJsxSource<'a, 'ctx> { Some(decl) } - fn get_filename_var(&mut self, ctx: &mut TraverseCtx<'a>) -> BoundIdentifier<'a> { + fn get_filename_var(&mut self, ctx: &mut TraverseCtx<'a>) -> &BoundIdentifier<'a> { if self.filename_var.is_none() { - self.filename_var = Some(BoundIdentifier::new_uid_in_root_scope( - FILE_NAME_VAR, - SymbolFlags::FunctionScopedVariable, - ctx, - )); + self.filename_var = Some( + ctx.generate_uid_in_root_scope(FILE_NAME_VAR, SymbolFlags::FunctionScopedVariable), + ); } - self.filename_var.as_ref().unwrap().clone() + self.filename_var.as_ref().unwrap() } } diff --git a/crates/oxc_transformer/src/react/refresh.rs b/crates/oxc_transformer/src/react/refresh.rs index 3a81bf8a9d5b7..18d6e3f0a107f 100644 --- a/crates/oxc_transformer/src/react/refresh.rs +++ b/crates/oxc_transformer/src/react/refresh.rs @@ -467,10 +467,9 @@ impl<'a, 'ctx> ReactRefresh<'a, 'ctx> { reference_flags: ReferenceFlags, ctx: &mut TraverseCtx<'a>, ) -> AssignmentTarget<'a> { - let symbol_id = ctx.generate_uid_in_root_scope("c", SymbolFlags::FunctionScopedVariable); - self.registrations.push((symbol_id, persistent_id)); - let name = ctx.ast.atom(ctx.symbols().get_name(symbol_id)); - let ident = ctx.create_bound_reference_id(SPAN, name, symbol_id, reference_flags); + let binding = ctx.generate_uid_in_root_scope("c", SymbolFlags::FunctionScopedVariable); + self.registrations.push((binding.symbol_id, persistent_id)); + let ident = binding.create_reference(reference_flags, ctx); let ident = ctx.ast.simple_assignment_target_from_identifier_reference(ident); ctx.ast.assignment_target_simple(ident) } @@ -683,12 +682,8 @@ impl<'a, 'ctx> ReactRefresh<'a, 'ctx> { .find(|scope_id| ctx.scopes().get_flags(*scope_id).is_var()) .unwrap_or_else(|| ctx.current_scope_id()); - let symbol_id = ctx.generate_uid("s", target_scope_id, SymbolFlags::FunctionScopedVariable); - - let symbol_name = ctx.ast.atom(ctx.symbols().get_name(symbol_id)); - - let binding_identifier = - BindingIdentifier::new_with_symbol_id(SPAN, symbol_name.clone(), symbol_id); + let binding = ctx.generate_uid("s", target_scope_id, SymbolFlags::FunctionScopedVariable); + let binding_identifier = binding.create_binding_identifier(); // _s(); let call_expression = ctx.ast.statement_expression( diff --git a/crates/oxc_transformer/src/typescript/namespace.rs b/crates/oxc_transformer/src/typescript/namespace.rs index 35a57cea51cc2..bbb1ccaad01fe 100644 --- a/crates/oxc_transformer/src/typescript/namespace.rs +++ b/crates/oxc_transformer/src/typescript/namespace.rs @@ -158,8 +158,8 @@ impl<'a, 'ctx> TypeScriptNamespace<'a, 'ctx> { // Reuse `TSModuleDeclaration`'s scope in transformed function let scope_id = decl.scope_id.get().unwrap(); - let symbol_id = ctx.generate_uid(&real_name, scope_id, SymbolFlags::FunctionScopedVariable); - let name = ctx.ast.atom(ctx.symbols().get_name(symbol_id)); + let binding = ctx.generate_uid(&real_name, scope_id, SymbolFlags::FunctionScopedVariable); + let name = binding.name; let directives; let namespace_top_level; diff --git a/crates/oxc_traverse/src/context/bound_identifier.rs b/crates/oxc_traverse/src/context/bound_identifier.rs index a5155b459187f..61dea4c26c5d3 100644 --- a/crates/oxc_traverse/src/context/bound_identifier.rs +++ b/crates/oxc_traverse/src/context/bound_identifier.rs @@ -1,10 +1,9 @@ -use oxc_ast::ast::{BindingIdentifier, IdentifierReference}; -use oxc_span::{Atom, Span, SPAN}; -use oxc_syntax::{ - reference::ReferenceFlags, - scope::ScopeId, - symbol::{SymbolFlags, SymbolId}, +use oxc_ast::{ + ast::{BindingIdentifier, BindingPattern, IdentifierReference}, + NONE, }; +use oxc_span::{Atom, Span, SPAN}; +use oxc_syntax::{reference::ReferenceFlags, symbol::SymbolId}; use crate::TraverseCtx; @@ -47,44 +46,18 @@ impl<'a> BoundIdentifier<'a> { Self { name, symbol_id } } - /// Create `BoundIdentifier` for new binding in specified scope - pub fn new_uid( - name: &str, - scope_id: ScopeId, - flags: SymbolFlags, - ctx: &mut TraverseCtx<'a>, - ) -> Self { - let symbol_id = ctx.generate_uid(name, scope_id, flags); - let name = ctx.ast.atom(&ctx.symbols().names[symbol_id]); - Self { name, symbol_id } - } - - /// Create `BoundIdentifier` for new binding in root scope - pub fn new_uid_in_root_scope( - name: &str, - flags: SymbolFlags, - ctx: &mut TraverseCtx<'a>, - ) -> Self { - let scope_id = ctx.scopes().root_scope_id(); - Self::new_uid(name, scope_id, flags, ctx) - } - - /// Create `BoundIdentifier` for new binding in current scope - #[allow(unused)] - pub fn new_uid_in_current_scope( - name: &str, - flags: SymbolFlags, - ctx: &mut TraverseCtx<'a>, - ) -> Self { - let scope_id = ctx.current_scope_id(); - Self::new_uid(name, scope_id, flags, ctx) - } - /// Create `BindingIdentifier` for this binding pub fn create_binding_identifier(&self) -> BindingIdentifier<'a> { BindingIdentifier::new_with_symbol_id(SPAN, self.name.clone(), self.symbol_id) } + /// Create `BindingPattern` for this binding + pub fn create_binding_pattern(&self, ctx: &mut TraverseCtx<'a>) -> BindingPattern<'a> { + let ident = self.create_binding_identifier(); + let binding_pattern_kind = ctx.ast.binding_pattern_kind_from_binding_identifier(ident); + ctx.ast.binding_pattern(binding_pattern_kind, NONE, false) + } + /// Create `IdentifierReference` referencing this binding, which is read from, with dummy `Span` pub fn create_read_reference(&self, ctx: &mut TraverseCtx<'a>) -> IdentifierReference<'a> { self.create_spanned_read_reference(SPAN, ctx) @@ -134,6 +107,15 @@ impl<'a> BoundIdentifier<'a> { self.create_spanned_reference(span, ReferenceFlags::Read | ReferenceFlags::Write, ctx) } + /// Create `IdentifierReference` referencing this binding, with specified `ReferenceFlags` + pub fn create_reference( + &self, + flags: ReferenceFlags, + ctx: &mut TraverseCtx<'a>, + ) -> IdentifierReference<'a> { + self.create_spanned_reference(SPAN, flags, ctx) + } + /// Create `IdentifierReference` referencing this binding, with specified `Span` and `ReferenceFlags` pub fn create_spanned_reference( &self, diff --git a/crates/oxc_traverse/src/context/mod.rs b/crates/oxc_traverse/src/context/mod.rs index 562bbc7da7eff..333a99e4bf1e6 100644 --- a/crates/oxc_traverse/src/context/mod.rs +++ b/crates/oxc_traverse/src/context/mod.rs @@ -3,8 +3,8 @@ use oxc_ast::{ ast::{Expression, IdentifierReference, Statement}, AstBuilder, }; -use oxc_semantic::{ScopeTree, SymbolTable}; -use oxc_span::{Atom, CompactStr, Span}; +use oxc_semantic::{NodeId, ScopeTree, SymbolTable}; +use oxc_span::{Atom, CompactStr, Span, SPAN}; use oxc_syntax::{ reference::{ReferenceFlags, ReferenceId}, scope::{ScopeFlags, ScopeId}, @@ -15,11 +15,13 @@ use crate::ancestor::{Ancestor, AncestorType}; mod ancestry; mod ast_operations; +use ast_operations::GatherNodeParts; mod bound_identifier; use ancestry::PopToken; pub use ancestry::TraverseAncestry; pub use bound_identifier::BoundIdentifier; mod identifier; +use identifier::to_identifier; mod scoping; pub use scoping::TraverseScoping; @@ -299,49 +301,73 @@ impl<'a> TraverseCtx<'a> { /// /// See also comments on [`TraverseScoping::generate_uid_name`] for important information /// on how UIDs are generated. There are some potential "gotchas". - /// - /// This is a shortcut for `ctx.scoping.generate_uid`. #[inline] - pub fn generate_uid(&mut self, name: &str, scope_id: ScopeId, flags: SymbolFlags) -> SymbolId { - self.scoping.generate_uid(name, scope_id, flags) + pub fn generate_uid( + &mut self, + name: &str, + scope_id: ScopeId, + flags: SymbolFlags, + ) -> BoundIdentifier<'a> { + // Get name for UID + let name = self.generate_uid_name(name); + let name_atom = self.ast.atom(&name); + + // Add binding to scope + let symbol_id = + self.symbols_mut().create_symbol(SPAN, name.clone(), flags, scope_id, NodeId::DUMMY); + self.scopes_mut().add_binding(scope_id, name, symbol_id); + + BoundIdentifier::new(name_atom, symbol_id) } /// Generate UID in current scope. /// /// See also comments on [`TraverseScoping::generate_uid_name`] for important information /// on how UIDs are generated. There are some potential "gotchas". - /// - /// This is a shortcut for `ctx.scoping.generate_uid_in_current_scope`. #[inline] - pub fn generate_uid_in_current_scope(&mut self, name: &str, flags: SymbolFlags) -> SymbolId { - self.scoping.generate_uid_in_current_scope(name, flags) + pub fn generate_uid_in_current_scope( + &mut self, + name: &str, + flags: SymbolFlags, + ) -> BoundIdentifier<'a> { + self.generate_uid(name, self.current_scope_id(), flags) } /// Generate UID in root scope. /// /// See also comments on [`TraverseScoping::generate_uid_name`] for important information /// on how UIDs are generated. There are some potential "gotchas". - /// - /// This is a shortcut for `ctx.scoping.generate_uid_in_root_scope`. #[inline] - pub fn generate_uid_in_root_scope(&mut self, name: &str, flags: SymbolFlags) -> SymbolId { - self.scoping.generate_uid_in_root_scope(name, flags) + pub fn generate_uid_in_root_scope( + &mut self, + name: &str, + flags: SymbolFlags, + ) -> BoundIdentifier<'a> { + self.generate_uid(name, self.scopes().root_scope_id(), flags) } /// Generate UID based on node. /// - /// See also comments on [`TraverseScoping::generate_uid_name`] for important information - /// on how UIDs are generated. There are some potential "gotchas". + /// Recursively gathers the identifying names of a node, and joins them with `$`. /// - /// This is a shortcut for `ctx.scoping.generate_uid_based_on_node`. + /// Based on Babel's `scope.generateUidBasedOnNode` logic. + /// #[inline] pub fn generate_uid_based_on_node( &mut self, node: &Expression<'a>, scope_id: ScopeId, flags: SymbolFlags, - ) -> SymbolId { - self.scoping.generate_uid_based_on_node(node, scope_id, flags) + ) -> BoundIdentifier<'a> { + let mut parts = String::new(); + node.gather(&mut |part| { + if !parts.is_empty() { + parts.push('$'); + } + parts.push_str(part); + }); + let name = if parts.is_empty() { "ref" } else { parts.trim_start_matches('_') }; + self.generate_uid(&to_identifier(name.get(..20).unwrap_or(name)), scope_id, flags) } /// Generate UID in current scope based on node. @@ -355,8 +381,8 @@ impl<'a> TraverseCtx<'a> { &mut self, node: &Expression<'a>, flags: SymbolFlags, - ) -> SymbolId { - self.scoping.generate_uid_in_current_scope_based_on_node(node, flags) + ) -> BoundIdentifier<'a> { + self.generate_uid_based_on_node(node, self.current_scope_id(), flags) } /// Create a reference bound to a `SymbolId`. diff --git a/crates/oxc_traverse/src/context/scoping.rs b/crates/oxc_traverse/src/context/scoping.rs index acb66c3e19e40..f446f4d60d73a 100644 --- a/crates/oxc_traverse/src/context/scoping.rs +++ b/crates/oxc_traverse/src/context/scoping.rs @@ -7,14 +7,13 @@ use rustc_hash::FxHashSet; #[allow(clippy::wildcard_imports)] use oxc_ast::{ast::*, visit::Visit}; use oxc_semantic::{NodeId, Reference, ScopeTree, SymbolTable}; -use oxc_span::{Atom, CompactStr, Span, SPAN}; +use oxc_span::{Atom, CompactStr, Span}; use oxc_syntax::{ reference::{ReferenceFlags, ReferenceId}, scope::{ScopeFlags, ScopeId}, - symbol::{SymbolFlags, SymbolId}, + symbol::SymbolId, }; -use super::{ast_operations::GatherNodeParts, identifier::to_identifier}; use crate::scopes_collector::ChildScopeCollector; /// Traverse scope context. @@ -229,81 +228,6 @@ impl TraverseScoping { uid } - /// Generate UID in provided scope. - /// - /// See also comments on [`TraverseScoping::generate_uid_name`] for important information - /// on how UIDs are generated. There are some potential "gotchas". - pub fn generate_uid(&mut self, name: &str, scope_id: ScopeId, flags: SymbolFlags) -> SymbolId { - // Get name for UID - let name = self.generate_uid_name(name); - - // Add binding to scope - let symbol_id = - self.symbols.create_symbol(SPAN, name.clone(), flags, scope_id, NodeId::DUMMY); - self.scopes.add_binding(scope_id, name, symbol_id); - symbol_id - } - - /// Generate UID in current scope. - /// - /// See also comments on [`TraverseScoping::generate_uid_name`] for important information - /// on how UIDs are generated. There are some potential "gotchas". - pub fn generate_uid_in_current_scope(&mut self, name: &str, flags: SymbolFlags) -> SymbolId { - self.generate_uid(name, self.current_scope_id, flags) - } - - /// Generate UID in root scope. - /// - /// See also comments on [`TraverseScoping::generate_uid_name`] for important information - /// on how UIDs are generated. There are some potential "gotchas". - pub fn generate_uid_in_root_scope(&mut self, name: &str, flags: SymbolFlags) -> SymbolId { - self.generate_uid(name, self.scopes.root_scope_id(), flags) - } - - /// Generate UID based on node. - /// - /// Recursively gathers the identifying names of a node, and joins them with `$`. - /// - /// Based on Babel's `scope.generateUidBasedOnNode` logic. - /// - /// - /// See also comments on [`TraverseScoping::generate_uid_name`] for important information - /// on how UIDs are generated. There are some potential "gotchas". - pub fn generate_uid_based_on_node<'a, T>( - &mut self, - node: &T, - scope_id: ScopeId, - flags: SymbolFlags, - ) -> SymbolId - where - T: GatherNodeParts<'a>, - { - let mut parts = String::new(); - node.gather(&mut |part| { - if !parts.is_empty() { - parts.push('$'); - } - parts.push_str(part); - }); - let name = if parts.is_empty() { "ref" } else { parts.trim_start_matches('_') }; - self.generate_uid(&to_identifier(name.get(..20).unwrap_or(name)), scope_id, flags) - } - - /// Generate UID in current scope based on node. - /// - /// See also comments on [`TraverseScoping::generate_uid_name`] for important information - /// on how UIDs are generated. There are some potential "gotchas". - pub fn generate_uid_in_current_scope_based_on_node<'a, T>( - &mut self, - node: &T, - flags: SymbolFlags, - ) -> SymbolId - where - T: GatherNodeParts<'a>, - { - self.generate_uid_based_on_node(node, self.current_scope_id, flags) - } - /// Create a reference bound to a `SymbolId` pub fn create_bound_reference( &mut self, diff --git a/tasks/transform_conformance/snapshots/babel.snap.md b/tasks/transform_conformance/snapshots/babel.snap.md index 11e9b457fc098..a12fd2a2214ce 100644 --- a/tasks/transform_conformance/snapshots/babel.snap.md +++ b/tasks/transform_conformance/snapshots/babel.snap.md @@ -1645,7 +1645,7 @@ x Output mismatch * regression/4403/input.js Reference flags mismatch for "_ref": -after transform: ReferenceId(3): ReferenceFlags(Write) +after transform: ReferenceId(2): ReferenceFlags(Write) rebuilt : ReferenceId(0): ReferenceFlags(Read | Write)