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

refactor(semantic)!: always create a scope for CatchClause #5109

Merged
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
2 changes: 1 addition & 1 deletion crates/oxc_ast/src/ast/js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1556,7 +1556,7 @@ pub struct TryStatement<'a> {
}

#[ast(visit)]
#[scope(flags(ScopeFlags::CatchClause), if(self.param.is_some()))]
#[scope(flags(ScopeFlags::CatchClause))]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut)]
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
Expand Down
9 changes: 2 additions & 7 deletions crates/oxc_ast/src/generated/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3711,17 +3711,12 @@ pub mod walk {
pub fn walk_catch_clause<'a, V: Visit<'a>>(visitor: &mut V, it: &CatchClause<'a>) {
let kind = AstKind::CatchClause(visitor.alloc(it));
visitor.enter_node(kind);
let scope_events_cond = it.param.is_some();
if scope_events_cond {
visitor.enter_scope(ScopeFlags::CatchClause, &it.scope_id);
}
visitor.enter_scope(ScopeFlags::CatchClause, &it.scope_id);
if let Some(param) = &it.param {
visitor.visit_catch_parameter(param);
}
visitor.visit_block_statement(&it.body);
if scope_events_cond {
visitor.leave_scope();
}
visitor.leave_scope();
visitor.leave_node(kind);
}

Expand Down
9 changes: 2 additions & 7 deletions crates/oxc_ast/src/generated/visit_mut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3923,17 +3923,12 @@ pub mod walk_mut {
pub fn walk_catch_clause<'a, V: VisitMut<'a>>(visitor: &mut V, it: &mut CatchClause<'a>) {
let kind = AstType::CatchClause;
visitor.enter_node(kind);
let scope_events_cond = it.param.is_some();
if scope_events_cond {
visitor.enter_scope(ScopeFlags::CatchClause, &it.scope_id);
}
visitor.enter_scope(ScopeFlags::CatchClause, &it.scope_id);
if let Some(param) = &mut it.param {
visitor.visit_catch_parameter(param);
}
visitor.visit_block_statement(&mut it.body);
if scope_events_cond {
visitor.leave_scope();
}
visitor.leave_scope();
visitor.leave_node(kind);
}

Expand Down
14 changes: 8 additions & 6 deletions crates/oxc_semantic/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -709,12 +709,14 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
// Move all bindings from catch clause param scope to catch clause body scope
// to make it easier to resolve references and check redeclare errors
if self.scope.get_flags(parent_scope_id).is_catch_clause() {
let parent_bindings =
self.scope.get_bindings_mut(parent_scope_id).drain(..).collect::<Bindings>();
parent_bindings.values().for_each(|symbol_id| {
self.symbols.set_scope_id(*symbol_id, self.current_scope_id);
});
*self.scope.get_bindings_mut(self.current_scope_id) = parent_bindings;
let parent_bindings = self.scope.get_bindings_mut(parent_scope_id);
if !parent_bindings.is_empty() {
let parent_bindings = parent_bindings.drain(..).collect::<Bindings>();
parent_bindings.values().for_each(|&symbol_id| {
self.symbols.set_scope_id(symbol_id, self.current_scope_id);
});
*self.scope.get_bindings_mut(self.current_scope_id) = parent_bindings;
}
}

self.visit_statements(&it.body);
Expand Down
19 changes: 8 additions & 11 deletions crates/oxc_traverse/src/walk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2025,14 +2025,13 @@ pub(crate) unsafe fn walk_catch_clause<'a, Tr: Traverse<'a>>(
ctx: &mut TraverseCtx<'a>,
) {
traverser.enter_catch_clause(&mut *node, ctx);
let mut previous_scope_id = None;
if let Some(scope_id) = (*((node as *mut u8).add(ancestor::OFFSET_CATCH_CLAUSE_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
{
previous_scope_id = Some(ctx.current_scope_id());
ctx.set_current_scope_id(scope_id);
}
let previous_scope_id = ctx.current_scope_id();
ctx.set_current_scope_id(
(*((node as *mut u8).add(ancestor::OFFSET_CATCH_CLAUSE_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap(),
);
ctx.push_stack(Ancestor::CatchClauseParam(ancestor::CatchClauseWithoutParam(node)));
if let Some(field) = &mut *((node as *mut u8).add(ancestor::OFFSET_CATCH_CLAUSE_PARAM)
as *mut Option<CatchParameter>)
Expand All @@ -2047,9 +2046,7 @@ pub(crate) unsafe fn walk_catch_clause<'a, Tr: Traverse<'a>>(
ctx,
);
ctx.pop_stack();
if let Some(previous_scope_id) = previous_scope_id {
ctx.set_current_scope_id(previous_scope_id);
}
ctx.set_current_scope_id(previous_scope_id);
traverser.exit_catch_clause(&mut *node, ctx);
}

Expand Down
28 changes: 2 additions & 26 deletions tasks/transform_conformance/babel.snap.md
Original file line number Diff line number Diff line change
Expand Up @@ -1673,22 +1673,10 @@ preset-env: unknown field `shippedProposals`, expected `targets` or `bugfixes`
| after transform: ScopeId(0): ["_unused"]
| rebuilt : ScopeId(0): []

x Scope children mismatch:
| after transform: ScopeId(0): [ScopeId(1), ScopeId(2)]
| rebuilt : ScopeId(0): [ScopeId(1), ScopeId(2)]

x Bindings mismatch:
| after transform: No scope
| rebuilt : ScopeId(2): []

x Bindings mismatch:
| after transform: ScopeId(2): []
| after transform: ScopeId(3): []
| rebuilt : ScopeId(3): ["_unused"]

x Scope parent mismatch:
| after transform: ScopeId(2): Some(ScopeId(0))
| rebuilt : ScopeId(3): Some(ScopeId(2))

x Symbol flags mismatch:
| after transform: SymbolId(0): SymbolFlags(CatchVariable)
| rebuilt : SymbolId(0): SymbolFlags(FunctionScopedVariable |
Expand All @@ -1704,22 +1692,10 @@ preset-env: unknown field `shippedProposals`, expected `targets` or `bugfixes`
| after transform: ScopeId(0): ["_unused"]
| rebuilt : ScopeId(0): []

x Scope children mismatch:
| after transform: ScopeId(0): [ScopeId(1), ScopeId(2), ScopeId(3)]
| rebuilt : ScopeId(0): [ScopeId(1), ScopeId(2), ScopeId(4)]

x Bindings mismatch:
| after transform: No scope
| rebuilt : ScopeId(2): []

x Bindings mismatch:
| after transform: ScopeId(2): []
| after transform: ScopeId(3): []
| rebuilt : ScopeId(3): ["_unused"]

x Scope parent mismatch:
| after transform: ScopeId(2): Some(ScopeId(0))
| rebuilt : ScopeId(3): Some(ScopeId(2))

x Symbol flags mismatch:
| after transform: SymbolId(0): SymbolFlags(CatchVariable)
| rebuilt : SymbolId(0): SymbolFlags(FunctionScopedVariable |
Expand Down
14 changes: 1 addition & 13 deletions tasks/transform_conformance/oxc.snap.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,10 @@ Passed: 8/35
| after transform: ScopeId(0): ["_unused", "_unused2"]
| rebuilt : ScopeId(0): ["_unused"]

x Scope children mismatch:
| after transform: ScopeId(0): [ScopeId(1), ScopeId(2)]
| rebuilt : ScopeId(0): [ScopeId(1), ScopeId(2)]

x Bindings mismatch:
| after transform: No scope
| rebuilt : ScopeId(2): []

x Bindings mismatch:
| after transform: ScopeId(2): []
| after transform: ScopeId(3): []
| rebuilt : ScopeId(3): ["_unused2"]

x Scope parent mismatch:
| after transform: ScopeId(2): Some(ScopeId(0))
| rebuilt : ScopeId(3): Some(ScopeId(2))

x Symbol flags mismatch:
| after transform: SymbolId(1): SymbolFlags(CatchVariable)
| rebuilt : SymbolId(1): SymbolFlags(FunctionScopedVariable |
Expand Down