diff --git a/Cargo.lock b/Cargo.lock index 3b32c9a4b2a443..ebc26410396b1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1929,10 +1929,8 @@ dependencies = [ "oxc_syntax", "phf", "rustc-hash", - "serde", + "self_cell", "serde_json", - "tsify", - "wasm-bindgen", ] [[package]] diff --git a/crates/oxc_semantic/Cargo.toml b/crates/oxc_semantic/Cargo.toml index facd8e08fcfa69..4ccd678d296d47 100644 --- a/crates/oxc_semantic/Cargo.toml +++ b/crates/oxc_semantic/Cargo.toml @@ -34,10 +34,7 @@ indexmap = { workspace = true } itertools = { workspace = true } phf = { workspace = true, features = ["macros"] } rustc-hash = { workspace = true } - -serde = { workspace = true, features = ["derive"], optional = true } -tsify = { workspace = true, optional = true } -wasm-bindgen = { workspace = true, optional = true } +self_cell = { workspace = true } [dev-dependencies] oxc_parser = { workspace = true } @@ -50,4 +47,4 @@ serde_json = { workspace = true } [features] default = [] -serialize = ["dep:serde", "dep:tsify", "dep:wasm-bindgen", "oxc_span/serialize", "oxc_syntax/serialize"] +serialize = ["oxc_span/serialize", "oxc_syntax/serialize"] diff --git a/crates/oxc_semantic/src/builder.rs b/crates/oxc_semantic/src/builder.rs index 0c236d678ce931..db622d3dbcb9e9 100644 --- a/crates/oxc_semantic/src/builder.rs +++ b/crates/oxc_semantic/src/builder.rs @@ -524,7 +524,7 @@ impl<'a> SemanticBuilder<'a> { *flags = ReferenceFlags::Type; } reference.set_symbol_id(symbol_id); - self.symbols.resolved_references[symbol_id].push(reference_id); + self.symbols.add_resolved_reference(symbol_id, reference_id); false }); diff --git a/crates/oxc_semantic/src/reference.rs b/crates/oxc_semantic/src/reference.rs index 81fe53c3e94cab..8bbfc3e2038fab 100644 --- a/crates/oxc_semantic/src/reference.rs +++ b/crates/oxc_semantic/src/reference.rs @@ -1,8 +1,3 @@ -#[cfg(feature = "serialize")] -use serde::Serialize; -#[cfg(feature = "serialize")] -use tsify::Tsify; - use oxc_syntax::{node::NodeId, reference::ReferenceFlags, symbol::SymbolId}; /// Describes where and how a Symbol is used in the AST. @@ -26,8 +21,6 @@ use oxc_syntax::{node::NodeId, reference::ReferenceFlags, symbol::SymbolId}; /// /// [`IdentifierReference`]: oxc_ast::ast::IdentifierReference #[derive(Debug, Clone)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))] pub struct Reference { /// The AST node making the reference. node_id: NodeId, diff --git a/crates/oxc_semantic/src/symbol.rs b/crates/oxc_semantic/src/symbol.rs index 01fdc45b714438..ba9e3bd5fa0d3b 100644 --- a/crates/oxc_semantic/src/symbol.rs +++ b/crates/oxc_semantic/src/symbol.rs @@ -1,12 +1,8 @@ use std::mem; -#[cfg(feature = "serialize")] -use serde::Serialize; -#[cfg(feature = "serialize")] -use tsify::Tsify; - +use oxc_allocator::{Allocator, Vec as ArenaVec}; use oxc_ast::ast::{Expression, IdentifierReference}; -use oxc_index::IndexVec; +use oxc_index::{Idx, IndexVec}; use oxc_span::{CompactStr, Span}; use oxc_syntax::{ node::NodeId, @@ -17,13 +13,6 @@ use oxc_syntax::{ use crate::reference::Reference; -#[cfg(feature = "serialize")] -#[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] -const TS_APPEND_CONTENT: &'static str = r#" -export type IndexVec = Array; -export type CompactStr = string; -"#; - /// Symbol Table /// /// `SoA` (Struct of Arrays) for memory efficiency. @@ -31,8 +20,6 @@ export type CompactStr = string; /// Most symbols won't have redeclarations, so instead of storing `Vec` directly in /// `redeclare_variables` (32 bytes per symbol), store `Option` (4 bytes). /// That ID indexes into `redeclarations` where the actual `Vec` is stored. -#[derive(Debug, Default)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify), serde(rename_all = "camelCase"))] pub struct SymbolTable { pub(crate) spans: IndexVec, pub(crate) names: IndexVec, @@ -40,12 +27,43 @@ pub struct SymbolTable { pub(crate) scope_ids: IndexVec, /// Pointer to the AST Node where this symbol is declared pub(crate) declarations: IndexVec, - pub resolved_references: IndexVec>, redeclarations: IndexVec>, - redeclaration_spans: IndexVec>, - pub references: IndexVec, + + inner: SymbolTableCell, +} + +impl Default for SymbolTable { + fn default() -> Self { + let allocator = Allocator::default(); + Self { + spans: IndexVec::new(), + names: IndexVec::new(), + flags: IndexVec::new(), + scope_ids: IndexVec::new(), + declarations: IndexVec::new(), + redeclarations: IndexVec::new(), + references: IndexVec::new(), + inner: SymbolTableCell::new(allocator, |allocator| SymbolTableInner { + resolved_references: ArenaVec::new_in(allocator), + redeclaration_spans: ArenaVec::new_in(allocator), + }), + } + } +} + +self_cell::self_cell!( + struct SymbolTableCell { + owner: Allocator, + #[covariant] + dependent: SymbolTableInner, + } +); + +struct SymbolTableInner<'a> { + resolved_references: ArenaVec<'a, ArenaVec<'a, ReferenceId>>, + redeclaration_spans: ArenaVec<'a, ArenaVec<'a, Span>>, } impl SymbolTable { @@ -65,8 +83,8 @@ impl SymbolTable { self.names.iter() } - pub fn resolved_references(&self) -> impl Iterator> + '_ { - self.resolved_references.iter() + pub fn resolved_references(&self) -> impl Iterator> + '_ { + self.inner.borrow_dependent().resolved_references.iter() } /// Iterate over all symbol IDs in this table. @@ -134,7 +152,7 @@ impl SymbolTable { #[inline] pub fn get_redeclarations(&self, symbol_id: SymbolId) -> &[Span] { if let Some(redeclaration_id) = self.redeclarations[symbol_id] { - &self.redeclaration_spans[redeclaration_id] + &self.inner.borrow_dependent().redeclaration_spans[redeclaration_id.index()] } else { static EMPTY: &[Span] = &[]; EMPTY @@ -184,16 +202,26 @@ impl SymbolTable { self.flags.push(flags); self.scope_ids.push(scope_id); self.declarations.push(node_id); - self.resolved_references.push(vec![]); + self.inner.with_dependent_mut(|allocator, inner| { + inner.resolved_references.push(ArenaVec::new_in(allocator)); + }); self.redeclarations.push(None) } pub fn add_redeclaration(&mut self, symbol_id: SymbolId, span: Span) { if let Some(redeclaration_id) = self.redeclarations[symbol_id] { - self.redeclaration_spans[redeclaration_id].push(span); + self.inner.with_dependent_mut(|_, inner| { + inner.redeclaration_spans[redeclaration_id.index()].push(span); + }); } else { - let redeclaration_id = self.redeclaration_spans.push(vec![span]); - self.redeclarations[symbol_id] = Some(redeclaration_id); + self.inner.with_dependent_mut(|allocator, inner| { + let mut v = ArenaVec::new_in(allocator); + v.push(span); + inner.redeclaration_spans.push(v); + let redeclaration_id = inner.redeclaration_spans.len(); + self.redeclarations[symbol_id] = + Some(RedeclarationId::from_usize(redeclaration_id)); + }); }; } @@ -228,8 +256,8 @@ impl SymbolTable { /// If you want direct access to a symbol's [`Reference`]s, use /// [`SymbolTable::get_resolved_references`]. #[inline] - pub fn get_resolved_reference_ids(&self, symbol_id: SymbolId) -> &Vec { - &self.resolved_references[symbol_id] + pub fn get_resolved_reference_ids(&self, symbol_id: SymbolId) -> &ArenaVec<'_, ReferenceId> { + &self.inner.borrow_dependent().resolved_references[symbol_id.index()] } /// Find [`Reference`]s resolved to a symbol. @@ -237,7 +265,7 @@ impl SymbolTable { &self, symbol_id: SymbolId, ) -> impl DoubleEndedIterator + '_ { - self.resolved_references[symbol_id] + self.get_resolved_reference_ids(symbol_id) .iter() .map(|&reference_id| &self.references[reference_id]) } @@ -256,8 +284,9 @@ impl SymbolTable { /// Add a reference to a symbol. pub fn add_resolved_reference(&mut self, symbol_id: SymbolId, reference_id: ReferenceId) { - let reference_ids = &mut self.resolved_references[symbol_id]; - reference_ids.push(reference_id); + self.inner.with_dependent_mut(|_allocator, inner| { + inner.resolved_references[symbol_id.index()].push(reference_id); + }); } /// Delete a reference to a symbol. @@ -265,9 +294,11 @@ impl SymbolTable { /// # Panics /// Panics if provided `reference_id` is not a resolved reference for `symbol_id`. pub fn delete_resolved_reference(&mut self, symbol_id: SymbolId, reference_id: ReferenceId) { - let reference_ids = &mut self.resolved_references[symbol_id]; - let index = reference_ids.iter().position(|&id| id == reference_id).unwrap(); - reference_ids.swap_remove(index); + self.inner.with_dependent_mut(|_allocator, inner| { + let reference_ids = &mut inner.resolved_references[symbol_id.index()]; + let index = reference_ids.iter().position(|&id| id == reference_id).unwrap(); + reference_ids.swap_remove(index); + }); } pub fn reserve(&mut self, additional_symbols: usize, additional_references: usize) { @@ -276,9 +307,9 @@ impl SymbolTable { self.flags.reserve(additional_symbols); self.scope_ids.reserve(additional_symbols); self.declarations.reserve(additional_symbols); - self.resolved_references.reserve(additional_symbols); - self.redeclarations.reserve(additional_symbols); - + self.inner.with_dependent_mut(|_allocator, inner| { + inner.resolved_references.reserve(additional_symbols); + }); self.references.reserve(additional_references); } } diff --git a/crates/oxc_wasm/src/lib.rs b/crates/oxc_wasm/src/lib.rs index 518f4fbe948a47..7bc756edae7506 100644 --- a/crates/oxc_wasm/src/lib.rs +++ b/crates/oxc_wasm/src/lib.rs @@ -234,13 +234,11 @@ impl Oxc { let (symbols, scopes) = semantic.into_symbol_table_and_scope_tree(); - if !source_type.is_typescript_definition() { - if run_options.scope.unwrap_or_default() { - self.scope_text = Self::get_scope_text(&program, &symbols, &scopes); - } - if run_options.symbol.unwrap_or_default() { - self.symbols = symbols.serialize(&self.serializer)?; - } + if !source_type.is_typescript_definition() && run_options.scope.unwrap_or_default() { + self.scope_text = Self::get_scope_text(&program, &symbols, &scopes); + // if run_options.symbol.unwrap_or_default() { + // self.symbols = symbols.serialize(&self.serializer)?; + // } } if run_options.transform.unwrap_or_default() { diff --git a/tasks/transform_checker/src/lib.rs b/tasks/transform_checker/src/lib.rs index 1d957f2ef838db..36422f4c38aa87 100644 --- a/tasks/transform_checker/src/lib.rs +++ b/tasks/transform_checker/src/lib.rs @@ -427,7 +427,12 @@ impl PostTransformChecker<'_, '_> { // Check resolved references match let reference_ids = self.get_pair(symbol_ids, |scoping, symbol_id| { - scoping.symbols.get_resolved_reference_ids(symbol_id).clone() + scoping + .symbols + .get_resolved_reference_ids(symbol_id) + .iter() + .copied() + .collect::>() }); if self.remap_reference_ids_sets(&reference_ids).is_mismatch() { self.errors.push_mismatch(