1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
//! 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, Debug)]
pub struct SourceCode(Rc<RefCell<CodeMap>>);
impl SourceCode {
/// 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)
})
}
/// Returns the reference to the file structure that a given span
/// is in.
pub fn get_file(&self, span: Span) -> Arc<codemap::File> {
self.codemap().look_up_span(span).file
}
}
impl Default for SourceCode {
/// Create a new SourceCode instance.
fn default() -> Self {
Self(Rc::new(RefCell::new(CodeMap::new())))
}
}