Clean up location handling, which wsa kind of a pain.
This commit is contained in:
129
src/errors.rs
129
src/errors.rs
@@ -1,46 +1,18 @@
|
||||
use crate::syntax::{LexerError, Location, Token};
|
||||
use codespan_reporting::diagnostic::{Diagnostic, Label};
|
||||
use crate::syntax::{Location, ParserError};
|
||||
use codespan_reporting::diagnostic::Diagnostic;
|
||||
use codespan_reporting::files;
|
||||
use lalrpop_util::ParseError;
|
||||
use std::io;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
#[error("IO failure: {0}")]
|
||||
IOError(#[from] io::Error),
|
||||
|
||||
#[error("Internal file database error: {0}")]
|
||||
InternalFileDBError(#[from] files::Error),
|
||||
|
||||
#[error("Error in parser: {0}")]
|
||||
ParserError(#[from] ParseError<Location, Token, LexerError>),
|
||||
|
||||
#[error("Internal error: Couldn't deal with bound variable with no bindiing site ({0})")]
|
||||
IOError(io::Error),
|
||||
InternalFileDBError(files::Error),
|
||||
ParserError(ParserError),
|
||||
BindingSiteFailure(Location, String),
|
||||
|
||||
#[error("Unbound variable '{0}'")]
|
||||
UnboundVariable(Location, String),
|
||||
|
||||
#[error("Internal error: {0}")]
|
||||
InternalError(Location, String),
|
||||
}
|
||||
|
||||
fn locations_to_labels(start: &Location, end: &Location) -> Vec<Label<usize>> {
|
||||
match start {
|
||||
Location::Manufactured => match end {
|
||||
Location::Manufactured => vec![],
|
||||
Location::InFile(file_id, off) => vec![Label::primary(*file_id, *off..*off)],
|
||||
},
|
||||
Location::InFile(file_id1, start) => match end {
|
||||
Location::InFile(file_id2, end) if file_id1 == file_id2 => {
|
||||
vec![Label::primary(*file_id1, *start..*end)]
|
||||
}
|
||||
_ => vec![Label::primary(*file_id1, *start..*start)],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn display_expected(expected: &[String]) -> String {
|
||||
match expected.len() {
|
||||
0 => "".to_string(),
|
||||
@@ -74,37 +46,21 @@ impl From<Error> for Diagnostic<usize> {
|
||||
|
||||
Error::ParserError(pe) => match pe {
|
||||
// this was just a token we didn't understand
|
||||
ParseError::InvalidToken { location } => match location {
|
||||
Location::Manufactured => Diagnostic::error().with_message(
|
||||
"encountered extremely confusing token (in generated data?!)",
|
||||
),
|
||||
Location::InFile(file_id, off) => Diagnostic::error()
|
||||
.with_message("encountered extremely confusing token")
|
||||
.with_labels(vec![Label::primary(*file_id, *off..*off)
|
||||
.with_message("extremely odd token")]),
|
||||
},
|
||||
ParserError::InvalidToken(location) => location
|
||||
.labelled_error("extremely odd token")
|
||||
.with_message("encountered extremely confusing token"),
|
||||
|
||||
// unexpected EOF!
|
||||
ParseError::UnrecognizedEOF { location, expected } => match location {
|
||||
Location::Manufactured => Diagnostic::error().with_message(format!(
|
||||
"unexpected end of file{}",
|
||||
display_expected(expected)
|
||||
)),
|
||||
Location::InFile(file_id, off) => Diagnostic::error()
|
||||
.with_message(format!(
|
||||
"unexpected enf of file{}",
|
||||
display_expected(expected)
|
||||
))
|
||||
.with_labels(vec![Label::primary(*file_id, *off..*off)]),
|
||||
},
|
||||
ParserError::UnrecognizedEOF(location, expected) => location.error().with_message(
|
||||
format!("expected enf of file{}", display_expected(expected)),
|
||||
),
|
||||
|
||||
// encountered a token where it shouldn't be
|
||||
ParseError::UnrecognizedToken { token, expected } => {
|
||||
let (start, token, end) = token;
|
||||
ParserError::UnrecognizedToken(start, end, token, expected) => {
|
||||
let expected_str =
|
||||
format!("unexpected token {}{}", token, display_expected(expected));
|
||||
let unexpected_str = format!("unexpected token {}", token);
|
||||
let mut labels = locations_to_labels(start, end);
|
||||
let mut labels = start.range_label(end);
|
||||
|
||||
Diagnostic::error()
|
||||
.with_labels(
|
||||
@@ -117,12 +73,11 @@ impl From<Error> for Diagnostic<usize> {
|
||||
}
|
||||
|
||||
// I think we get this when we get a token, but were expected EOF
|
||||
ParseError::ExtraToken { token } => {
|
||||
let (start, token, end) = token;
|
||||
ParserError::ExtraToken(start, token, end) => {
|
||||
let expected_str =
|
||||
format!("unexpected token {} after the expected end of file", token);
|
||||
let unexpected_str = format!("unexpected token {}", token);
|
||||
let mut labels = locations_to_labels(start, end);
|
||||
let mut labels = start.range_label(end);
|
||||
|
||||
Diagnostic::error()
|
||||
.with_labels(
|
||||
@@ -135,53 +90,25 @@ impl From<Error> for Diagnostic<usize> {
|
||||
}
|
||||
|
||||
// simple lexer errors
|
||||
ParseError::User { error } => match error {
|
||||
LexerError::LexFailure(location) => match location {
|
||||
Location::Manufactured => Diagnostic::error()
|
||||
.with_message("unexpected character encountered in manufactured code?"),
|
||||
Location::InFile(file_id, offset) => Diagnostic::error()
|
||||
.with_labels(vec![Label::primary(*file_id, *offset..*offset)
|
||||
.with_message("unexpected character")]),
|
||||
},
|
||||
},
|
||||
ParserError::LexFailure(location) => {
|
||||
location.error().with_message("unexpected character")
|
||||
}
|
||||
},
|
||||
|
||||
Error::BindingSiteFailure(location, name) => match location {
|
||||
Location::Manufactured => Diagnostic::error().with_message(format!(
|
||||
Error::BindingSiteFailure(location, name) => location
|
||||
.labelled_error("discovered here")
|
||||
.with_message(format!(
|
||||
"Internal Error: Lost binding site for bound variable {}",
|
||||
name
|
||||
)),
|
||||
Location::InFile(file_id, offset) => Diagnostic::error()
|
||||
.with_labels(vec![
|
||||
Label::primary(*file_id, *offset..*offset).with_message("discovered here")
|
||||
])
|
||||
.with_message(format!(
|
||||
"Internal Error: Lost binding site for bound variable {}",
|
||||
name
|
||||
)),
|
||||
},
|
||||
|
||||
Error::UnboundVariable(location, name) => match location {
|
||||
Location::Manufactured => {
|
||||
Diagnostic::error().with_message(format!("Unbound variable '{}'", name))
|
||||
}
|
||||
Location::InFile(file_id, offset) => Diagnostic::error()
|
||||
.with_labels(vec![
|
||||
Label::primary(*file_id, *offset..*offset).with_message("unbound here")
|
||||
])
|
||||
.with_message(format!("Unbound variable '{}'", name)),
|
||||
},
|
||||
Error::UnboundVariable(location, name) => location
|
||||
.labelled_error("unbound here")
|
||||
.with_message(format!("Unbound variable '{}'", name)),
|
||||
|
||||
Error::InternalError(location, string) => match location {
|
||||
Location::Manufactured => {
|
||||
Diagnostic::error().with_message(format!("Internal error: {}", string))
|
||||
}
|
||||
Location::InFile(file_id, offset) => Diagnostic::error()
|
||||
.with_labels(vec![
|
||||
Label::primary(*file_id, *offset..*offset).with_message("this is related")
|
||||
])
|
||||
.with_message(format!("Internal error: {}", string)),
|
||||
},
|
||||
Error::InternalError(location, string) => location
|
||||
.labelled_error("this is related")
|
||||
.with_message(format!("Internal error: {}", string)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user