use crate::config::LogLevel;
use swc_core::{
common::{sync::Lrc, SourceMap},
ecma::{
ast::Program,
codegen::{text_writer::JsWriter, Config as CodegenConfig, Emitter},
},
};
const LOG_PREFIX: &str = "[intlayer/swc]";
pub static DEBUG_LOG: bool = false;
#[derive(Debug, Clone, Copy)]
pub struct Logger {
level: LogLevel,
}
impl Logger {
pub fn new(level: LogLevel) -> Self {
Self { level }
}
pub fn is_enabled(&self) -> bool {
self.level > LogLevel::Off
}
pub fn is_debug(&self) -> bool {
self.level >= LogLevel::Debug
}
pub fn info(&self, message: impl AsRef<str>) {
if self.level >= LogLevel::Info {
println!("{} {}", LOG_PREFIX, message.as_ref());
}
}
pub fn debug(&self, message: impl AsRef<str>) {
if self.is_debug() {
println!("{} {}", LOG_PREFIX, message.as_ref());
}
}
pub fn report_file(&self, file_path: &str, summary: &TransformSummary, program: &Program) {
if !self.is_enabled() {
return;
}
if !summary.changed_anything() {
self.debug(format!("{}: unchanged", file_path));
return;
}
self.info(format!(
"{}: {} static import(s), {} dynamic import(s), {} field rename(s)",
file_path, summary.static_imports, summary.dynamic_imports, summary.renamed_fields
));
if self.is_debug() {
self.debug(format!(
"{}: output\n{}",
file_path,
program_to_code(program)
));
}
}
}
#[derive(Debug, Default, Clone, Copy)]
pub struct TransformSummary {
pub static_imports: usize,
pub dynamic_imports: usize,
pub renamed_fields: usize,
}
impl TransformSummary {
pub fn changed_anything(&self) -> bool {
self.static_imports > 0 || self.dynamic_imports > 0 || self.renamed_fields > 0
}
}
pub fn program_to_code(program: &Program) -> String {
let source_map = Lrc::new(SourceMap::default());
let mut buffer = vec![];
{
let writer = JsWriter::new(source_map.clone(), "\n", &mut buffer, None);
let mut emitter = Emitter {
cfg: CodegenConfig::default(),
cm: source_map.clone(),
comments: None,
wr: writer,
};
let _ = emitter.emit_program(program);
}
String::from_utf8_lossy(&buffer).into_owned()
}