Skip to content

Commit

Permalink
fix(semantic): ScopeTree::rename_binding preserve order of bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
overlookmotel committed Dec 14, 2024
1 parent 5a6de6c commit 94bb514
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 5 deletions.
29 changes: 25 additions & 4 deletions crates/oxc_semantic/src/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,10 +352,31 @@ impl ScopeTree {
}

/// Rename a binding to a new name.
pub fn rename_binding(&mut self, scope_id: ScopeId, old_name: &str, new_name: CompactStr) {
if let Some(symbol_id) = self.bindings[scope_id].shift_remove(old_name) {
self.bindings[scope_id].insert(new_name, symbol_id);
}
///
/// Preserves order of bindings.
///
/// The following must be true for successful operation:
/// * Binding exists in specified scope for `old_name`.
/// * Existing binding is for specified `symbol_id`.
/// * No binding already exists for `new_name`.
///
/// Panics in debug mode if any of the above are not true.
pub fn rename_binding(
&mut self,
scope_id: ScopeId,
symbol_id: SymbolId,
old_name: &str,
new_name: CompactStr,
) {
let bindings = &mut self.bindings[scope_id];
// Insert on end
let existing_symbol_id = bindings.insert(new_name, symbol_id);
debug_assert!(existing_symbol_id.is_none());
// Remove old entry. `swap_remove` swaps the last entry into the place or removed entry.
// As we just inserted the new entry on end, this means the new entry takes the place of the old.
// Order of entries is same as before, only the key has changed.
let old_symbol_id = bindings.swap_remove(old_name);
debug_assert!(old_symbol_id == Some(symbol_id));
}

/// Reserve memory for an `additional` number of scopes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -906,7 +906,7 @@ impl<'a> ArrowFunctionConverter<'a> {
fn rename_arguments_symbol(symbol_id: SymbolId, name: CompactStr, ctx: &mut TraverseCtx<'a>) {
let scope_id = ctx.symbols().get_scope_id(symbol_id);
ctx.symbols_mut().set_name(symbol_id, name.clone());
ctx.scopes_mut().rename_binding(scope_id, "arguments", name);
ctx.scopes_mut().rename_binding(scope_id, symbol_id, "arguments", name);
}

/// Transform the identifier reference for `arguments` if it's affected after transformation.
Expand Down

0 comments on commit 94bb514

Please sign in to comment.