diff --git a/crates/oxc_ast/src/ast/js.rs b/crates/oxc_ast/src/ast/js.rs index 0b614378e..ae8d6f9d2 100644 --- a/crates/oxc_ast/src/ast/js.rs +++ b/crates/oxc_ast/src/ast/js.rs @@ -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))] diff --git a/crates/oxc_ast/src/generated/visit.rs b/crates/oxc_ast/src/generated/visit.rs index 9c07a8bf4..fd4fa802f 100644 --- a/crates/oxc_ast/src/generated/visit.rs +++ b/crates/oxc_ast/src/generated/visit.rs @@ -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); } diff --git a/crates/oxc_ast/src/generated/visit_mut.rs b/crates/oxc_ast/src/generated/visit_mut.rs index 23beadf71..8426af9f6 100644 --- a/crates/oxc_ast/src/generated/visit_mut.rs +++ b/crates/oxc_ast/src/generated/visit_mut.rs @@ -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); } diff --git a/crates/oxc_semantic/src/builder.rs b/crates/oxc_semantic/src/builder.rs index 410da10c2..0b118da5a 100644 --- a/crates/oxc_semantic/src/builder.rs +++ b/crates/oxc_semantic/src/builder.rs @@ -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::(); - 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::(); + 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); diff --git a/crates/oxc_traverse/src/walk.rs b/crates/oxc_traverse/src/walk.rs index efe45c3df..d3ded3cc5 100644 --- a/crates/oxc_traverse/src/walk.rs +++ b/crates/oxc_traverse/src/walk.rs @@ -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>)) - .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>)) + .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) @@ -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); } diff --git a/tasks/transform_conformance/babel.snap.md b/tasks/transform_conformance/babel.snap.md index 25d758330..b9c111048 100644 --- a/tasks/transform_conformance/babel.snap.md +++ b/tasks/transform_conformance/babel.snap.md @@ -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 | @@ -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 | diff --git a/tasks/transform_conformance/oxc.snap.md b/tasks/transform_conformance/oxc.snap.md index 3be840580..e21aa2e36 100644 --- a/tasks/transform_conformance/oxc.snap.md +++ b/tasks/transform_conformance/oxc.snap.md @@ -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 |