use bumpalo::Bump;
use crate::{
ast::{
AstString, Attribute, Block, BlockNode, Function, GenericType, GenericTypePack, Local,
LocalInit, Type, TypeKind, TypePack, TypePackKind,
},
location::Location,
};
#[derive(Debug, Default)]
pub struct AstArena {
bump: Bump,
}
impl AstArena {
pub fn new() -> Self {
Self { bump: Bump::new() }
}
pub fn alloc<T>(&self, value: T) -> &mut T {
self.bump.alloc(value)
}
pub fn alloc_node<T>(&self, value: T) -> &T {
self.bump.alloc(value)
}
pub(crate) fn alloc_block<'ast>(&'ast self, value: BlockNode<'ast>) -> Block<'ast> {
self.alloc_block_node(value)
}
pub fn alloc_attribute<'ast>(&'ast self, value: Attribute<'ast>) -> &'ast Attribute<'ast> {
self.alloc_node(value)
}
pub fn alloc_function<'ast>(&'ast self, value: Function<'ast>) -> &'ast Function<'ast> {
self.alloc_node(value)
}
pub fn alloc_generic_type<'ast>(
&'ast self,
value: GenericType<'ast>,
) -> &'ast GenericType<'ast> {
self.alloc_node(value)
}
pub fn alloc_generic_type_pack<'ast>(
&'ast self,
value: GenericTypePack<'ast>,
) -> &'ast GenericTypePack<'ast> {
self.alloc_node(value)
}
pub fn alloc_local<'ast>(&'ast self, value: Local<'ast>) -> &'ast Local<'ast> {
self.alloc_node(value)
}
pub fn alloc_local_binding<'ast>(&'ast self, init: LocalInit<'ast>) -> &'ast Local<'ast> {
self.alloc_local(Local::new(init))
}
pub fn alloc_type<'ast>(&'ast self, location: Location, value: TypeKind<'ast>) -> Type<'ast> {
self.alloc_type_kind(location, value)
}
pub fn alloc_type_pack<'ast>(
&'ast self,
location: Location,
value: TypePackKind<'ast>,
) -> TypePack<'ast> {
self.alloc_type_pack_kind(location, value)
}
pub fn alloc_slice_fill_iter<T, I>(&self, values: I) -> &[T]
where
I: IntoIterator<Item = T>,
I::IntoIter: ExactSizeIterator,
{
self.bump.alloc_slice_fill_iter(values)
}
pub fn alloc_slice_copy<T: Copy>(&self, values: &[T]) -> &[T] {
self.bump.alloc_slice_copy(values)
}
pub fn alloc_bytes(&self, bytes: &[u8]) -> &[u8] {
self.alloc_slice_copy(bytes)
}
pub fn alloc_ast_string<'ast>(&'ast self, bytes: &[u8]) -> AstString<'ast> {
AstString::from_arena_bytes(self.alloc_bytes(bytes))
}
}