diff --git a/Cargo.lock b/Cargo.lock index 4e831176d..315e52fa1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1569,6 +1569,13 @@ dependencies = [ "walkdir", ] +[[package]] +name = "oxc_data_structures" +version = "0.30.5" +dependencies = [ + "assert-unchecked", +] + [[package]] name = "oxc_diagnostics" version = "0.30.5" @@ -1985,7 +1992,6 @@ dependencies = [ name = "oxc_transformer" version = "0.30.5" dependencies = [ - "assert-unchecked", "base64", "cow-utils", "dashmap 6.0.1", @@ -1994,6 +2000,7 @@ dependencies = [ "oxc_allocator", "oxc_ast", "oxc_codegen", + "oxc_data_structures", "oxc_diagnostics", "oxc_parser", "oxc_regular_expression", diff --git a/Cargo.toml b/Cargo.toml index 65cd9f494..574c679fa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -82,6 +82,7 @@ oxc_ast = { version = "0.30.5", path = "crates/oxc_ast" } oxc_ast_macros = { version = "0.30.5", path = "crates/oxc_ast_macros" } oxc_cfg = { version = "0.30.5", path = "crates/oxc_cfg" } oxc_codegen = { version = "0.30.5", path = "crates/oxc_codegen" } +oxc_data_structures = { version = "0.30.5", path = "crates/oxc_data_structures" } oxc_diagnostics = { version = "0.30.5", path = "crates/oxc_diagnostics" } oxc_index = { version = "0.30.5", path = "crates/oxc_index" } oxc_isolated_declarations = { version = "0.30.5", path = "crates/oxc_isolated_declarations" } diff --git a/crates/oxc_data_structures/Cargo.toml b/crates/oxc_data_structures/Cargo.toml new file mode 100644 index 000000000..dd9db0f19 --- /dev/null +++ b/crates/oxc_data_structures/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "oxc_data_structures" +version = "0.30.5" +authors.workspace = true +categories.workspace = true +edition.workspace = true +homepage.workspace = true +include = ["/src"] +keywords.workspace = true +license.workspace = true +publish = true +repository.workspace = true +rust-version.workspace = true +description.workspace = true + +[lints] +workspace = true + +[lib] +test = true +doctest = false + +[dependencies] +assert-unchecked = { workspace = true } diff --git a/crates/oxc_data_structures/src/lib.rs b/crates/oxc_data_structures/src/lib.rs new file mode 100644 index 000000000..c93897d0a --- /dev/null +++ b/crates/oxc_data_structures/src/lib.rs @@ -0,0 +1 @@ +pub mod stack; diff --git a/crates/oxc_transformer/src/helpers/stack/capacity.rs b/crates/oxc_data_structures/src/stack/capacity.rs similarity index 100% rename from crates/oxc_transformer/src/helpers/stack/capacity.rs rename to crates/oxc_data_structures/src/stack/capacity.rs diff --git a/crates/oxc_transformer/src/helpers/stack/common.rs b/crates/oxc_data_structures/src/stack/common.rs similarity index 100% rename from crates/oxc_transformer/src/helpers/stack/common.rs rename to crates/oxc_data_structures/src/stack/common.rs diff --git a/crates/oxc_transformer/src/helpers/stack/mod.rs b/crates/oxc_data_structures/src/stack/mod.rs similarity index 100% rename from crates/oxc_transformer/src/helpers/stack/mod.rs rename to crates/oxc_data_structures/src/stack/mod.rs diff --git a/crates/oxc_transformer/src/helpers/stack/non_empty.rs b/crates/oxc_data_structures/src/stack/non_empty.rs similarity index 98% rename from crates/oxc_transformer/src/helpers/stack/non_empty.rs rename to crates/oxc_data_structures/src/stack/non_empty.rs index ef7403ae9..c18724abe 100644 --- a/crates/oxc_transformer/src/helpers/stack/non_empty.rs +++ b/crates/oxc_data_structures/src/stack/non_empty.rs @@ -132,7 +132,8 @@ impl NonEmptyStack { /// # Panics /// Panics if `T` is a zero-sized type. /// - /// # SAFETY + /// # Safety + /// /// * `capacity` must not be 0. /// * `capacity` must not exceed [`Self::MAX_CAPACITY`]. #[inline] @@ -253,8 +254,9 @@ impl NonEmptyStack { /// Pop value from stack, without checking that stack isn't empty. /// - /// # SAFETY - /// Stack must have at least 2 entries, so that after pop, it still has at least 1. + /// # Safety + /// + /// * Stack must have at least 2 entries, so that after pop, it still has at least 1. #[inline] pub unsafe fn pop_unchecked(&mut self) -> T { debug_assert!(self.cursor > self.start); @@ -284,6 +286,11 @@ impl NonEmptyStack { offset + 1 } + #[inline] + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + /// Get capacity. #[inline] pub fn capacity(&self) -> usize { diff --git a/crates/oxc_transformer/src/helpers/stack/non_null.rs b/crates/oxc_data_structures/src/stack/non_null.rs similarity index 100% rename from crates/oxc_transformer/src/helpers/stack/non_null.rs rename to crates/oxc_data_structures/src/stack/non_null.rs diff --git a/crates/oxc_transformer/src/helpers/stack/sparse.rs b/crates/oxc_data_structures/src/stack/sparse.rs similarity index 97% rename from crates/oxc_transformer/src/helpers/stack/sparse.rs rename to crates/oxc_data_structures/src/stack/sparse.rs index 943b0e0a0..15ba747dc 100644 --- a/crates/oxc_transformer/src/helpers/stack/sparse.rs +++ b/crates/oxc_data_structures/src/stack/sparse.rs @@ -30,11 +30,16 @@ pub struct SparseStack { values: Stack, } +impl Default for SparseStack { + fn default() -> Self { + Self::new() + } +} + impl SparseStack { /// Maximum capacity for entries (either `Some` or `None`). /// /// Effectively unlimited on 64-bit systems. - #[expect(dead_code)] pub const MAX_TOTAL_CAPACITY: usize = NonEmptyStack::::MAX_CAPACITY; /// Maximum capacity for filled entries (`Some`). @@ -44,7 +49,6 @@ impl SparseStack { /// Both are effectively unlimited on 64-bit systems. /// /// [`MAX_TOTAL_CAPACITY`]: Self::MAX_TOTAL_CAPACITY - #[expect(dead_code)] pub const MAX_FILLED_CAPACITY: usize = Stack::::MAX_CAPACITY; /// Create new `SparseStack`. @@ -70,7 +74,6 @@ impl SparseStack { /// * `total_capacity` must not exceed `Self::MAX_TOTAL_CAPACITY`. /// * `filled_capacity` must not exceed `Self::MAX_FILLED_CAPACITY`. #[inline] - #[expect(dead_code)] pub fn with_capacity(total_capacity: usize, filled_capacity: usize) -> Self { Self { has_values: NonEmptyStack::with_capacity(total_capacity, false), @@ -187,11 +190,15 @@ impl SparseStack { self.has_values.len() } + #[inline] + pub fn is_empty(&self) -> bool { + self.has_values.len() == 0 + } + /// Get capacity of stack for any entries (either `Some` or `None`). /// /// Capacity is always at least 1. Stack is never empty. #[inline] - #[expect(dead_code)] pub fn total_capacity(&self) -> usize { self.has_values.capacity() } @@ -202,7 +209,6 @@ impl SparseStack { /// /// [`total_capacity`]: Self::total_capacity #[inline] - #[expect(dead_code)] pub fn filled_capacity(&self) -> usize { self.values.capacity() } diff --git a/crates/oxc_transformer/src/helpers/stack/standard.rs b/crates/oxc_data_structures/src/stack/standard.rs similarity index 98% rename from crates/oxc_transformer/src/helpers/stack/standard.rs rename to crates/oxc_data_structures/src/stack/standard.rs index c722773c5..b6042f47c 100644 --- a/crates/oxc_transformer/src/helpers/stack/standard.rs +++ b/crates/oxc_data_structures/src/stack/standard.rs @@ -36,6 +36,12 @@ pub struct Stack { end: NonNull, } +impl Default for Stack { + fn default() -> Self { + Self::new() + } +} + impl StackCapacity for Stack {} impl StackCommon for Stack { @@ -117,7 +123,8 @@ impl Stack { /// # Panics /// Panics if `T` is a zero-sized type. /// - /// # SAFETY + /// # Safety + /// /// * `capacity` must not be 0. /// * `capacity` must not exceed [`Self::MAX_CAPACITY`]. #[inline] @@ -154,7 +161,6 @@ impl Stack { /// Get reference to last value on stack. #[inline] - #[cfg_attr(not(test), expect(dead_code))] pub fn last(&self) -> Option<&T> { #[expect(clippy::if_not_else)] if !self.is_empty() { @@ -167,8 +173,9 @@ impl Stack { /// Get reference to last value on stack, without checking stack isn't empty. /// - /// # SAFETY - /// Stack must not be empty. + /// # Safety + /// + /// * Stack must not be empty. #[inline] pub unsafe fn last_unchecked(&self) -> &T { debug_assert!(self.end > self.start); @@ -182,7 +189,6 @@ impl Stack { /// Get mutable reference to last value on stack. #[inline] - #[cfg_attr(not(test), expect(dead_code))] pub fn last_mut(&mut self) -> Option<&mut T> { #[expect(clippy::if_not_else)] if !self.is_empty() { @@ -195,8 +201,9 @@ impl Stack { /// Get mutable reference to last value on stack, without checking stack isn't empty. /// - /// # SAFETY - /// Stack must not be empty. + /// # Safety + /// + /// * Stack must not be empty. #[inline] pub unsafe fn last_mut_unchecked(&mut self) -> &mut T { debug_assert!(self.end > self.start); @@ -265,7 +272,6 @@ impl Stack { /// Pop value from stack. #[inline] - #[cfg_attr(not(test), expect(dead_code))] pub fn pop(&mut self) -> Option { #[expect(clippy::if_not_else)] if !self.is_empty() { @@ -278,8 +284,9 @@ impl Stack { /// Pop value from stack, without checking that stack isn't empty. /// - /// # SAFETY - /// Stack must not be empty. + /// # Safety + /// + /// * Stack must not be empty. #[inline] pub unsafe fn pop_unchecked(&mut self) -> T { debug_assert!(self.end > self.start); diff --git a/crates/oxc_transformer/Cargo.toml b/crates/oxc_transformer/Cargo.toml index fb86c6971..8d74b5098 100644 --- a/crates/oxc_transformer/Cargo.toml +++ b/crates/oxc_transformer/Cargo.toml @@ -21,8 +21,14 @@ test = true doctest = false [dependencies] +base64 = { workspace = true } +cow-utils = { workspace = true } +dashmap = { workspace = true } +indexmap = { workspace = true } +oxc-browserslist = { workspace = true } oxc_allocator = { workspace = true } oxc_ast = { workspace = true } +oxc_data_structures = { workspace = true } oxc_diagnostics = { workspace = true } oxc_parser = { workspace = true } oxc_regular_expression = { workspace = true } @@ -30,13 +36,6 @@ oxc_semantic = { workspace = true } oxc_span = { workspace = true } oxc_syntax = { workspace = true, features = ["to_js_string"] } oxc_traverse = { workspace = true } - -assert-unchecked = { workspace = true } -base64 = { workspace = true } -cow-utils = { workspace = true } -dashmap = { workspace = true } -indexmap = { workspace = true } -oxc-browserslist = { workspace = true } ropey = { workspace = true } rustc-hash = { workspace = true } serde = { workspace = true, features = ["derive"] } diff --git a/crates/oxc_transformer/src/common/var_declarations.rs b/crates/oxc_transformer/src/common/var_declarations.rs index 65566a40f..24f5d9ab1 100644 --- a/crates/oxc_transformer/src/common/var_declarations.rs +++ b/crates/oxc_transformer/src/common/var_declarations.rs @@ -16,11 +16,12 @@ use std::cell::RefCell; use oxc_allocator::Vec; use oxc_ast::{ast::*, NONE}; +use oxc_data_structures::stack::SparseStack; use oxc_span::SPAN; use oxc_syntax::symbol::SymbolId; use oxc_traverse::{Traverse, TraverseCtx}; -use crate::{helpers::stack::SparseStack, TransformCtx}; +use crate::TransformCtx; /// Transform that maintains the stack of `Vec`s, and adds a `var` statement /// to top of a statement block if another transform has requested that. diff --git a/crates/oxc_transformer/src/es2015/arrow_functions.rs b/crates/oxc_transformer/src/es2015/arrow_functions.rs index cc5b1a383..186a34387 100644 --- a/crates/oxc_transformer/src/es2015/arrow_functions.rs +++ b/crates/oxc_transformer/src/es2015/arrow_functions.rs @@ -123,15 +123,17 @@ use oxc_allocator::Vec; use oxc_ast::{ast::*, NONE}; +use oxc_data_structures::stack::SparseStack; use oxc_span::SPAN; use oxc_syntax::{ scope::{ScopeFlags, ScopeId}, symbol::SymbolFlags, }; use oxc_traverse::{Ancestor, Traverse, TraverseCtx}; + use serde::Deserialize; -use crate::helpers::{bindings::BoundIdentifier, stack::SparseStack}; +use crate::helpers::bindings::BoundIdentifier; #[derive(Debug, Default, Clone, Deserialize)] pub struct ArrowFunctionsOptions { diff --git a/crates/oxc_transformer/src/lib.rs b/crates/oxc_transformer/src/lib.rs index d88cae8c4..83a259b29 100644 --- a/crates/oxc_transformer/src/lib.rs +++ b/crates/oxc_transformer/src/lib.rs @@ -31,7 +31,6 @@ mod plugins; mod helpers { pub mod bindings; - pub mod stack; } use std::path::Path;