fob_gen/
program_builder.rs1use crate::error::Result;
4use crate::format::FormatOptions;
5use oxc_allocator::Allocator;
6use oxc_ast::AstBuilder;
7use oxc_ast::ast::*;
8use oxc_codegen::Codegen;
9use oxc_span::{SPAN, SourceType};
10use std::io::Write;
11
12pub struct ProgramBuilder<'a> {
17 ast: AstBuilder<'a>,
18 body: Vec<Statement<'a>>,
19 source_type: SourceType,
20}
21
22impl<'a> ProgramBuilder<'a> {
23 pub fn new(allocator: &'a Allocator) -> Self {
25 Self {
26 ast: AstBuilder::new(allocator),
27 body: Vec::new(),
28 source_type: SourceType::mjs(),
29 }
30 }
31
32 pub fn with_source_type(allocator: &'a Allocator, source_type: SourceType) -> Self {
34 Self {
35 ast: AstBuilder::new(allocator),
36 body: Vec::new(),
37 source_type,
38 }
39 }
40
41 pub fn ast(&self) -> &AstBuilder<'a> {
43 &self.ast
44 }
45
46 pub fn ast_mut(&mut self) -> &mut AstBuilder<'a> {
48 &mut self.ast
49 }
50
51 pub fn push(&mut self, stmt: Statement<'a>) {
53 self.body.push(stmt);
54 }
55
56 pub fn extend(&mut self, stmts: impl IntoIterator<Item = Statement<'a>>) {
58 self.body.extend(stmts);
59 }
60
61 pub fn len(&self) -> usize {
63 self.body.len()
64 }
65
66 pub fn is_empty(&self) -> bool {
68 self.body.is_empty()
69 }
70
71 pub fn write_to<W: Write>(self, writer: &mut W, _opts: &FormatOptions) -> Result<()> {
75 let body_vec = self.ast.vec_from_iter(self.body);
76 let program = self.ast.program(
77 SPAN,
78 self.source_type,
79 "",
80 self.ast.vec(), None, self.ast.vec(), body_vec,
84 );
85
86 let codegen = Codegen::new();
87 let result = codegen.build(&program);
88
89 writer
90 .write_all(result.code.as_bytes())
91 .map_err(|e| crate::error::GenError::CodegenFailed(format!("Write error: {}", e)))?;
92
93 Ok(())
94 }
95
96 pub fn generate(self, _opts: &FormatOptions) -> Result<String> {
100 let body_vec = self.ast.vec_from_iter(self.body);
101 let program = self.ast.program(
102 SPAN,
103 self.source_type,
104 "",
105 self.ast.vec(), None, self.ast.vec(), body_vec,
109 );
110
111 let codegen = Codegen::new();
112 let result = codegen.build(&program);
113
114 Ok(result.code)
115 }
116
117 pub fn build_program(self) -> Program<'a> {
121 let body_vec = self.ast.vec_from_iter(self.body);
122 self.ast.program(
123 SPAN,
124 self.source_type,
125 "",
126 self.ast.vec(), None, self.ast.vec(), body_vec,
130 )
131 }
132}