mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
refactor(semantic)!: always create a scope for CatchClause (#5109)
Part of #5008. Make scope for `CatchClause` unconditional. i.e. always create a scope, even if there is no catch parameter.
This commit is contained in:
parent
dd3ad4d68e
commit
d304d6f973
7 changed files with 24 additions and 71 deletions
|
|
@ -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))]
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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>)
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 |
|
||||
|
|
|
|||
|
|
@ -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 |
|
||||
|
|
|
|||
Loading…
Reference in a new issue