use oxc_syntax::node::{NodeFlags, NodeId};
use super::{Ancestry, AncestryStack, AstNodes};
pub struct AstNodeStore<'a> {
node_count: u32,
pub current_node_id: NodeId,
pub current_node_flags: NodeFlags,
pub kind: AstNodeStoreKind<'a>,
}
pub enum AstNodeStoreKind<'a> {
Full(AstNodes<'a>),
Ancestry(AncestryStack<'a>),
}
impl Default for AstNodeStore<'_> {
fn default() -> Self {
Self {
node_count: 0,
current_node_id: NodeId::new(0),
current_node_flags: NodeFlags::empty(),
kind: AstNodeStoreKind::Ancestry(AncestryStack::default()),
}
}
}
impl<'a> AstNodeStore<'a> {
pub fn set_build_nodes(&mut self, yes: bool) {
self.kind = if yes {
AstNodeStoreKind::Full(AstNodes::default())
} else {
AstNodeStoreKind::Ancestry(AncestryStack::default())
};
}
#[cfg(debug_assertions)]
#[inline]
pub fn node_count(&self) -> u32 {
self.node_count
}
#[inline]
pub fn alloc_node_id(&mut self) -> NodeId {
let node_id = NodeId::new(self.node_count as usize);
self.node_count += 1;
node_id
}
#[inline]
pub fn reserve(&mut self, additional: usize) {
if let AstNodeStoreKind::Full(nodes) = &mut self.kind {
nodes.reserve(additional);
}
}
#[inline]
pub fn ancestry(&self) -> Ancestry<'a, '_> {
match &self.kind {
AstNodeStoreKind::Full(nodes) => {
Ancestry::Nodes { nodes, current_node_id: self.current_node_id }
}
AstNodeStoreKind::Ancestry(stack) => Ancestry::Stack(stack),
}
}
#[inline]
pub fn into_nodes(self) -> AstNodes<'a> {
match self.kind {
AstNodeStoreKind::Full(nodes) => nodes,
AstNodeStoreKind::Ancestry(_) => AstNodes::default(),
}
}
}