mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
fix(semantic): correctly resolve identifiers inside catch parameter initializers (#3050)
closes #2499
This commit is contained in:
parent
92d709bf21
commit
84c43c8282
3 changed files with 36 additions and 25 deletions
|
|
@ -241,33 +241,27 @@ impl<'a> Binder for FormalParameter<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> Binder for CatchClause<'a> {
|
||||
impl<'a> Binder for CatchParameter<'a> {
|
||||
fn bind(&self, builder: &mut SemanticBuilder) {
|
||||
let current_scope_id = builder.current_scope_id;
|
||||
if let Some(param) = &self.param {
|
||||
// https://tc39.es/ecma262/#sec-variablestatements-in-catch-blocks
|
||||
// It is a Syntax Error if any element of the BoundNames of CatchParameter also occurs in the VarDeclaredNames of Block
|
||||
// unless CatchParameter is CatchParameter : BindingIdentifier
|
||||
if let BindingPatternKind::BindingIdentifier(ident) = ¶m.pattern.kind {
|
||||
let includes = SymbolFlags::FunctionScopedVariable | SymbolFlags::CatchVariable;
|
||||
let symbol_id = builder.declare_shadow_symbol(
|
||||
&ident.name,
|
||||
// https://tc39.es/ecma262/#sec-variablestatements-in-catch-blocks
|
||||
// It is a Syntax Error if any element of the BoundNames of CatchParameter also occurs in the VarDeclaredNames of Block
|
||||
// unless CatchParameter is CatchParameter : BindingIdentifier
|
||||
if let BindingPatternKind::BindingIdentifier(ident) = &self.pattern.kind {
|
||||
let includes = SymbolFlags::FunctionScopedVariable | SymbolFlags::CatchVariable;
|
||||
let symbol_id =
|
||||
builder.declare_shadow_symbol(&ident.name, ident.span, current_scope_id, includes);
|
||||
ident.symbol_id.set(Some(symbol_id));
|
||||
} else {
|
||||
self.pattern.bound_names(&mut |ident| {
|
||||
let symbol_id = builder.declare_symbol(
|
||||
ident.span,
|
||||
current_scope_id,
|
||||
includes,
|
||||
&ident.name,
|
||||
SymbolFlags::BlockScopedVariable | SymbolFlags::CatchVariable,
|
||||
SymbolFlags::BlockScopedVariableExcludes,
|
||||
);
|
||||
ident.symbol_id.set(Some(symbol_id));
|
||||
} else {
|
||||
param.pattern.bound_names(&mut |ident| {
|
||||
let symbol_id = builder.declare_symbol(
|
||||
ident.span,
|
||||
&ident.name,
|
||||
SymbolFlags::BlockScopedVariable | SymbolFlags::CatchVariable,
|
||||
SymbolFlags::BlockScopedVariableExcludes,
|
||||
);
|
||||
ident.symbol_id.set(Some(symbol_id));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1732,8 +1732,9 @@ impl<'a> SemanticBuilder<'a> {
|
|||
AstKind::FormalParameter(param) => {
|
||||
param.bind(self);
|
||||
}
|
||||
AstKind::CatchClause(clause) => {
|
||||
clause.bind(self);
|
||||
AstKind::CatchParameter(param) => {
|
||||
self.current_node_flags |= NodeFlags::Parameter;
|
||||
param.bind(self);
|
||||
}
|
||||
AstKind::TSModuleDeclaration(module_declaration) => {
|
||||
module_declaration.bind(self);
|
||||
|
|
@ -1832,7 +1833,7 @@ impl<'a> SemanticBuilder<'a> {
|
|||
AstKind::ArrowFunctionExpression(_) => {
|
||||
self.function_stack.pop();
|
||||
}
|
||||
AstKind::FormalParameters(_) => {
|
||||
AstKind::FormalParameters(_) | AstKind::CatchParameter(_) => {
|
||||
self.current_node_flags -= NodeFlags::Parameter;
|
||||
}
|
||||
AstKind::TSModuleBlock(_) => {
|
||||
|
|
|
|||
|
|
@ -121,3 +121,19 @@ fn test_function_parameters() {
|
|||
.has_number_of_references(1)
|
||||
.test();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_catch_clause_parameters() {
|
||||
SemanticTester::js(
|
||||
"
|
||||
const a = 0;
|
||||
try {
|
||||
} catch ({ [a]: b }) {
|
||||
const a = 1;
|
||||
}
|
||||
",
|
||||
)
|
||||
.has_root_symbol("a")
|
||||
.has_number_of_references(1)
|
||||
.test();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue