1mod hir;
2pub mod hir_id;
3use std::cell::{Cell, RefCell};
4pub mod node_map;
5
6pub use hir_id::HirId;
7
8pub mod visitor;
9
10pub use hir::*;
11use hir_id::HirNode;
12use node_map::{HirNodeKind, NodeMap};
13
14mod _arena {
15 use crate::UseItem;
16
17 use super::{Expression, Type, item::Module};
18
19 ::arena::define_arenas!(
20 [visibility = pub]
21 expr : Expression<'ctx>,
22 types: Type<'ctx>,
23 modules: Module<'ctx>,
24 uses: UseItem<'ctx>,
25 );
26}
27
28use _arena::ArenaAllocable;
29
30pub struct Session<'hir> {
36 root: Cell<Option<&'hir Module<'hir>>>,
37 node_map: RefCell<NodeMap<'hir>>,
38 arena: _arena::Arena<'hir>,
39}
40
41impl<'hir> Session<'hir> {
42 pub fn set_root(&self, m: &'hir Module<'hir>) { self.root.set(Some(m)); }
43
44 pub fn get_root(&self) -> &'hir Module<'hir> { self.root.get().unwrap() }
45
46 pub fn get_node(&self, id: &HirId) -> HirNodeKind<'hir> {
53 self.node_map
54 .borrow()
55 .get_by_id(id)
56 .unwrap_or_else(|| unreachable!())
57 }
58}
59
60impl Default for Session<'_> {
61 fn default() -> Self {
62 Self {
63 arena: _arena::Arena::new(),
64 root: Cell::new(None),
65 node_map: RefCell::default(),
66 }
67 }
68}
69
70impl<'hir> Session<'hir> {
71
72 #[inline]
73 pub fn alloc_annon<T, C>(&self, val: T) -> &'hir T
74 where
75 T: ArenaAllocable<'hir, C>
76 {
77 val.alloc_into(&self.arena)
78 }
79
80 pub fn alloc<T, C>(&self, val: T) -> &'hir T
81 where
82 T: ArenaAllocable<'hir, C> + HirNode<'hir>,
83 {
84 let elem = val.alloc_into(&self.arena);
85 let mut map = self.node_map.borrow_mut();
86 elem.set_hir_id(map.get_next_id());
87 map.define(elem.get_hir_id(), elem.get_hir_node_kind());
88 elem
89 }
90 pub fn alloc_iter<T, I, C>(&self, val: I) -> &'hir [T]
91 where
92 T: ArenaAllocable<'hir, C> + HirNode<'hir>,
93 I: IntoIterator<
94 Item = T,
95 IntoIter: ExactSizeIterator
96 >,
97 {
98 let items = T::alloc_iter(val, &self.arena);
99 let mut node_map = self.node_map.borrow_mut();
100 for elem in &mut *items {
101 elem.set_hir_id(node_map.get_next_id());
102 }
103 for elem in &*items {
104 node_map.define(elem.get_hir_id(), elem.get_hir_node_kind());
105 }
106 items
107 }
108
109 #[inline]
110 pub fn alloc_iter_annon<T, I, C>(&self, val: I) -> &'hir [T]
111 where
112 T: ArenaAllocable<'hir, C>,
113 I: IntoIterator<
114 Item = T,
115 IntoIter: ExactSizeIterator
116 >,
117 {
118 T::alloc_iter(val, &self.arena)
119 }
120}