vue_compiler_core/
compiler.rs

1use super::{
2    codegen::{CodeGenerateOption, CodeGenerator, CodeWriter},
3    converter::{BaseConvertInfo as BaseInfo, BaseConverter, BaseRoot, ConvertOption, Converter},
4    error::ErrorHandler,
5    parser::{ParseOption, Parser},
6    scanner::{ScanOption, Scanner},
7    transformer::{BaseTransformer, CorePass, MergedPass, TransformOption, Transformer},
8};
9
10use std::io;
11
12// TODO: we have internal option that diverges from vue's option
13// CompileOption should behave like Vue option and be normalized to internal option
14pub struct CompileOption<E: ErrorHandler + Clone> {
15    pub scanning: ScanOption,
16    pub parsing: ParseOption,
17    pub conversion: ConvertOption,
18    pub transformation: TransformOption,
19    pub codegen: CodeGenerateOption,
20    pub error_handler: E,
21}
22
23// TODO: refactor this ownership usage
24pub trait TemplateCompiler<'a> {
25    type IR;
26    type Output;
27    type Eh: ErrorHandler;
28    type Conv: Converter<'a, IR = Self::IR>;
29    type Trans: Transformer<IR = Self::IR>;
30    type Gen: CodeGenerator<IR = Self::IR, Output = Self::Output>;
31
32    fn get_scanner(&self) -> Scanner;
33    fn get_parser(&self) -> Parser;
34    fn get_converter(&self) -> Self::Conv;
35    fn get_transformer(&mut self) -> Self::Trans;
36    fn get_code_generator(&mut self) -> Self::Gen;
37    fn get_error_handler(&self) -> Self::Eh;
38
39    fn compile(&mut self, source: &'a str) -> Self::Output {
40        let scanner = self.get_scanner();
41        let parser = self.get_parser();
42        let eh = self.get_error_handler();
43        let tokens = scanner.scan(source, eh);
44        let eh = self.get_error_handler();
45        let ast = parser.parse(tokens, eh);
46        let mut ir = self.get_converter().convert_ir(ast);
47        self.get_transformer().transform(&mut ir);
48        self.get_code_generator().generate(ir)
49    }
50}
51
52type Passes<'a, 'b> = &'b mut dyn CorePass<BaseInfo<'a>>;
53
54pub struct BaseCompiler<'a, 'b, Eh: ErrorHandler + Clone, W: io::Write> {
55    writer: Option<W>,
56    passes: Option<&'b mut [Passes<'a, 'b>]>,
57    option: CompileOption<Eh>,
58}
59
60impl<'a, 'b, Eh, W> BaseCompiler<'a, 'b, Eh, W>
61where
62    W: io::Write,
63    Eh: ErrorHandler + Clone + 'static,
64{
65    pub fn new(writer: W, passes: &'b mut [Passes<'a, 'b>], option: CompileOption<Eh>) -> Self {
66        Self {
67            writer: Some(writer),
68            passes: Some(passes),
69            option,
70        }
71    }
72}
73
74impl<'a, 'b, Eh, W> TemplateCompiler<'a> for BaseCompiler<'a, 'b, Eh, W>
75where
76    W: io::Write,
77    Eh: ErrorHandler + Clone + 'static,
78{
79    type IR = BaseRoot<'a>;
80    type Eh = Eh;
81    type Output = io::Result<()>;
82    type Conv = BaseConverter<'a>;
83    type Trans = BaseTransformer<'a, MergedPass<'b, Passes<'a, 'b>>>;
84    type Gen = CodeWriter<'a, W>;
85
86    fn get_scanner(&self) -> Scanner {
87        Scanner::new(self.option.scanning.clone())
88    }
89
90    fn get_parser(&self) -> Parser {
91        Parser::new(self.option.parsing.clone())
92    }
93    fn get_converter(&self) -> Self::Conv {
94        let eh = self.get_error_handler();
95        let option = self.option.conversion.clone();
96        BaseConverter {
97            err_handle: Box::new(eh),
98            sfc_info: Default::default(),
99            option,
100        }
101    }
102    fn get_transformer(&mut self) -> Self::Trans {
103        let pass = MergedPass::new(self.passes.take().unwrap());
104        BaseTransformer::new(pass)
105    }
106    fn get_code_generator(&mut self) -> Self::Gen {
107        let option = self.option.codegen.clone();
108        let writer = self.writer.take().unwrap();
109        CodeWriter::new(writer, option)
110    }
111    fn get_error_handler(&self) -> Self::Eh {
112        self.option.error_handler.clone()
113    }
114}