feat(semantic): add ScopeFlags::CatchClause for use in CatchClause (#4205)

This commit is contained in:
Dunqing 2024-07-12 03:47:07 +00:00
parent 126b66c4f8
commit 92ee77487f
6 changed files with 12 additions and 23 deletions

View file

@ -1300,7 +1300,7 @@ pub struct TryStatement<'a> {
}
#[visited_node]
#[scope]
#[scope(flags(ScopeFlags::CatchClause))]
#[derive(Debug)]
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
#[cfg_attr(feature = "serialize", serde(tag = "type"))]

View file

@ -3692,7 +3692,7 @@ 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);
visitor.enter_scope(ScopeFlags::empty(), &it.scope_id);
visitor.enter_scope(ScopeFlags::CatchClause, &it.scope_id);
if let Some(param) = &it.param {
visitor.visit_catch_parameter(param);
}

View file

@ -3897,7 +3897,7 @@ 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);
visitor.enter_scope(ScopeFlags::empty(), &it.scope_id);
visitor.enter_scope(ScopeFlags::CatchClause, &it.scope_id);
if let Some(param) = &mut it.param {
visitor.visit_catch_parameter(param);
}

View file

@ -440,13 +440,10 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
self.current_scope_id = self.scope.add_scope(parent_scope_id, flags);
scope_id.set(Some(self.current_scope_id));
// TODO: replace node-based check with scope-based
if !flags.is_top()
&& matches!(self.nodes.parent_kind(self.current_node_id), Some(AstKind::CatchClause(_)))
{
// Clone the `CatchClause` bindings and add them to the current scope.
// to make it easier to check redeclare errors.
if let Some(parent_scope_id) = parent_scope_id {
if let Some(parent_scope_id) = parent_scope_id {
if self.scope.get_flags(parent_scope_id).is_catch_clause() {
// Clone the `CatchClause` bindings and add them to the current scope.
// to make it easier to check redeclare errors.
let bindings = self.scope.get_bindings(parent_scope_id).clone();
self.scope.get_bindings_mut(self.current_scope_id).extend(bindings);
}

View file

@ -23,6 +23,7 @@ bitflags! {
const Constructor = 1 << 6;
const GetAccessor = 1 << 7;
const SetAccessor = 1 << 8;
const CatchClause = 1 << 9;
const Var = Self::Top.bits() | Self::Function.bits() | Self::ClassStaticBlock.bits() | Self::TsModuleBlock.bits();
const Modifiers = Self::Constructor.bits() | Self::GetAccessor.bits() | Self::SetAccessor.bits();
}
@ -81,4 +82,8 @@ impl ScopeFlags {
pub fn is_set_or_get_accessor(&self) -> bool {
self.intersects(Self::SetAccessor | Self::GetAccessor)
}
pub fn is_catch_clause(&self) -> bool {
self.contains(Self::CatchClause)
}
}

View file

@ -9482,19 +9482,6 @@ Expect to Parse: "conformance/types/typeRelationships/typeAndMemberIdentity/obje
22 │
╰────
× Identifier `e` has already been declared
╭─[compiler/redeclareParameterInCatchBlock.ts:27:9]
26 │
27 │ } catch(e) {
· ┬
· ╰── `e` has already been declared here
28 │ function test() {
29 │ let e;
· ┬
· ╰── It can not be redeclared here
30 │ }
╰────
× Unexpected flag a in regular expression literal
╭─[compiler/regularExpressionScanning.ts:3:12]
2 │ // Flags