Skip to content

Commit

Permalink
refactor(semantic): move function/class-specific code into specific v…
Browse files Browse the repository at this point in the history
…isitors (#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.
  • Loading branch information
overlookmotel committed Jul 15, 2024
1 parent ee16668 commit 16698bc
Showing 1 changed file with 38 additions and 22 deletions.
60 changes: 38 additions & 22 deletions crates/oxc_semantic/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
Expand Down

0 comments on commit 16698bc

Please sign in to comment.