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
|
//! 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)
})
}
/// 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
}
}
|