Skip to content

Commit

Permalink
feat(traverse): generate_uid_name method
Browse files Browse the repository at this point in the history
  • Loading branch information
overlookmotel committed Sep 17, 2024
1 parent b24ab2f commit 82e8778
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 17 deletions.
27 changes: 27 additions & 0 deletions crates/oxc_traverse/src/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,23 @@ impl<'a> TraverseCtx<'a> {
self.scoping.insert_scope_below_expression(expr, flags)
}

/// Generate UID var name.
///
/// Finds a unique variable name which does clash with any other variables used in the program.
///
/// See [`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_name`.
pub fn generate_uid_name(&mut self, name: &str) -> CompactStr {
self.scoping.generate_uid_name(name)
}

/// Generate UID.
///
/// 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 {
Expand All @@ -290,6 +305,9 @@ impl<'a> TraverseCtx<'a> {

/// 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 {
Expand All @@ -298,6 +316,9 @@ impl<'a> TraverseCtx<'a> {

/// 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 {
Expand All @@ -306,6 +327,9 @@ impl<'a> TraverseCtx<'a> {

/// 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".
///
/// This is a shortcut for `ctx.scoping.generate_uid_based_on_node`.
#[inline]
pub fn generate_uid_based_on_node(
Expand All @@ -319,6 +343,9 @@ impl<'a> TraverseCtx<'a> {

/// 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".
///
/// This is a shortcut for `ctx.scoping.generate_uid_in_current_scope_based_on_node`.
#[inline]
pub fn generate_uid_in_current_scope_based_on_node(
Expand Down
49 changes: 32 additions & 17 deletions crates/oxc_traverse/src/context/scoping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,9 @@ impl TraverseScoping {
new_scope_id
}

/// Generate UID.
/// Generate UID var name.
///
/// Finds a unique variable name which does clash with any other variables used in the program.
/// Generates a binding for it in scope provided.
///
/// Based on Babel's `scope.generateUid` logic.
/// <https://github.com/babel/babel/blob/3b1a3c0be9df65140260a316c1a21adcf948645d/packages/babel-traverse/src/scope/index.ts#L501-L523>
Expand Down Expand Up @@ -216,9 +215,27 @@ impl TraverseScoping {
/// what was found in AST.
/// i.e. if source contains identifiers `_foo` and `__bar`, create UIDs names `___0`, `___1`,
/// `___2` etc. They'll all be unique within the program.
#[allow(clippy::missing_panics_doc)]
pub fn generate_uid_name(&mut self, name: &str) -> CompactStr {
// If `uid_names` is not already populated, initialize it
if self.uid_names.is_none() {
self.init_uid_names();
}
let uid_names = self.uid_names.as_mut().unwrap();

let base = get_uid_name_base(name);
let uid = get_unique_name(base, uid_names);
uid_names.insert(uid.clone());
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.find_uid_name(name);
let name = self.generate_uid_name(name);

// Add binding to scope
let symbol_id =
Expand All @@ -228,11 +245,17 @@ impl TraverseScoping {
}

/// 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)
}
Expand All @@ -243,6 +266,9 @@ impl TraverseScoping {
///
/// Based on Babel's `scope.generateUidBasedOnNode` logic.
/// <https://github.com/babel/babel/blob/419644f27c5c59deb19e71aaabd417a3bc5483ca/packages/babel-traverse/src/scope/index.ts#L543>
///
/// 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,
Expand All @@ -264,6 +290,9 @@ impl TraverseScoping {
}

/// 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,
Expand Down Expand Up @@ -453,20 +482,6 @@ impl TraverseScoping {
self.current_scope_id = scope_id;
}

/// Find a variable name which can be used as a UID
fn find_uid_name(&mut self, name: &str) -> CompactStr {
// If `uid_names` is not already populated, initialize it
if self.uid_names.is_none() {
self.init_uid_names();
}
let uid_names = self.uid_names.as_mut().unwrap();

let base = get_uid_name_base(name);
let uid = get_unique_name(base, uid_names);
uid_names.insert(uid.clone());
uid
}

/// Initialize `uid_names`.
///
/// Iterate through all symbols and unresolved references in AST and identify any var names
Expand Down

0 comments on commit 82e8778

Please sign in to comment.