use crate::error::Result;
use crate::format::FormatOptions;
use oxc_allocator::Allocator;
use oxc_ast::AstBuilder;
use oxc_ast::ast::*;
use oxc_codegen::Codegen;
use oxc_span::{SPAN, SourceType};
use std::io::Write;
pub struct ProgramBuilder<'a> {
ast: AstBuilder<'a>,
body: Vec<Statement<'a>>,
source_type: SourceType,
}
impl<'a> ProgramBuilder<'a> {
pub fn new(allocator: &'a Allocator) -> Self {
Self {
ast: AstBuilder::new(allocator),
body: Vec::new(),
source_type: SourceType::mjs(),
}
}
pub fn with_source_type(allocator: &'a Allocator, source_type: SourceType) -> Self {
Self {
ast: AstBuilder::new(allocator),
body: Vec::new(),
source_type,
}
}
pub fn ast(&self) -> &AstBuilder<'a> {
&self.ast
}
pub fn ast_mut(&mut self) -> &mut AstBuilder<'a> {
&mut self.ast
}
pub fn push(&mut self, stmt: Statement<'a>) {
self.body.push(stmt);
}
pub fn extend(&mut self, stmts: impl IntoIterator<Item = Statement<'a>>) {
self.body.extend(stmts);
}
pub fn len(&self) -> usize {
self.body.len()
}
pub fn is_empty(&self) -> bool {
self.body.is_empty()
}
pub fn write_to<W: Write>(self, writer: &mut W, _opts: &FormatOptions) -> Result<()> {
let body_vec = self.ast.vec_from_iter(self.body);
let program = self.ast.program(
SPAN,
self.source_type,
"",
self.ast.vec(), None, self.ast.vec(), body_vec,
);
let codegen = Codegen::new();
let result = codegen.build(&program);
writer
.write_all(result.code.as_bytes())
.map_err(|e| crate::error::GenError::CodegenFailed(format!("Write error: {}", e)))?;
Ok(())
}
pub fn generate(self, _opts: &FormatOptions) -> Result<String> {
let body_vec = self.ast.vec_from_iter(self.body);
let program = self.ast.program(
SPAN,
self.source_type,
"",
self.ast.vec(), None, self.ast.vec(), body_vec,
);
let codegen = Codegen::new();
let result = codegen.build(&program);
Ok(result.code)
}
pub fn build_program(self) -> Program<'a> {
let body_vec = self.ast.vec_from_iter(self.body);
self.ast.program(
SPAN,
self.source_type,
"",
self.ast.vec(), None, self.ast.vec(), body_vec,
)
}
}