From c3c3447ac3f07bdf6cfc455bdca98ddec6e0f303 Mon Sep 17 00:00:00 2001 From: Boshen <1430279+Boshen@users.noreply.github.com> Date: Tue, 1 Oct 2024 10:02:45 +0000 Subject: [PATCH] feat(data_structures): add `oxc_data_structures` crate; add stack (#6206) --- Cargo.lock | 9 ++++++- Cargo.toml | 1 + crates/oxc_data_structures/Cargo.toml | 24 +++++++++++++++++ crates/oxc_data_structures/src/lib.rs | 1 + .../src}/stack/capacity.rs | 0 .../src}/stack/common.rs | 0 .../src}/stack/mod.rs | 0 .../src}/stack/non_empty.rs | 13 ++++++--- .../src}/stack/non_null.rs | 0 .../src}/stack/sparse.rs | 16 +++++++---- .../src}/stack/standard.rs | 27 ++++++++++++------- crates/oxc_transformer/Cargo.toml | 13 +++++---- .../src/common/var_declarations.rs | 3 ++- .../src/es2015/arrow_functions.rs | 4 ++- crates/oxc_transformer/src/lib.rs | 1 - 15 files changed, 83 insertions(+), 29 deletions(-) create mode 100644 crates/oxc_data_structures/Cargo.toml create mode 100644 crates/oxc_data_structures/src/lib.rs rename crates/{oxc_transformer/src/helpers => oxc_data_structures/src}/stack/capacity.rs (100%) rename crates/{oxc_transformer/src/helpers => oxc_data_structures/src}/stack/common.rs (100%) rename crates/{oxc_transformer/src/helpers => oxc_data_structures/src}/stack/mod.rs (100%) rename crates/{oxc_transformer/src/helpers => oxc_data_structures/src}/stack/non_empty.rs (98%) rename crates/{oxc_transformer/src/helpers => oxc_data_structures/src}/stack/non_null.rs (100%) rename crates/{oxc_transformer/src/helpers => oxc_data_structures/src}/stack/sparse.rs (97%) rename crates/{oxc_transformer/src/helpers => oxc_data_structures/src}/stack/standard.rs (98%) diff --git a/Cargo.lock b/Cargo.lock index 4e831176de0d1..315e52fa1ed4d 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 65cd9f4947305..574c679fafdfc 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 0000000000000..dd9db0f194c75 --- /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 0000000000000..c93897d0acb76 --- /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 ef7403ae9634d..c18724abe3907 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 943b0e0a093bf..15ba747dc65a8 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 c722773c5d312..b6042f47cb916 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 fb86c6971aed5..8d74b5098d8c5 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 65566a40ff141..24f5d9ab16b5c 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 cc5b1a383920d..186a34387a374 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 d88cae8c48c9c..83a259b2950da 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;