1use std::convert::Infallible;
2use codespan_reporting::files::{Error, Files};
3use codespan_reporting::term::termcolor::WriteColor;
4use derive_more::{From, Unwrap};
5
6use kodept_ast::graph::SyntaxTree;
7use kodept_ast::traits::{Accessor, Linker};
8use kodept_core::code_point::CodePoint;
9use kodept_core::file_relative::CodePath;
10
11use crate::error::report::{Report, ReportMessage};
12use crate::error::traits::{CodespanSettings, Reportable};
13
14#[derive(Debug, From, Unwrap)]
15pub enum UnrecoverableError {
16 Report(Report),
17 Infallible(Infallible),
18}
19
20impl UnrecoverableError {
21 pub fn into_report(self) -> Report {
22 match self {
23 UnrecoverableError::Report(x) => x,
24 UnrecoverableError::Infallible(_) => unreachable!(),
25 }
26 }
27}
28
29impl Reportable for UnrecoverableError {
30 type FileId = ();
31
32 fn emit<'f, W: WriteColor, F: Files<'f, FileId=Self::FileId>>(self, settings: &mut CodespanSettings<W>, source: &'f F) -> Result<(), Error> {
33 self.into_report().emit(settings, source)
34 }
35}
36
37pub trait Reporter: FileContextual {
38 fn report_and_fail<R: Into<ReportMessage>, T>(
39 &self,
40 at: Vec<CodePoint>,
41 message: R,
42 ) -> Result<T, UnrecoverableError> {
43 Err(Report::new(&self.file_path(), at, message).into())
44 }
45
46 fn add_report<R: Into<ReportMessage>>(&mut self, at: Vec<CodePoint>, message: R) {
47 self.report(Report::new(&self.file_path(), at, message))
48 }
49
50 fn report(&mut self, report: Report);
51}
52
53pub trait FileContextual {
54 fn file_path(&self) -> CodePath;
55}
56
57pub trait Context: Linker + Accessor + Reporter {}
58
59pub trait MutableContext: Context {
60 fn modify_tree(
61 &mut self,
62 f: impl FnOnce(SyntaxTree) -> SyntaxTree,
63 ) -> Result<(), ReportMessage>;
64}
65
66impl<T: Linker + Accessor + Reporter> Context for T {}