1use backend;
2use codebase::CodebaseError;
3use diagnostics;
4use diagnostics::InternalDiagnostic;
5use frontend;
6use frontend::{Downstream, Token};
7use span;
8use std::borrow::BorrowMut;
9use std::fmt::Debug;
10use std::marker;
11
12pub trait Session {
13 type Ident: Into<String> + Debug + PartialEq;
14 type Span: span::Span;
15 fn analyze_file(&mut self, path: Self::Ident) -> Result<(), CodebaseError>;
16 fn invoke_macro(
17 &mut self,
18 name: (Self::Ident, Self::Span),
19 args: MacroArgs<Self::Ident, Self::Span>,
20 );
21 fn emit_diagnostic(&mut self, diagnostic: InternalDiagnostic<Self::Span>);
22 fn emit_item(&mut self, item: backend::Item<Self::Span>);
23 fn define_label(&mut self, label: (String, Self::Span));
24 fn define_macro(
25 &mut self,
26 name: (impl Into<Self::Ident>, Self::Span),
27 params: Vec<(Self::Ident, Self::Span)>,
28 tokens: Vec<(Token<Self::Ident>, Self::Span)>,
29 );
30 fn set_origin(&mut self, origin: backend::RelocExpr<Self::Span>);
31}
32
33pub type MacroArgs<I, S> = Vec<Vec<(Token<I>, S)>>;
34
35pub struct Components<F, B, D, BMF, BMB, BMD>
36where
37 F: frontend::Frontend,
38 B: backend::Backend<F::Span>,
39 D: diagnostics::DiagnosticsListener<F::Span>,
40 BMF: BorrowMut<F>,
41 BMB: BorrowMut<B>,
42 BMD: BorrowMut<D>,
43{
44 frontend: BMF,
45 backend: BMB,
46 diagnostics: BMD,
47 phantom: marker::PhantomData<(F, B, D)>,
48}
49
50pub type BorrowedComponents<'a, F, B, D> = Components<F, B, D, &'a mut F, &'a mut B, &'a mut D>;
51
52impl<F, B, D, BMF, BMB, BMD> Components<F, B, D, BMF, BMB, BMD>
53where
54 F: frontend::Frontend,
55 B: backend::Backend<F::Span>,
56 D: diagnostics::DiagnosticsListener<F::Span>,
57 BMF: BorrowMut<F>,
58 BMB: BorrowMut<B>,
59 BMD: BorrowMut<D>,
60{
61 pub fn new(
62 frontend: BMF,
63 backend: BMB,
64 diagnostics: BMD,
65 ) -> Components<F, B, D, BMF, BMB, BMD> {
66 Components {
67 frontend,
68 backend,
69 diagnostics,
70 phantom: marker::PhantomData,
71 }
72 }
73
74 pub fn build_object(self) -> B::Object
75 where
76 BMB: Into<B>,
77 {
78 self.backend.into().into_object()
79 }
80}
81
82impl<F, B, D, BMF, BMB, BMD> Session for Components<F, B, D, BMF, BMB, BMD>
83where
84 F: frontend::Frontend,
85 B: backend::Backend<F::Span>,
86 D: diagnostics::DiagnosticsListener<F::Span>,
87 BMF: BorrowMut<F>,
88 BMB: BorrowMut<B>,
89 BMD: BorrowMut<D>,
90{
91 type Ident = F::Ident;
92 type Span = F::Span;
93
94 fn analyze_file(&mut self, path: Self::Ident) -> Result<(), CodebaseError> {
95 self.frontend.borrow_mut().analyze_file(
96 path,
97 Downstream {
98 backend: self.backend.borrow_mut(),
99 diagnostics: self.diagnostics.borrow_mut(),
100 },
101 )
102 }
103
104 fn invoke_macro(
105 &mut self,
106 name: (Self::Ident, Self::Span),
107 args: MacroArgs<Self::Ident, Self::Span>,
108 ) {
109 self.frontend.borrow_mut().invoke_macro(
110 name,
111 args,
112 Downstream {
113 backend: self.backend.borrow_mut(),
114 diagnostics: self.diagnostics.borrow_mut(),
115 },
116 )
117 }
118
119 fn emit_diagnostic(&mut self, diagnostic: InternalDiagnostic<Self::Span>) {
120 self.diagnostics.borrow_mut().emit_diagnostic(diagnostic)
121 }
122
123 fn emit_item(&mut self, item: backend::Item<Self::Span>) {
124 self.backend.borrow_mut().emit_item(item)
125 }
126
127 fn define_label(&mut self, label: (String, Self::Span)) {
128 self.backend.borrow_mut().add_label(label)
129 }
130
131 fn define_macro(
132 &mut self,
133 name: (impl Into<Self::Ident>, Self::Span),
134 params: Vec<(Self::Ident, Self::Span)>,
135 tokens: Vec<(Token<Self::Ident>, Self::Span)>,
136 ) {
137 self.frontend
138 .borrow_mut()
139 .define_macro(name, params, tokens)
140 }
141
142 fn set_origin(&mut self, origin: backend::RelocExpr<Self::Span>) {
143 self.backend.borrow_mut().set_origin(origin)
144 }
145}