Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(traverse): add TraverseCtx::change_parent_scope_for_expression #8510

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions crates/oxc_traverse/src/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,21 @@ impl<'a> TraverseCtx<'a> {
self.scoping.remove_scope_for_expression(scope_id, expr);
}

/// Change parent scope for an expression.
///
/// Set parent of its child scopes to the given parent scope.
///
/// Use this when wrapping an expression with an arrow function, or similar.
/// For example when wrapping `() => foo` to `() => { return () => foo }`,
/// the parent scope of inner arrow function `() => foo` should be the
/// new outside arrow function.
///
/// This is a shortcut for `ctx.scoping.change_parent_scope_for_expression`.
#[inline]
pub fn change_parent_scope_for_expression(&mut self, scope_id: ScopeId, expr: &Expression) {
self.scoping.change_parent_scope_for_expression(scope_id, expr);
}

/// Generate binding.
///
/// Creates a symbol with the provided name and flags and adds it to the specified scope.
Expand Down
24 changes: 24 additions & 0 deletions crates/oxc_traverse/src/context/scoping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,30 @@ impl TraverseScoping {
self.scopes.delete_scope(scope_id);
}

/// Change parent scope for an expression.
///
/// Set parent of its child scopes to the given parent scope.
///
/// Use this when wrapping an expression with an arrow function, or similar.
/// For example when wrapping `() => foo` to `() => { return () => foo }`,
/// the parent scope of inner arrow function `() => foo` should be the
/// new outside arrow function.
pub fn change_parent_scope_for_expression(
&mut self,
parent_scope_id: ScopeId,
expr: &Expression,
) {
let mut collector = ChildScopeCollector::new();
collector.visit_expression(expr);

let child_ids = collector.scope_ids;
if !child_ids.is_empty() {
for child_id in child_ids {
self.scopes.set_parent_id(child_id, Some(parent_scope_id));
}
}
}

/// Add binding to [`ScopeTree`] and [`SymbolTable`].
#[inline]
pub(crate) fn add_binding(
Expand Down
Loading