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:
overlookmotel 2024-08-23 08:30:27 +00:00
parent dd3ad4d68e
commit d304d6f973
7 changed files with 24 additions and 71 deletions

View file

@ -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))]

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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 |

View file

@ -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 |