1e2d323a7c
This change is quite verbose, so a little bit of explaining: 1. To correctly format parse errors, errors must be able to return more than one annotated span (the parser returns a list of errors for each span). To accomplish this, the structure of how the `Diagnostic` struct which formats an error is constructed has changed to delegate the creation of the `SpanLabel` vector to the kind of error. 2. The rnix structures don't have human-readable output formats by default, so some verbose methods for formatting them in human-readable ways have been added in the errors module. We might want to move these out into a submodule. 3. In many cases, the errors returned by rnix are a bit strange - so while we format them with all information that is easily available they may look weird or not necessarily help users. Consider this CL only a first step in the right direction. Change-Id: Ie7dd74751af9e7ecb35d751f8b087aae5ae6e2e8 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6871 Reviewed-by: sterni <sternenseemann@systemli.org> Autosubmit: tazjin <tazjin@tvl.su> Tested-by: BuildkiteCI
63 lines
2 KiB
Rust
63 lines
2 KiB
Rust
//! 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
|
|
}
|
|
}
|