mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
refactor(semantic): move function/class-specific code into specific visitors (#4278)
Instead of calling `bind_function_or_class_expression` for every scope, and then branching on the AST node kind, insert the relevant code into the visitors for functions and classes. This reduces work on all other kinds of scopes e.g. block statements.
This commit is contained in:
parent
ee16668168
commit
16698bc191
1 changed files with 38 additions and 22 deletions
|
|
@ -430,24 +430,6 @@ impl<'a> SemanticBuilder<'a> {
|
|||
self.symbols.union_flag(symbol_id, SymbolFlags::Export);
|
||||
}
|
||||
}
|
||||
|
||||
fn bind_function_or_class_expression(&mut self) {
|
||||
match self.nodes.kind(self.current_node_id) {
|
||||
AstKind::Class(class) => {
|
||||
if class.is_expression() {
|
||||
// We need to bind class expression in the class scope,
|
||||
class.bind(self);
|
||||
}
|
||||
}
|
||||
AstKind::Function(func) => {
|
||||
if func.is_expression() {
|
||||
// We need to bind function expression in the function scope,
|
||||
func.bind(self);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Visit<'a> for SemanticBuilder<'a> {
|
||||
|
|
@ -484,10 +466,6 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
|
|||
if self.unresolved_references.len() <= self.current_scope_depth {
|
||||
self.unresolved_references.push(UnresolvedReferences::default());
|
||||
}
|
||||
|
||||
if !flags.is_top() {
|
||||
self.bind_function_or_class_expression();
|
||||
}
|
||||
}
|
||||
|
||||
fn leave_scope(&mut self) {
|
||||
|
|
@ -570,6 +548,39 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
|
|||
self.leave_node(kind);
|
||||
}
|
||||
|
||||
fn visit_class(&mut self, class: &Class<'a>) {
|
||||
let kind = AstKind::Class(self.alloc(class));
|
||||
self.enter_node(kind);
|
||||
|
||||
self.visit_decorators(&class.decorators);
|
||||
if let Some(id) = &class.id {
|
||||
self.visit_binding_identifier(id);
|
||||
}
|
||||
|
||||
self.enter_scope(ScopeFlags::StrictMode, &class.scope_id);
|
||||
if class.is_expression() {
|
||||
// We need to bind class expression in the class scope
|
||||
class.bind(self);
|
||||
}
|
||||
|
||||
if let Some(type_parameters) = &class.type_parameters {
|
||||
self.visit_ts_type_parameter_declaration(type_parameters);
|
||||
}
|
||||
if let Some(super_class) = &class.super_class {
|
||||
self.visit_class_heritage(super_class);
|
||||
}
|
||||
if let Some(super_type_parameters) = &class.super_type_parameters {
|
||||
self.visit_ts_type_parameter_instantiation(super_type_parameters);
|
||||
}
|
||||
if let Some(implements) = &class.implements {
|
||||
self.visit_ts_class_implementses(implements);
|
||||
}
|
||||
self.visit_class_body(&class.body);
|
||||
|
||||
self.leave_scope();
|
||||
self.leave_node(kind);
|
||||
}
|
||||
|
||||
fn visit_continue_statement(&mut self, stmt: &ContinueStatement<'a>) {
|
||||
let kind = AstKind::ContinueStatement(self.alloc(stmt));
|
||||
self.enter_node(kind);
|
||||
|
|
@ -1458,6 +1469,11 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
|
|||
&func.scope_id,
|
||||
);
|
||||
|
||||
if func.is_expression() {
|
||||
// We need to bind function expression in the function scope
|
||||
func.bind(self);
|
||||
}
|
||||
|
||||
if let Some(id) = &func.id {
|
||||
self.visit_binding_identifier(id);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue