diff options
author | Vincent Ambo <mail@tazj.in> | 2022-10-04T14·05+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-10-05T10·29+0000 |
commit | 3530404a4a1cc363d87e559ac24780aa318adb19 (patch) | |
tree | 71458cd9fdc83efd71c3c0187e2381a5434fc7f7 /tvix/eval/src/source.rs | |
parent | 2ff764ceb700a1ef18fb532fbbc1ff937ed63f8a (diff) |
refactor(tvix/eval): introduce source::SourceCode type r/5035
This type hides away the lower-level handling of most codemap data structures, especially to library consumers (see corresponding changes in tvixbolt). This will help with implement `import` by giving us central control over how the codemap works. Change-Id: Ifcea36776879725871b30c518aeb96ab5fda035a Reviewed-on: https://cl.tvl.fyi/c/depot/+/6855 Tested-by: BuildkiteCI Reviewed-by: wpcarro <wpcarro@gmail.com>
Diffstat (limited to 'tvix/eval/src/source.rs')
-rw-r--r-- | tvix/eval/src/source.rs | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/tvix/eval/src/source.rs b/tvix/eval/src/source.rs new file mode 100644 index 000000000000..010449528206 --- /dev/null +++ b/tvix/eval/src/source.rs @@ -0,0 +1,57 @@ +//! This module contains utilities for dealing with the codemap that +//! needs to be carried across different compiler instantiations in an +//! evaluation. +//! +//! The data type `SourceCode` should be carried through all relevant +//! places instead of copying the codemap structures directly. + +use std::{ + cell::{Ref, RefCell, RefMut}, + rc::Rc, + sync::Arc, +}; + +use codemap::{CodeMap, Span}; + +/// Tracks all source code in a Tvix evaluation for accurate error +/// reporting. +#[derive(Clone)] +pub struct SourceCode(Rc<RefCell<CodeMap>>); + +impl SourceCode { + /// Create a new SourceCode instance. + pub fn new() -> Self { + SourceCode(Rc::new(RefCell::new(CodeMap::new()))) + } + + /// Access a read-only reference to the codemap. + pub fn codemap(&self) -> Ref<CodeMap> { + self.0.borrow() + } + + /// Access a writable reference to the codemap. + fn codemap_mut(&self) -> RefMut<CodeMap> { + self.0.borrow_mut() + } + + /// Add a file to the codemap. The returned Arc is managed by the + /// codemap internally and can be used like a normal reference. + pub fn add_file(&self, name: String, code: String) -> Arc<codemap::File> { + self.codemap_mut().add_file(name, code) + } + + /// Retrieve the line number of the given span. If it spans + /// multiple lines, the first line will be returned. + pub fn get_line(&self, span: Span) -> usize { + // lines are 0-indexed in the codemap, but users probably want + // real line numbers + self.codemap().look_up_span(span).begin.line + 1 + } + + /// Returns the literal source slice of the given span. + pub fn source_slice(&self, span: Span) -> Ref<str> { + Ref::map(self.codemap(), |c| { + c.find_file(span.low()).source_slice(span) + }) + } +} |