Refactor error reports
This commit is contained in:
parent
4433c587f5
commit
3c2a70803e
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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!(
|
||||||
|
Loading…
Reference in New Issue
Block a user