From b28c54a2c239acd73f2eea80fda9ee3960d2c046 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 13 Aug 2020 16:28:27 +0200 Subject: Rename ra_hir_def -> hir_def --- crates/hir_def/src/trace.rs | 51 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 crates/hir_def/src/trace.rs (limited to 'crates/hir_def/src/trace.rs') diff --git a/crates/hir_def/src/trace.rs b/crates/hir_def/src/trace.rs new file mode 100644 index 000000000..fd64e7018 --- /dev/null +++ b/crates/hir_def/src/trace.rs @@ -0,0 +1,51 @@ +//! Trace is a pretty niche data structure which is used when lowering a CST +//! into HIR. +//! +//! Lowering process calculates two bits of information: +//! * the lowered syntax itself +//! * a mapping between lowered syntax and original syntax +//! +//! Due to the way salsa works, the mapping is usually hot lava, as it contains +//! absolute offsets. The `Trace` structure (inspired, at least in name, by +//! Kotlin's `BindingTrace`) allows use the same code to compute both +//! projections. +use arena::{map::ArenaMap, Arena, Idx, RawId}; + +pub(crate) struct Trace { + arena: Option>, + map: Option, V>>, + len: u32, +} + +impl Trace { + pub(crate) fn new_for_arena() -> Trace { + Trace { arena: Some(Arena::default()), map: None, len: 0 } + } + + pub(crate) fn new_for_map() -> Trace { + Trace { arena: None, map: Some(ArenaMap::default()), len: 0 } + } + + pub(crate) fn alloc(&mut self, value: impl FnOnce() -> V, data: impl FnOnce() -> T) -> Idx { + let id = if let Some(arena) = &mut self.arena { + arena.alloc(data()) + } else { + let id = Idx::::from_raw(RawId::from(self.len)); + self.len += 1; + id + }; + + if let Some(map) = &mut self.map { + map.insert(id, value()); + } + id + } + + pub(crate) fn into_arena(mut self) -> Arena { + self.arena.take().unwrap() + } + + pub(crate) fn into_map(mut self) -> ArenaMap, V> { + self.map.take().unwrap() + } +} -- cgit v1.2.3