mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +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",
|
||||
]
|
||||
|
||||
[[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",
|
||||
|
|
|
|||
|
|
@ -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" }
|
||||
|
|
|
|||
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 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<T> NonEmptyStack<T> {
|
|||
|
||||
/// 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<T> NonEmptyStack<T> {
|
|||
offset + 1
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
/// Get capacity.
|
||||
#[inline]
|
||||
pub fn capacity(&self) -> usize {
|
||||
|
|
@ -30,11 +30,16 @@ pub struct SparseStack<T> {
|
|||
values: Stack<T>,
|
||||
}
|
||||
|
||||
impl<T> Default for SparseStack<T> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> SparseStack<T> {
|
||||
/// Maximum capacity for entries (either `Some` or `None`).
|
||||
///
|
||||
/// Effectively unlimited on 64-bit systems.
|
||||
#[expect(dead_code)]
|
||||
pub const MAX_TOTAL_CAPACITY: usize = NonEmptyStack::<bool>::MAX_CAPACITY;
|
||||
|
||||
/// Maximum capacity for filled entries (`Some`).
|
||||
|
|
@ -44,7 +49,6 @@ impl<T> SparseStack<T> {
|
|||
/// 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::<T>::MAX_CAPACITY;
|
||||
|
||||
/// Create new `SparseStack`.
|
||||
|
|
@ -70,7 +74,6 @@ impl<T> SparseStack<T> {
|
|||
/// * `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<T> SparseStack<T> {
|
|||
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<T> SparseStack<T> {
|
|||
///
|
||||
/// [`total_capacity`]: Self::total_capacity
|
||||
#[inline]
|
||||
#[expect(dead_code)]
|
||||
pub fn filled_capacity(&self) -> usize {
|
||||
self.values.capacity()
|
||||
}
|
||||
|
|
@ -36,6 +36,12 @@ pub struct Stack<T> {
|
|||
end: NonNull<T>,
|
||||
}
|
||||
|
||||
impl<T> Default for Stack<T> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> StackCapacity<T> for Stack<T> {}
|
||||
|
||||
impl<T> StackCommon<T> for Stack<T> {
|
||||
|
|
@ -117,7 +123,8 @@ impl<T> Stack<T> {
|
|||
/// # 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<T> Stack<T> {
|
|||
|
||||
/// 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<T> Stack<T> {
|
|||
|
||||
/// 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<T> Stack<T> {
|
|||
|
||||
/// 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<T> Stack<T> {
|
|||
|
||||
/// 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<T> Stack<T> {
|
|||
|
||||
/// Pop value from stack.
|
||||
#[inline]
|
||||
#[cfg_attr(not(test), expect(dead_code))]
|
||||
pub fn pop(&mut self) -> Option<T> {
|
||||
#[expect(clippy::if_not_else)]
|
||||
if !self.is_empty() {
|
||||
|
|
@ -278,8 +284,9 @@ impl<T> Stack<T> {
|
|||
|
||||
/// 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);
|
||||
|
|
@ -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"] }
|
||||
|
|
|
|||
|
|
@ -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<VariableDeclarator>`s, and adds a `var` statement
|
||||
/// to top of a statement block if another transform has requested that.
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ mod plugins;
|
|||
|
||||
mod helpers {
|
||||
pub mod bindings;
|
||||
pub mod stack;
|
||||
}
|
||||
|
||||
use std::path::Path;
|
||||
|
|
|
|||
Loading…
Reference in a new issue