use crate::{ format_diagnostic::{lalrpop_error_to_diagnostic, DiagnosticExt, ToDiagnostic}, parser::{lexer, parse_error}, }; use codespan_reporting::diagnostic; use eww_shared_util::{Span, Spanned}; use simplexpr::dynval; use thiserror::Error; pub type DiagResult = Result; #[derive(Debug, Error)] #[error("{}", .0.to_message())] pub struct DiagError(pub diagnostic::Diagnostic); static_assertions::assert_impl_all!(DiagError: Send, Sync); static_assertions::assert_impl_all!(dynval::ConversionError: Send, Sync); static_assertions::assert_impl_all!(lalrpop_util::ParseError < usize, lexer::Token, parse_error::ParseError>: Send, Sync); impl From for DiagError { fn from(x: T) -> Self { Self(x.to_diagnostic()) } } impl DiagError { pub fn note(self, note: &str) -> Self { DiagError(self.0.with_note(note.to_string())) } pub fn from_parse_error( file_id: usize, err: lalrpop_util::ParseError, ) -> DiagError { DiagError(lalrpop_error_to_diagnostic(&err, file_id)) } } pub fn get_parse_error_span(file_id: usize, err: &lalrpop_util::ParseError) -> Span { use lalrpop_util::ParseError::*; match err { InvalidToken { location } => Span(*location, *location, file_id), UnrecognizedEOF { location, .. } => Span(*location, *location, file_id), UnrecognizedToken { token, .. } => Span(token.0, token.2, file_id), ExtraToken { token } => Span(token.0, token.2, file_id), User { error } => error.span(), } } pub trait DiagResultExt { fn note(self, note: &str) -> DiagResult; } impl DiagResultExt for DiagResult { fn note(self, note: &str) -> DiagResult { self.map_err(|e| e.note(note)) } }