Skip to content

Commit 088e6a4

Browse files
committed
fix(transformer/using): correctly reparent scopes in for of stmt
1 parent c7fc700 commit 088e6a4

File tree

3 files changed

+47
-14
lines changed

3 files changed

+47
-14
lines changed

crates/oxc_transformer/src/proposals/explicit_resource_management.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,11 @@ impl<'a> Traverse<'a> for ExplicitResourceManagement<'a, '_> {
115115

116116
let scope_id = match &mut for_of_stmt.body {
117117
Statement::BlockStatement(block) => block.scope_id(),
118-
_ => ctx.create_child_scope(for_of_stmt_scope_id, ScopeFlags::empty()),
118+
_ => ctx.scoping.insert_scope_below_statement_from_scope_id(
119+
&for_of_stmt.body,
120+
for_of_stmt.scope_id(),
121+
ScopeFlags::empty(),
122+
),
119123
};
120124
ctx.scoping_mut().set_symbol_scope_id(for_of_init_symbol_id, scope_id);
121125
ctx.scoping_mut().move_binding(for_of_stmt_scope_id, scope_id, &for_of_init_name);

crates/oxc_traverse/src/context/scoping.rs

+40
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,24 @@ impl TraverseScoping {
102102
self.insert_scope_below(&collector.scope_ids, flags)
103103
}
104104

105+
/// Insert a scope into scope tree below a statement.
106+
///
107+
/// Statement must be in provided scope.
108+
/// New scope is created as child of the provided scope.
109+
/// All child scopes of the statement are reassigned to be children of the new scope.
110+
///
111+
/// `flags` provided are amended to inherit from parent scope's flags.
112+
pub fn insert_scope_below_statement_from_scope_id(
113+
&mut self,
114+
stmt: &Statement,
115+
scope_id: ScopeId,
116+
flags: ScopeFlags,
117+
) -> ScopeId {
118+
let mut collector = ChildScopeCollector::new();
119+
collector.visit_statement(stmt);
120+
self.insert_scope_below_from_scope_id(&collector.scope_ids, scope_id, flags)
121+
}
122+
105123
/// Insert a scope into scope tree below an expression.
106124
///
107125
/// Expression must be in current scope.
@@ -153,6 +171,28 @@ impl TraverseScoping {
153171
new_scope_id
154172
}
155173

174+
fn insert_scope_below_from_scope_id(
175+
&mut self,
176+
child_scope_ids: &[ScopeId],
177+
scope_id: ScopeId,
178+
flags: ScopeFlags,
179+
) -> ScopeId {
180+
// Remove these scopes from parent's children
181+
if self.scoping.has_scope_child_ids() {
182+
self.scoping.remove_child_scopes(scope_id, child_scope_ids);
183+
}
184+
185+
// Create new scope as child of parent
186+
let new_scope_id = self.create_child_scope(scope_id, flags);
187+
188+
// Set scopes as children of new scope instead
189+
for &child_id in child_scope_ids {
190+
self.scoping.set_scope_parent_id(child_id, Some(new_scope_id));
191+
}
192+
193+
new_scope_id
194+
}
195+
156196
/// Remove scope for an expression from the scope chain.
157197
///
158198
/// Delete the scope and set parent of its child scopes to its parent scope.

tasks/transform_conformance/snapshots/oxc.snap.md

+2-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
commit: 578ac4df
22

3-
Passed: 138/229
3+
Passed: 139/229
44

55
# All Passed:
66
* babel-plugin-transform-class-static-block
@@ -320,21 +320,10 @@ x Output mismatch
320320
x Output mismatch
321321

322322

323-
# babel-plugin-proposal-explicit-resource-management (0/3)
323+
# babel-plugin-proposal-explicit-resource-management (1/3)
324324
* export-class-name/input.js
325325
x Output mismatch
326326

327-
* for-of-no-block/input.js
328-
Scope children mismatch:
329-
after transform: ScopeId(1): [ScopeId(2), ScopeId(3), ScopeId(4), ScopeId(5), ScopeId(7)]
330-
rebuilt : ScopeId(1): [ScopeId(2), ScopeId(3), ScopeId(5), ScopeId(7)]
331-
Scope children mismatch:
332-
after transform: ScopeId(4): []
333-
rebuilt : ScopeId(3): [ScopeId(4)]
334-
Scope parent mismatch:
335-
after transform: ScopeId(3): Some(ScopeId(1))
336-
rebuilt : ScopeId(4): Some(ScopeId(3))
337-
338327
* function-with-scopes-in-params/input.js
339328
Bindings mismatch:
340329
after transform: ScopeId(1): ["_usingCtx", "a", "b", "x", "y"]

0 commit comments

Comments
 (0)