Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(semantic): rename Counts in transform checker #5709

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions crates/oxc_semantic/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::{
binder::Binder,
checker,
class::ClassTableBuilder,
counter::Counter,
counter::Counts,
diagnostics::redeclaration,
jsdoc::JSDocBuilder,
label::UnusedLabels,
Expand Down Expand Up @@ -231,26 +231,26 @@ impl<'a> SemanticBuilder<'a> {
// Avoiding this growth produces up to 30% perf boost on our benchmarks.
// TODO: It would be even more efficient to calculate counts in parser to avoid
// this extra AST traversal.
let mut counter = Counter::default();
counter.visit_program(program);
self.nodes.reserve(counter.nodes_count);
self.scope.reserve(counter.scopes_count);
self.symbols.reserve(counter.symbols_count, counter.references_count);
let mut counts = Counts::default();
counts.visit_program(program);
self.nodes.reserve(counts.nodes);
self.scope.reserve(counts.scopes);
self.symbols.reserve(counts.symbols, counts.references);

// Visit AST to generate scopes tree etc
self.visit_program(program);

// Check that `Counter` got accurate counts
debug_assert_eq!(self.nodes.len(), counter.nodes_count);
debug_assert_eq!(self.scope.len(), counter.scopes_count);
debug_assert_eq!(self.symbols.references.len(), counter.references_count);
// `Counter` may overestimate number of symbols, because multiple `BindingIdentifier`s
// Check that estimated counts accurately
debug_assert_eq!(self.nodes.len(), counts.nodes);
debug_assert_eq!(self.scope.len(), counts.scopes);
debug_assert_eq!(self.symbols.references.len(), counts.references);
// `Counts` may overestimate number of symbols, because multiple `BindingIdentifier`s
// can result in only a single symbol.
// e.g. `var x; var x;` = 2 x `BindingIdentifier` but 1 x symbol.
// This is not a big problem - allocating a `Vec` with excess capacity is cheap.
// It's allocating with *not enough* capacity which is costly, as then the `Vec`
// will grow and reallocate.
debug_assert!(self.symbols.len() <= counter.symbols_count);
debug_assert!(self.symbols.len() <= counts.symbols);

// Checking syntax error on module record requires scope information from the previous AST pass
if self.check_syntax_error {
Expand Down
29 changes: 14 additions & 15 deletions crates/oxc_semantic/src/counter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,49 +11,48 @@ use oxc_ast::{
};
use oxc_syntax::scope::{ScopeFlags, ScopeId};

#[allow(clippy::struct_field_names)]
#[derive(Default, Debug)]
pub(crate) struct Counter {
pub nodes_count: usize,
pub scopes_count: usize,
pub symbols_count: usize,
pub references_count: usize,
pub(crate) struct Counts {
pub nodes: usize,
pub scopes: usize,
pub symbols: usize,
pub references: usize,
}

impl<'a> Visit<'a> for Counter {
impl<'a> Visit<'a> for Counts {
#[inline]
fn enter_node(&mut self, _: AstKind<'a>) {
self.nodes_count += 1;
self.nodes += 1;
}

#[inline]
fn enter_scope(&mut self, _: ScopeFlags, _: &Cell<Option<ScopeId>>) {
self.scopes_count += 1;
self.scopes += 1;
}

#[inline]
fn visit_binding_identifier(&mut self, _: &BindingIdentifier<'a>) {
self.nodes_count += 1;
self.symbols_count += 1;
self.nodes += 1;
self.symbols += 1;
}

#[inline]
fn visit_identifier_reference(&mut self, _: &IdentifierReference<'a>) {
self.nodes_count += 1;
self.references_count += 1;
self.nodes += 1;
self.references += 1;
}

#[inline]
fn visit_ts_enum_member_name(&mut self, it: &TSEnumMemberName<'a>) {
if !it.is_expression() {
self.symbols_count += 1;
self.symbols += 1;
}
walk_ts_enum_member_name(self, it);
}

#[inline]
fn visit_ts_module_declaration_name(&mut self, it: &TSModuleDeclarationName<'a>) {
self.symbols_count += 1;
self.symbols += 1;
walk_ts_module_declaration_name(self, it);
}
}