hir/
lib.rs

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
30/// Hir session
31///
32/// This struct represents a hir compilation session
33/// It holds an arena with all the nodes of the tree, and
34/// a map to find nodes by their [`HirId`]
35pub 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    /// Gets a node by their [`HirId`].
47    /// This functions assumes that the id is valid, and exists
48    /// in the tree.
49    ///
50    /// # Panics
51    /// - If the id dosn't match a node in the graph
52    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}