1use bumpalo::Bump;
2
3use crate::{
4 ast::{
5 AstString, Attribute, Block, BlockNode, Function, GenericType, GenericTypePack, Local,
6 LocalInit, Type, TypeKind, TypePack, TypePackKind,
7 },
8 location::Location,
9};
10
11#[derive(Debug, Default)]
12pub struct AstArena {
13 bump: Bump,
14}
15
16impl AstArena {
17 pub fn new() -> Self {
18 Self { bump: Bump::new() }
19 }
20
21 pub fn alloc<T>(&self, value: T) -> &mut T {
22 self.bump.alloc(value)
23 }
24
25 pub fn alloc_node<T>(&self, value: T) -> &T {
26 self.bump.alloc(value)
27 }
28
29 pub(crate) fn alloc_block<'ast>(&'ast self, value: BlockNode<'ast>) -> Block<'ast> {
30 self.alloc_block_node(value)
31 }
32
33 pub fn alloc_attribute<'ast>(&'ast self, value: Attribute<'ast>) -> &'ast Attribute<'ast> {
34 self.alloc_node(value)
35 }
36
37 pub fn alloc_function<'ast>(&'ast self, value: Function<'ast>) -> &'ast Function<'ast> {
38 self.alloc_node(value)
39 }
40
41 pub fn alloc_generic_type<'ast>(
42 &'ast self,
43 value: GenericType<'ast>,
44 ) -> &'ast GenericType<'ast> {
45 self.alloc_node(value)
46 }
47
48 pub fn alloc_generic_type_pack<'ast>(
49 &'ast self,
50 value: GenericTypePack<'ast>,
51 ) -> &'ast GenericTypePack<'ast> {
52 self.alloc_node(value)
53 }
54
55 pub fn alloc_local<'ast>(&'ast self, value: Local<'ast>) -> &'ast Local<'ast> {
56 self.alloc_node(value)
57 }
58
59 pub fn alloc_local_binding<'ast>(&'ast self, init: LocalInit<'ast>) -> &'ast Local<'ast> {
60 self.alloc_local(Local::new(init))
61 }
62
63 pub fn alloc_type<'ast>(&'ast self, location: Location, value: TypeKind<'ast>) -> Type<'ast> {
64 self.alloc_type_kind(location, value)
65 }
66
67 pub fn alloc_type_pack<'ast>(
68 &'ast self,
69 location: Location,
70 value: TypePackKind<'ast>,
71 ) -> TypePack<'ast> {
72 self.alloc_type_pack_kind(location, value)
73 }
74
75 pub fn alloc_slice_fill_iter<T, I>(&self, values: I) -> &[T]
76 where
77 I: IntoIterator<Item = T>,
78 I::IntoIter: ExactSizeIterator,
79 {
80 self.bump.alloc_slice_fill_iter(values)
81 }
82
83 pub fn alloc_slice_copy<T: Copy>(&self, values: &[T]) -> &[T] {
84 self.bump.alloc_slice_copy(values)
85 }
86
87 pub fn alloc_bytes(&self, bytes: &[u8]) -> &[u8] {
88 self.alloc_slice_copy(bytes)
89 }
90
91 pub fn alloc_ast_string<'ast>(&'ast self, bytes: &[u8]) -> AstString<'ast> {
92 AstString::from_arena_bytes(self.alloc_bytes(bytes))
93 }
94}