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

perf(semantic)!: remove SymbolTable::spans field #4473

Closed
Closed
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
perf(semantic)!: remove SymbolTable::spans field
  • Loading branch information
overlookmotel committed Jul 26, 2024
commit 16c2ec410ed7fd538782b7aa9e5817977aae0867
5 changes: 3 additions & 2 deletions crates/oxc_linter/src/rules/eslint/no_class_assign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,14 @@ declare_oxc_lint!(

impl Rule for NoClassAssign {
fn run_on_symbol(&self, symbol_id: SymbolId, ctx: &LintContext<'_>) {
let symbol_table = ctx.semantic().symbols();
let semantic = &**ctx.semantic();
let symbol_table = semantic.symbols();
if symbol_table.get_flag(symbol_id).is_class() {
for reference in symbol_table.get_resolved_references(symbol_id) {
if reference.is_write() {
ctx.diagnostic(no_class_assign_diagnostic(
symbol_table.get_name(symbol_id),
symbol_table.get_span(symbol_id),
semantic.symbol_span(symbol_id),
ctx.semantic().reference_span(reference),
));
}
Expand Down
5 changes: 3 additions & 2 deletions crates/oxc_linter/src/rules/eslint/no_const_assign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,14 @@ declare_oxc_lint!(

impl Rule for NoConstAssign {
fn run_on_symbol(&self, symbol_id: SymbolId, ctx: &LintContext<'_>) {
let symbol_table = ctx.semantic().symbols();
let semantic = &**ctx.semantic();
let symbol_table = semantic.symbols();
if symbol_table.get_flag(symbol_id).is_const_variable() {
for reference in symbol_table.get_resolved_references(symbol_id) {
if reference.is_write() {
ctx.diagnostic(no_const_assign_diagnostic(
symbol_table.get_name(symbol_id),
symbol_table.get_span(symbol_id),
semantic.symbol_span(symbol_id),
ctx.semantic().reference_span(reference),
));
}
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_linter/src/rules/eslint/no_label_var.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ impl Rule for NoLabelVar {
if let Some(symbol_id) =
ctx.scopes().find_binding(node.scope_id(), &labeled_stmt.label.name)
{
let decl_span = ctx.symbols().get_span(symbol_id);
let decl_span = ctx.semantic().symbol_span(symbol_id);
let label_decl = labeled_stmt.span.start;
ctx.diagnostic(no_label_var_diagnostic(
&labeled_stmt.label.name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ impl Rule for NoShadowRestrictedNames {
}
}

let span = ctx.symbols().get_span(symbol_id);
let span = ctx.semantic().symbol_span(symbol_id);
ctx.diagnostic(no_shadow_restricted_names_diagnostic(name, span));

for &span in ctx.symbols().get_redeclarations(symbol_id) {
Expand Down
3 changes: 1 addition & 2 deletions crates/oxc_linter/src/rules/import/namespace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,7 @@ impl Rule for Namespace {
return;
}

let Some(symbol_id) =
ctx.semantic().symbols().get_symbol_id_from_span(entry.local_name.span())
let Some(symbol_id) = ctx.semantic().get_symbol_id_from_span(entry.local_name.span())
else {
return;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ impl Rule for NoNamedAsDefaultMember {

if !remote_module_record_ref.exported_bindings.is_empty() {
has_members_map.insert(
ctx.symbols().get_symbol_id_from_span(import_entry.local_name.span()).unwrap(),
ctx.semantic().get_symbol_id_from_span(import_entry.local_name.span()).unwrap(),
(remote_module_record_ref, import_entry.module_request.name().clone()),
);
}
Expand Down
3 changes: 1 addition & 2 deletions crates/oxc_semantic/src/binder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,7 @@ impl<'a> Binder<'a> for CatchParameter<'a> {
// 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);
let symbol_id = builder.declare_shadow_symbol(&ident.name, current_scope_id, includes);
ident.symbol_id.set(Some(symbol_id));
} else {
self.pattern.bound_names(&mut |ident| {
Expand Down
16 changes: 5 additions & 11 deletions crates/oxc_semantic/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use oxc_cfg::{
IterationInstructionKind, ReturnInstructionKind,
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_span::{Atom, CompactStr, SourceType, Span};
use oxc_span::{Atom, CompactStr, GetSpan, SourceType, Span};
use oxc_syntax::{module_record::ModuleRecord, operator::AssignmentOperator};
use rustc_hash::FxHashMap;

Expand Down Expand Up @@ -343,13 +343,8 @@ impl<'a> SemanticBuilder<'a> {

let includes = includes | self.current_symbol_flags;
let name = CompactStr::new(name);
let symbol_id = self.symbols.create_symbol(
span,
name.clone(),
includes,
scope_id,
self.current_node_id,
);
let symbol_id =
self.symbols.create_symbol(name.clone(), includes, scope_id, self.current_node_id);
self.scope.add_binding(scope_id, name, symbol_id);
symbol_id
}
Expand All @@ -376,7 +371,8 @@ impl<'a> SemanticBuilder<'a> {
self.hoisting_variables.get(&scope_id).and_then(|symbols| symbols.get(name).copied())
})?;
if report_error && self.symbols.get_flag(symbol_id).intersects(excludes) {
let symbol_span = self.symbols.get_span(symbol_id);
let declaration_node_id = self.symbols.get_declaration(symbol_id);
let symbol_span = self.nodes.kind(declaration_node_id).span();
self.error(redeclaration(name, symbol_span, span));
}
Some(symbol_id)
Expand All @@ -401,14 +397,12 @@ impl<'a> SemanticBuilder<'a> {
pub fn declare_shadow_symbol(
&mut self,
name: &str,
span: Span,
scope_id: ScopeId,
includes: SymbolFlags,
) -> SymbolId {
let includes = includes | self.current_symbol_flags;
let name = CompactStr::new(name);
let symbol_id = self.symbols.create_symbol(
span,
name.clone(),
includes,
self.current_scope_id,
Expand Down
19 changes: 19 additions & 0 deletions crates/oxc_semantic/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ impl<'a> Semantic<'a> {
self.nodes.get_node(self.symbols.get_declaration(symbol_id))
}

pub fn symbol_span(&self, symbol_id: SymbolId) -> Span {
self.symbol_declaration(symbol_id).kind().span()
}

pub fn is_reference_to_global_variable(&self, ident: &IdentifierReference) -> bool {
self.scopes().root_unresolved_references().contains_key(ident.name.as_str())
}
Expand All @@ -153,6 +157,21 @@ impl<'a> Semantic<'a> {
let node = self.nodes.get_node(reference.node_id());
node.kind().span()
}

pub fn get_symbol_id_from_span(&self, span: Span) -> Option<SymbolId> {
self.symbols.declarations.iter_enumerated().find_map(|(symbol_id, &node_id)| {
let inner_span = self.nodes.kind(node_id).span();
if inner_span == span {
Some(symbol_id)
} else {
None
}
})
}

pub fn get_scope_id_from_span(&self, span: Span) -> Option<ScopeId> {
self.get_symbol_id_from_span(span).map(|symbol_id| self.symbols.get_scope_id(symbol_id))
}
}

#[cfg(test)]
Expand Down
24 changes: 3 additions & 21 deletions crates/oxc_semantic/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ export type IndexVec<I, T> = Array<T>;
#[derive(Debug, Default)]
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify), serde(rename_all = "camelCase"))]
pub struct SymbolTable {
pub spans: IndexVec<SymbolId, Span>,
pub names: IndexVec<SymbolId, CompactStr>,
pub flags: IndexVec<SymbolId, SymbolFlags>,
pub scope_ids: IndexVec<SymbolId, ScopeId>,
Expand All @@ -49,25 +48,19 @@ pub struct SymbolTable {

impl SymbolTable {
pub fn len(&self) -> usize {
self.spans.len()
self.names.len()
}

pub fn is_empty(&self) -> bool {
self.len() == 0
}

pub fn iter(&self) -> impl Iterator<Item = SymbolId> + '_ {
self.spans.iter_enumerated().map(|(symbol_id, _)| symbol_id)
self.flags.iter_enumerated().map(|(symbol_id, _)| symbol_id)
}

pub fn iter_rev(&self) -> impl Iterator<Item = SymbolId> + '_ {
self.spans.iter_enumerated().rev().map(|(symbol_id, _)| symbol_id)
}

pub fn get_symbol_id_from_span(&self, span: Span) -> Option<SymbolId> {
self.spans
.iter_enumerated()
.find_map(|(symbol, &inner_span)| if inner_span == span { Some(symbol) } else { None })
self.flags.iter_enumerated().rev().map(|(symbol_id, _)| symbol_id)
}

pub fn get_symbol_id_from_name(&self, name: &str) -> Option<SymbolId> {
Expand All @@ -80,10 +73,6 @@ impl SymbolTable {
})
}

pub fn get_span(&self, symbol_id: SymbolId) -> Span {
self.spans[symbol_id]
}

pub fn get_name(&self, symbol_id: SymbolId) -> &str {
&self.names[symbol_id]
}
Expand Down Expand Up @@ -113,10 +102,6 @@ impl SymbolTable {
self.scope_ids[symbol_id]
}

pub fn get_scope_id_from_span(&self, span: Span) -> Option<ScopeId> {
self.get_symbol_id_from_span(span).map(|symbol_id| self.get_scope_id(symbol_id))
}

pub fn get_scope_id_from_name(&self, name: &str) -> Option<ScopeId> {
self.get_symbol_id_from_name(name).map(|symbol_id| self.get_scope_id(symbol_id))
}
Expand All @@ -127,13 +112,11 @@ impl SymbolTable {

pub fn create_symbol(
&mut self,
span: Span,
name: CompactStr,
flag: SymbolFlags,
scope_id: ScopeId,
node_id: AstNodeId,
) -> SymbolId {
self.spans.push(span);
self.names.push(name);
self.flags.push(flag);
self.scope_ids.push(scope_id);
Expand Down Expand Up @@ -210,7 +193,6 @@ impl SymbolTable {
}

pub fn reserve(&mut self, additional_symbols: usize, additional_references: usize) {
self.spans.reserve(additional_symbols);
self.names.reserve(additional_symbols);
self.flags.reserve(additional_symbols);
self.scope_ids.reserve(additional_symbols);
Expand Down
1 change: 0 additions & 1 deletion crates/oxc_transformer/src/typescript/enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ impl<'a> TypeScriptEnum<'a> {
let enum_name = decl.id.name.clone();
let func_scope_id = decl.scope_id.get().unwrap();
let param_symbol_id = ctx.symbols_mut().create_symbol(
decl.id.span,
enum_name.to_compact_str(),
SymbolFlags::FunctionScopedVariable,
func_scope_id,
Expand Down
5 changes: 2 additions & 3 deletions crates/oxc_traverse/src/context/scoping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use oxc_ast::{
visit::{walk, Visit},
};
use oxc_semantic::{AstNodeId, Reference, ScopeTree, SymbolTable};
use oxc_span::{Atom, CompactStr, Span, SPAN};
use oxc_span::{Atom, CompactStr, Span};
use oxc_syntax::{
reference::{ReferenceFlag, ReferenceId},
scope::{ScopeFlags, ScopeId},
Expand Down Expand Up @@ -245,8 +245,7 @@ impl TraverseScoping {
let name = CompactStr::new(&self.find_uid_name(name));

// Add binding to scope
let symbol_id =
self.symbols.create_symbol(SPAN, name.clone(), flags, scope_id, AstNodeId::DUMMY);
let symbol_id = self.symbols.create_symbol(name.clone(), flags, scope_id, AstNodeId::DUMMY);
self.scopes.add_binding(scope_id, name, symbol_id);
symbol_id
}
Expand Down
Loading