1use std::fmt;
2
3use erg_common::config::ErgConfig;
4use erg_common::traits::{Runnable, Stream};
5use erg_common::Str;
6use erg_parser::ast::AST;
7
8use crate::context::ModuleContext;
9use crate::error::CompileErrors;
10use crate::hir::HIR;
11use crate::module::SharedCompilerResource;
12
13#[derive(Debug)]
14pub struct CompleteArtifact<Inner = HIR> {
15 pub object: Inner,
16 pub warns: CompileErrors,
17}
18
19impl<Inner> CompleteArtifact<Inner> {
20 pub const fn new(object: Inner, warns: CompileErrors) -> Self {
21 Self { object, warns }
22 }
23}
24
25#[derive(Debug)]
26pub struct IncompleteArtifact<Inner = HIR> {
27 pub object: Option<Inner>,
28 pub errors: CompileErrors,
29 pub warns: CompileErrors,
30}
31
32impl<I> fmt::Display for IncompleteArtifact<I> {
33 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34 if !self.warns.is_empty() {
35 writeln!(f, "{}", self.warns)?;
36 }
37 write!(f, "{}", self.errors)
38 }
39}
40
41impl<I: fmt::Debug> std::error::Error for IncompleteArtifact<I> {}
42
43impl<Inner> From<CompleteArtifact<Inner>> for IncompleteArtifact<Inner> {
44 fn from(artifact: CompleteArtifact<Inner>) -> Self {
45 Self {
46 object: Some(artifact.object),
47 errors: CompileErrors::empty(),
48 warns: artifact.warns,
49 }
50 }
51}
52
53impl<Inner> IncompleteArtifact<Inner> {
54 pub const fn new(object: Option<Inner>, errors: CompileErrors, warns: CompileErrors) -> Self {
55 Self {
56 object,
57 errors,
58 warns,
59 }
60 }
61}
62
63#[derive(Debug)]
64pub struct ErrorArtifact {
65 pub errors: CompileErrors,
66 pub warns: CompileErrors,
67}
68
69impl fmt::Display for ErrorArtifact {
70 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71 if !self.warns.is_empty() {
72 writeln!(f, "{}", self.warns)?;
73 }
74 write!(f, "{}", self.errors)
75 }
76}
77
78impl std::error::Error for ErrorArtifact {}
79
80impl<Inner> From<IncompleteArtifact<Inner>> for ErrorArtifact {
81 fn from(artifact: IncompleteArtifact<Inner>) -> Self {
82 Self {
83 errors: artifact.errors,
84 warns: artifact.warns,
85 }
86 }
87}
88
89impl From<CompileErrors> for ErrorArtifact {
90 fn from(errors: CompileErrors) -> Self {
91 Self {
92 errors,
93 warns: CompileErrors::empty(),
94 }
95 }
96}
97
98impl ErrorArtifact {
99 pub const fn new(errors: CompileErrors, warns: CompileErrors) -> Self {
100 Self { errors, warns }
101 }
102
103 pub fn clear(&mut self) {
104 self.errors.clear();
105 self.warns.clear();
106 }
107}
108
109pub trait Buildable<T = HIR> {
110 fn inherit(cfg: ErgConfig, shared: SharedCompilerResource) -> Self
111 where
112 Self: Sized;
113 fn inherit_with_name(cfg: ErgConfig, mod_name: Str, shared: SharedCompilerResource) -> Self
114 where
115 Self: Sized;
116 fn build(
117 &mut self,
118 src: String,
119 mode: &str,
120 ) -> Result<CompleteArtifact<T>, IncompleteArtifact<T>>;
121 fn build_from_ast(
122 &mut self,
123 ast: AST,
124 mode: &str,
125 ) -> Result<CompleteArtifact<T>, IncompleteArtifact<T>>;
126 fn pop_context(&mut self) -> Option<ModuleContext>;
127 fn get_context(&self) -> Option<&ModuleContext>;
128}
129
130pub trait BuildRunnable<T = HIR>: Buildable<T> + Runnable + 'static {
131 fn build_module(&mut self) -> Result<CompleteArtifact<T>, IncompleteArtifact<T>> {
132 let src = self.cfg_mut().input.read();
133 self.build(src, "exec")
134 }
135}