1
0

Refactor error reports

This commit is contained in:
Jeff 2024-09-02 11:04:08 -04:00
parent 4433c587f5
commit 3c2a70803e
3 changed files with 75 additions and 27 deletions

View File

@ -61,9 +61,13 @@ impl Context {
&self, &self,
identifier: &Identifier, identifier: &Identifier,
) -> Result<Option<(ContextData, usize)>, ContextError> { ) -> Result<Option<(ContextData, usize)>, ContextError> {
let associations = self.associations.read()?; if let Some((variable_data, position)) = self.associations.read()?.get(identifier) {
Ok(Some((variable_data.clone(), *position)))
Ok(associations.get(identifier).cloned()) } else if let Some(parent) = &self.parent {
parent.get(identifier)
} else {
Ok(None)
}
} }
/// Returns the type associated with the given identifier. /// Returns the type associated with the given identifier.
@ -268,11 +272,9 @@ impl Context {
let mut associations = self.associations.write()?; let mut associations = self.associations.write()?;
if let Some((_, last_position)) = associations.get_mut(identifier) { if let Some((_, last_position)) = associations.get_mut(identifier) {
if position > *last_position { log::trace!("Updating {identifier}'s last position to {position:?}");
log::trace!("Updating {identifier}'s last position to {position:?}");
*last_position = position; *last_position = position;
}
Ok(true) Ok(true)
} else { } else {

View File

@ -1,8 +1,8 @@
//! Top-level error handling for the Dust language. //! Top-level error handling for the Dust language.
use annotate_snippets::{Level, Renderer, Snippet}; use annotate_snippets::{Level, Message, Renderer, Snippet};
use std::fmt::Display; use std::fmt::Display;
use crate::{Span, AnalysisError, ContextError, LexError, ParseError, RuntimeError}; use crate::{AnalysisError, ContextError, LexError, ParseError, RuntimeError, Span};
/// An error that occurred during the execution of the Dust language and its /// An error that occurred during the execution of the Dust language and its
/// corresponding source code. /// corresponding source code.
@ -79,14 +79,26 @@ impl<'src> DustError<'src> {
} }
} }
pub fn error_data(&self) -> Vec<(&'static str, Span, String)> { fn footer(&self) -> Vec<(&'static str, Span, String)> {
match self { match self {
DustError::ContextError(_) => vec![], DustError::ContextError(_) => vec![],
DustError::Runtime { runtime_error, .. } => vec![( DustError::Runtime { runtime_error, .. } => {
"Runtime error", let mut error_data = vec![(
runtime_error.position(), "Runtime error",
runtime_error.to_string(), runtime_error.position(),
)], runtime_error.to_string(),
)];
if let RuntimeError::Expression { error, position } = runtime_error {
error_data.push((
"Error occured at this expression",
*position,
error.to_string(),
));
}
error_data
}
DustError::Analysis { DustError::Analysis {
analysis_errors, .. analysis_errors, ..
} => analysis_errors } => analysis_errors
@ -108,13 +120,43 @@ impl<'src> DustError<'src> {
let mut report = String::new(); let mut report = String::new();
let renderer = Renderer::styled(); let renderer = Renderer::styled();
for (title, span, label) in self.error_data() { match self {
let message = Level::Error.title(title).snippet( DustError::ContextError(_) => {
Snippet::source(self.source()) let message = Level::Error.title("Context error");
.annotation(Level::Info.span(span.0..span.1).label(&label)),
);
report.push_str(&format!("{}", renderer.render(message))); report.push_str(&renderer.render(message).to_string());
}
DustError::Runtime {
runtime_error,
source,
} => {
let error = runtime_error.root_error();
let position = error.position();
let label = error.to_string();
let message = Level::Error
.title("Runtime error")
.snippet(
Snippet::source(source)
.fold(true)
.annotation(Level::Error.span(position.0..position.1).label(&label)),
)
.footer(
Level::Error
.title("This error occured during the execution of the Dust program."),
);
report.push_str(&renderer.render(message).to_string());
report.push('\n');
}
DustError::Analysis {
analysis_errors,
source,
} => todo!(),
DustError::Parse {
parse_error,
source,
} => todo!(),
DustError::Lex { lex_error, source } => todo!(),
} }
report report

View File

@ -1236,6 +1236,14 @@ impl RuntimeError {
Self::UndefinedField { field_position, .. } => *field_position, Self::UndefinedField { field_position, .. } => *field_position,
} }
} }
pub fn root_error(&self) -> &Self {
match self {
Self::Expression { error, .. } => error.root_error(),
Self::Statement { error, .. } => error.root_error(),
error => error,
}
}
} }
impl From<ParseError> for RuntimeError { impl From<ParseError> for RuntimeError {
@ -1264,12 +1272,8 @@ impl Display for RuntimeError {
write!(f, "Function call error at {:?}: {}", position, error) write!(f, "Function call error at {:?}: {}", position, error)
} }
Self::ParseError(parse_error) => write!(f, "{}", parse_error), Self::ParseError(parse_error) => write!(f, "{}", parse_error),
Self::Expression { error, position } => { Self::Expression { .. } => {
write!( write!(f, "Error while running expression")
f,
"Error while running expression at {:?}: {}",
position, error
)
} }
Self::Statement { error, position } => { Self::Statement { error, position } => {
write!( write!(