mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
feat(data_structures): add oxc_data_structures crate; add stack (#6206)
This commit is contained in:
parent
788e444c1f
commit
c3c3447ac3
15 changed files with 83 additions and 29 deletions
9
Cargo.lock
generated
9
Cargo.lock
generated
|
|
@ -1569,6 +1569,13 @@ dependencies = [
|
||||||
"walkdir",
|
"walkdir",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "oxc_data_structures"
|
||||||
|
version = "0.30.5"
|
||||||
|
dependencies = [
|
||||||
|
"assert-unchecked",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxc_diagnostics"
|
name = "oxc_diagnostics"
|
||||||
version = "0.30.5"
|
version = "0.30.5"
|
||||||
|
|
@ -1985,7 +1992,6 @@ dependencies = [
|
||||||
name = "oxc_transformer"
|
name = "oxc_transformer"
|
||||||
version = "0.30.5"
|
version = "0.30.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"assert-unchecked",
|
|
||||||
"base64",
|
"base64",
|
||||||
"cow-utils",
|
"cow-utils",
|
||||||
"dashmap 6.0.1",
|
"dashmap 6.0.1",
|
||||||
|
|
@ -1994,6 +2000,7 @@ dependencies = [
|
||||||
"oxc_allocator",
|
"oxc_allocator",
|
||||||
"oxc_ast",
|
"oxc_ast",
|
||||||
"oxc_codegen",
|
"oxc_codegen",
|
||||||
|
"oxc_data_structures",
|
||||||
"oxc_diagnostics",
|
"oxc_diagnostics",
|
||||||
"oxc_parser",
|
"oxc_parser",
|
||||||
"oxc_regular_expression",
|
"oxc_regular_expression",
|
||||||
|
|
|
||||||
|
|
@ -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_ast_macros = { version = "0.30.5", path = "crates/oxc_ast_macros" }
|
||||||
oxc_cfg = { version = "0.30.5", path = "crates/oxc_cfg" }
|
oxc_cfg = { version = "0.30.5", path = "crates/oxc_cfg" }
|
||||||
oxc_codegen = { version = "0.30.5", path = "crates/oxc_codegen" }
|
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_diagnostics = { version = "0.30.5", path = "crates/oxc_diagnostics" }
|
||||||
oxc_index = { version = "0.30.5", path = "crates/oxc_index" }
|
oxc_index = { version = "0.30.5", path = "crates/oxc_index" }
|
||||||
oxc_isolated_declarations = { version = "0.30.5", path = "crates/oxc_isolated_declarations" }
|
oxc_isolated_declarations = { version = "0.30.5", path = "crates/oxc_isolated_declarations" }
|
||||||
|
|
|
||||||
24
crates/oxc_data_structures/Cargo.toml
Normal file
24
crates/oxc_data_structures/Cargo.toml
Normal file
|
|
@ -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 }
|
||||||
1
crates/oxc_data_structures/src/lib.rs
Normal file
1
crates/oxc_data_structures/src/lib.rs
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
pub mod stack;
|
||||||
|
|
@ -132,7 +132,8 @@ impl<T> NonEmptyStack<T> {
|
||||||
/// # Panics
|
/// # Panics
|
||||||
/// Panics if `T` is a zero-sized type.
|
/// Panics if `T` is a zero-sized type.
|
||||||
///
|
///
|
||||||
/// # SAFETY
|
/// # Safety
|
||||||
|
///
|
||||||
/// * `capacity` must not be 0.
|
/// * `capacity` must not be 0.
|
||||||
/// * `capacity` must not exceed [`Self::MAX_CAPACITY`].
|
/// * `capacity` must not exceed [`Self::MAX_CAPACITY`].
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
@ -253,8 +254,9 @@ impl<T> NonEmptyStack<T> {
|
||||||
|
|
||||||
/// Pop value from stack, without checking that stack isn't empty.
|
/// Pop value from stack, without checking that stack isn't empty.
|
||||||
///
|
///
|
||||||
/// # SAFETY
|
/// # Safety
|
||||||
/// Stack must have at least 2 entries, so that after pop, it still has at least 1.
|
///
|
||||||
|
/// * Stack must have at least 2 entries, so that after pop, it still has at least 1.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn pop_unchecked(&mut self) -> T {
|
pub unsafe fn pop_unchecked(&mut self) -> T {
|
||||||
debug_assert!(self.cursor > self.start);
|
debug_assert!(self.cursor > self.start);
|
||||||
|
|
@ -284,6 +286,11 @@ impl<T> NonEmptyStack<T> {
|
||||||
offset + 1
|
offset + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.len() == 0
|
||||||
|
}
|
||||||
|
|
||||||
/// Get capacity.
|
/// Get capacity.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn capacity(&self) -> usize {
|
pub fn capacity(&self) -> usize {
|
||||||
|
|
@ -30,11 +30,16 @@ pub struct SparseStack<T> {
|
||||||
values: Stack<T>,
|
values: Stack<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> Default for SparseStack<T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> SparseStack<T> {
|
impl<T> SparseStack<T> {
|
||||||
/// Maximum capacity for entries (either `Some` or `None`).
|
/// Maximum capacity for entries (either `Some` or `None`).
|
||||||
///
|
///
|
||||||
/// Effectively unlimited on 64-bit systems.
|
/// Effectively unlimited on 64-bit systems.
|
||||||
#[expect(dead_code)]
|
|
||||||
pub const MAX_TOTAL_CAPACITY: usize = NonEmptyStack::<bool>::MAX_CAPACITY;
|
pub const MAX_TOTAL_CAPACITY: usize = NonEmptyStack::<bool>::MAX_CAPACITY;
|
||||||
|
|
||||||
/// Maximum capacity for filled entries (`Some`).
|
/// Maximum capacity for filled entries (`Some`).
|
||||||
|
|
@ -44,7 +49,6 @@ impl<T> SparseStack<T> {
|
||||||
/// Both are effectively unlimited on 64-bit systems.
|
/// Both are effectively unlimited on 64-bit systems.
|
||||||
///
|
///
|
||||||
/// [`MAX_TOTAL_CAPACITY`]: Self::MAX_TOTAL_CAPACITY
|
/// [`MAX_TOTAL_CAPACITY`]: Self::MAX_TOTAL_CAPACITY
|
||||||
#[expect(dead_code)]
|
|
||||||
pub const MAX_FILLED_CAPACITY: usize = Stack::<T>::MAX_CAPACITY;
|
pub const MAX_FILLED_CAPACITY: usize = Stack::<T>::MAX_CAPACITY;
|
||||||
|
|
||||||
/// Create new `SparseStack`.
|
/// Create new `SparseStack`.
|
||||||
|
|
@ -70,7 +74,6 @@ impl<T> SparseStack<T> {
|
||||||
/// * `total_capacity` must not exceed `Self::MAX_TOTAL_CAPACITY`.
|
/// * `total_capacity` must not exceed `Self::MAX_TOTAL_CAPACITY`.
|
||||||
/// * `filled_capacity` must not exceed `Self::MAX_FILLED_CAPACITY`.
|
/// * `filled_capacity` must not exceed `Self::MAX_FILLED_CAPACITY`.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[expect(dead_code)]
|
|
||||||
pub fn with_capacity(total_capacity: usize, filled_capacity: usize) -> Self {
|
pub fn with_capacity(total_capacity: usize, filled_capacity: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
has_values: NonEmptyStack::with_capacity(total_capacity, false),
|
has_values: NonEmptyStack::with_capacity(total_capacity, false),
|
||||||
|
|
@ -187,11 +190,15 @@ impl<T> SparseStack<T> {
|
||||||
self.has_values.len()
|
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`).
|
/// Get capacity of stack for any entries (either `Some` or `None`).
|
||||||
///
|
///
|
||||||
/// Capacity is always at least 1. Stack is never empty.
|
/// Capacity is always at least 1. Stack is never empty.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[expect(dead_code)]
|
|
||||||
pub fn total_capacity(&self) -> usize {
|
pub fn total_capacity(&self) -> usize {
|
||||||
self.has_values.capacity()
|
self.has_values.capacity()
|
||||||
}
|
}
|
||||||
|
|
@ -202,7 +209,6 @@ impl<T> SparseStack<T> {
|
||||||
///
|
///
|
||||||
/// [`total_capacity`]: Self::total_capacity
|
/// [`total_capacity`]: Self::total_capacity
|
||||||
#[inline]
|
#[inline]
|
||||||
#[expect(dead_code)]
|
|
||||||
pub fn filled_capacity(&self) -> usize {
|
pub fn filled_capacity(&self) -> usize {
|
||||||
self.values.capacity()
|
self.values.capacity()
|
||||||
}
|
}
|
||||||
|
|
@ -36,6 +36,12 @@ pub struct Stack<T> {
|
||||||
end: NonNull<T>,
|
end: NonNull<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> Default for Stack<T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> StackCapacity<T> for Stack<T> {}
|
impl<T> StackCapacity<T> for Stack<T> {}
|
||||||
|
|
||||||
impl<T> StackCommon<T> for Stack<T> {
|
impl<T> StackCommon<T> for Stack<T> {
|
||||||
|
|
@ -117,7 +123,8 @@ impl<T> Stack<T> {
|
||||||
/// # Panics
|
/// # Panics
|
||||||
/// Panics if `T` is a zero-sized type.
|
/// Panics if `T` is a zero-sized type.
|
||||||
///
|
///
|
||||||
/// # SAFETY
|
/// # Safety
|
||||||
|
///
|
||||||
/// * `capacity` must not be 0.
|
/// * `capacity` must not be 0.
|
||||||
/// * `capacity` must not exceed [`Self::MAX_CAPACITY`].
|
/// * `capacity` must not exceed [`Self::MAX_CAPACITY`].
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
@ -154,7 +161,6 @@ impl<T> Stack<T> {
|
||||||
|
|
||||||
/// Get reference to last value on stack.
|
/// Get reference to last value on stack.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg_attr(not(test), expect(dead_code))]
|
|
||||||
pub fn last(&self) -> Option<&T> {
|
pub fn last(&self) -> Option<&T> {
|
||||||
#[expect(clippy::if_not_else)]
|
#[expect(clippy::if_not_else)]
|
||||||
if !self.is_empty() {
|
if !self.is_empty() {
|
||||||
|
|
@ -167,8 +173,9 @@ impl<T> Stack<T> {
|
||||||
|
|
||||||
/// Get reference to last value on stack, without checking stack isn't empty.
|
/// Get reference to last value on stack, without checking stack isn't empty.
|
||||||
///
|
///
|
||||||
/// # SAFETY
|
/// # Safety
|
||||||
/// Stack must not be empty.
|
///
|
||||||
|
/// * Stack must not be empty.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn last_unchecked(&self) -> &T {
|
pub unsafe fn last_unchecked(&self) -> &T {
|
||||||
debug_assert!(self.end > self.start);
|
debug_assert!(self.end > self.start);
|
||||||
|
|
@ -182,7 +189,6 @@ impl<T> Stack<T> {
|
||||||
|
|
||||||
/// Get mutable reference to last value on stack.
|
/// Get mutable reference to last value on stack.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg_attr(not(test), expect(dead_code))]
|
|
||||||
pub fn last_mut(&mut self) -> Option<&mut T> {
|
pub fn last_mut(&mut self) -> Option<&mut T> {
|
||||||
#[expect(clippy::if_not_else)]
|
#[expect(clippy::if_not_else)]
|
||||||
if !self.is_empty() {
|
if !self.is_empty() {
|
||||||
|
|
@ -195,8 +201,9 @@ impl<T> Stack<T> {
|
||||||
|
|
||||||
/// Get mutable reference to last value on stack, without checking stack isn't empty.
|
/// Get mutable reference to last value on stack, without checking stack isn't empty.
|
||||||
///
|
///
|
||||||
/// # SAFETY
|
/// # Safety
|
||||||
/// Stack must not be empty.
|
///
|
||||||
|
/// * Stack must not be empty.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn last_mut_unchecked(&mut self) -> &mut T {
|
pub unsafe fn last_mut_unchecked(&mut self) -> &mut T {
|
||||||
debug_assert!(self.end > self.start);
|
debug_assert!(self.end > self.start);
|
||||||
|
|
@ -265,7 +272,6 @@ impl<T> Stack<T> {
|
||||||
|
|
||||||
/// Pop value from stack.
|
/// Pop value from stack.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg_attr(not(test), expect(dead_code))]
|
|
||||||
pub fn pop(&mut self) -> Option<T> {
|
pub fn pop(&mut self) -> Option<T> {
|
||||||
#[expect(clippy::if_not_else)]
|
#[expect(clippy::if_not_else)]
|
||||||
if !self.is_empty() {
|
if !self.is_empty() {
|
||||||
|
|
@ -278,8 +284,9 @@ impl<T> Stack<T> {
|
||||||
|
|
||||||
/// Pop value from stack, without checking that stack isn't empty.
|
/// Pop value from stack, without checking that stack isn't empty.
|
||||||
///
|
///
|
||||||
/// # SAFETY
|
/// # Safety
|
||||||
/// Stack must not be empty.
|
///
|
||||||
|
/// * Stack must not be empty.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn pop_unchecked(&mut self) -> T {
|
pub unsafe fn pop_unchecked(&mut self) -> T {
|
||||||
debug_assert!(self.end > self.start);
|
debug_assert!(self.end > self.start);
|
||||||
|
|
@ -21,8 +21,14 @@ test = true
|
||||||
doctest = false
|
doctest = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
base64 = { workspace = true }
|
||||||
|
cow-utils = { workspace = true }
|
||||||
|
dashmap = { workspace = true }
|
||||||
|
indexmap = { workspace = true }
|
||||||
|
oxc-browserslist = { workspace = true }
|
||||||
oxc_allocator = { workspace = true }
|
oxc_allocator = { workspace = true }
|
||||||
oxc_ast = { workspace = true }
|
oxc_ast = { workspace = true }
|
||||||
|
oxc_data_structures = { workspace = true }
|
||||||
oxc_diagnostics = { workspace = true }
|
oxc_diagnostics = { workspace = true }
|
||||||
oxc_parser = { workspace = true }
|
oxc_parser = { workspace = true }
|
||||||
oxc_regular_expression = { workspace = true }
|
oxc_regular_expression = { workspace = true }
|
||||||
|
|
@ -30,13 +36,6 @@ oxc_semantic = { workspace = true }
|
||||||
oxc_span = { workspace = true }
|
oxc_span = { workspace = true }
|
||||||
oxc_syntax = { workspace = true, features = ["to_js_string"] }
|
oxc_syntax = { workspace = true, features = ["to_js_string"] }
|
||||||
oxc_traverse = { workspace = true }
|
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 }
|
ropey = { workspace = true }
|
||||||
rustc-hash = { workspace = true }
|
rustc-hash = { workspace = true }
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,12 @@ use std::cell::RefCell;
|
||||||
|
|
||||||
use oxc_allocator::Vec;
|
use oxc_allocator::Vec;
|
||||||
use oxc_ast::{ast::*, NONE};
|
use oxc_ast::{ast::*, NONE};
|
||||||
|
use oxc_data_structures::stack::SparseStack;
|
||||||
use oxc_span::SPAN;
|
use oxc_span::SPAN;
|
||||||
use oxc_syntax::symbol::SymbolId;
|
use oxc_syntax::symbol::SymbolId;
|
||||||
use oxc_traverse::{Traverse, TraverseCtx};
|
use oxc_traverse::{Traverse, TraverseCtx};
|
||||||
|
|
||||||
use crate::{helpers::stack::SparseStack, TransformCtx};
|
use crate::TransformCtx;
|
||||||
|
|
||||||
/// Transform that maintains the stack of `Vec<VariableDeclarator>`s, and adds a `var` statement
|
/// Transform that maintains the stack of `Vec<VariableDeclarator>`s, and adds a `var` statement
|
||||||
/// to top of a statement block if another transform has requested that.
|
/// to top of a statement block if another transform has requested that.
|
||||||
|
|
|
||||||
|
|
@ -123,15 +123,17 @@
|
||||||
|
|
||||||
use oxc_allocator::Vec;
|
use oxc_allocator::Vec;
|
||||||
use oxc_ast::{ast::*, NONE};
|
use oxc_ast::{ast::*, NONE};
|
||||||
|
use oxc_data_structures::stack::SparseStack;
|
||||||
use oxc_span::SPAN;
|
use oxc_span::SPAN;
|
||||||
use oxc_syntax::{
|
use oxc_syntax::{
|
||||||
scope::{ScopeFlags, ScopeId},
|
scope::{ScopeFlags, ScopeId},
|
||||||
symbol::SymbolFlags,
|
symbol::SymbolFlags,
|
||||||
};
|
};
|
||||||
use oxc_traverse::{Ancestor, Traverse, TraverseCtx};
|
use oxc_traverse::{Ancestor, Traverse, TraverseCtx};
|
||||||
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::helpers::{bindings::BoundIdentifier, stack::SparseStack};
|
use crate::helpers::bindings::BoundIdentifier;
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Deserialize)]
|
#[derive(Debug, Default, Clone, Deserialize)]
|
||||||
pub struct ArrowFunctionsOptions {
|
pub struct ArrowFunctionsOptions {
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@ mod plugins;
|
||||||
|
|
||||||
mod helpers {
|
mod helpers {
|
||||||
pub mod bindings;
|
pub mod bindings;
|
||||||
pub mod stack;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue