use crate::StoreRef;
use crate::base::Ref;
use crate::binding::Binding;
use crate::expr::Expr;
use crate::{ExprNodeIndex, flags};
pub use crate::ArrayBinding;
#[derive(Copy, Clone, bun_core::EnumTag)]
#[enum_tag(existing = super::binding::Tag)]
pub enum B {
BIdentifier(StoreRef<Identifier>),
BArray(StoreRef<Array>),
BObject(StoreRef<Object>),
BMissing(Missing),
}
impl Default for B {
fn default() -> Self {
B::BMissing(Missing {})
}
}
const _: () = assert!(core::mem::size_of::<B>() == 16);
const _: () = assert!(core::mem::size_of::<super::binding::Binding>() == 24);
const _: () = assert!(
core::mem::size_of::<Option<B>>() == core::mem::size_of::<B>(),
"B lost its niche — check for #[repr] or oversized inline payload"
);
pub struct Identifier {
pub r#ref: Ref,
}
pub struct Property {
pub flags: flags::PropertySet,
pub key: ExprNodeIndex,
pub value: Binding,
pub default_value: Option<Expr>,
}
pub struct Object {
pub properties: crate::StoreSlice<Property>,
pub is_single_line: bool,
}
pub struct Array {
pub items: crate::StoreSlice<ArrayBinding>,
pub has_spread: bool,
pub is_single_line: bool,
}
#[derive(Default, Copy, Clone)]
pub struct Missing {}
impl Array {
#[inline]
pub fn items(&self) -> &[ArrayBinding] {
self.items.slice()
}
#[inline]
pub fn items_mut(&mut self) -> &mut [ArrayBinding] {
self.items.slice_mut()
}
}
impl Object {
#[inline]
pub fn properties(&self) -> &[Property] {
self.properties.slice()
}
#[inline]
pub fn properties_mut(&mut self) -> &mut [Property] {
self.properties.slice_mut()
}
}
impl B {
pub fn write_to_hasher<H, S>(&self, hasher: &mut H, symbol_table: &mut S)
where
H: bun_core::Hasher + ?Sized,
S: crate::base::SymbolTable + ?Sized,
{
#[inline(always)]
fn raw<H: bun_core::Hasher + ?Sized, T: bun_core::NoUninit>(h: &mut H, v: T) {
h.update(bun_core::bytes_of(&v));
}
match self {
B::BIdentifier(id) => {
let ref_ = id.r#ref;
let original_name = ref_.get_symbol(symbol_table).original_name.slice();
raw(hasher, self.tag() as u8);
raw(hasher, original_name.len());
}
B::BArray(array) => {
raw(hasher, self.tag() as u8);
raw(hasher, array.has_spread);
raw(hasher, array.items().len());
for item in array.items().iter() {
raw(hasher, item.default_value.is_some());
if let Some(default) = &item.default_value {
default.data.write_to_hasher(hasher, symbol_table);
}
item.binding.data.write_to_hasher(hasher, symbol_table);
}
}
B::BObject(object) => {
raw(hasher, self.tag() as u8);
raw(hasher, object.properties().len());
for property in object.properties().iter() {
raw(hasher, property.default_value.is_some());
raw(hasher, property.flags.as_u8());
if let Some(default) = &property.default_value {
default.data.write_to_hasher(hasher, symbol_table);
}
property.key.data.write_to_hasher(hasher, symbol_table);
property.value.data.write_to_hasher(hasher, symbol_table);
}
}
B::BMissing(_) => {}
}
}
}
type _BindingTagHost = Binding;
pub use crate::g::Class;