use std::sync::Arc;
use farmfe_core::{
config::script::{DecoratorVersion, ScriptConfig},
context::CompilationContext,
module::ModuleId,
plugin::PluginProcessModuleHookParam,
swc_common::{comments::SingleThreadedComments, Globals, Mark, SourceMap},
swc_ecma_ast::Program,
};
use farmfe_toolkit::{
script::swc_try_with::try_with,
swc_ecma_transforms::{
proposals::{decorator_2022_03::decorator_2022_03, decorators},
typescript::{tsx, typescript, Config as TsConfig, ImportsNotUsedAsValues, TsxConfig},
},
swc_ecma_transforms_base::helpers::inject_helpers,
swc_ecma_visit::VisitMutWith,
};
fn default_config(script: &ScriptConfig, module_id: &ModuleId) -> TsConfig {
let import_not_used_as_values = if script.import_not_used_as_values.is_preserved(module_id) {
ImportsNotUsedAsValues::Preserve
} else {
ImportsNotUsedAsValues::Remove
};
TsConfig {
import_not_used_as_values,
..Default::default()
}
}
pub fn strip_typescript(
param: &mut PluginProcessModuleHookParam,
cm: &Arc<SourceMap>,
globals: &Globals,
context: &Arc<CompilationContext>,
) -> farmfe_core::error::Result<()> {
try_with(cm.clone(), globals, || {
let top_level_mark = Mark::from_u32(param.meta.as_script().top_level_mark);
let unresolved_mark = Mark::from_u32(param.meta.as_script().unresolved_mark);
let ast = param.meta.as_script_mut().take_ast();
let mut program = Program::Module(ast);
match param.module_type {
farmfe_core::module::ModuleType::Js => {}
farmfe_core::module::ModuleType::Jsx => {
}
farmfe_core::module::ModuleType::Ts => {
program.mutate(&mut typescript(
default_config(&context.config.script, param.module_id),
unresolved_mark,
top_level_mark,
));
}
farmfe_core::module::ModuleType::Tsx => {
let comments: SingleThreadedComments = param.meta.as_script().comments.clone().into();
program.mutate(&mut tsx(
cm.clone(),
default_config(&context.config.script, param.module_id),
TsxConfig::default(),
comments,
unresolved_mark,
top_level_mark,
));
program.mutate(&mut typescript(
default_config(&context.config.script, param.module_id),
unresolved_mark,
top_level_mark,
));
}
_ => {}
}
param.meta.as_script_mut().set_ast(program.expect_module());
})
}
pub fn transform_decorators(
param: &mut PluginProcessModuleHookParam,
cm: &Arc<SourceMap>,
globals: &Globals,
context: &Arc<CompilationContext>,
) -> farmfe_core::error::Result<()> {
let config = &context.config.script.decorators;
let is_included = config
.includes
.iter()
.any(|r| r.is_match(¶m.module_id.to_string()));
let is_excluded = config
.excludes
.iter()
.any(|r| r.is_match(¶m.module_id.to_string()));
if is_included || !is_excluded {
try_with(cm.clone(), globals, || {
let mut ast = Program::Module(param.meta.as_script_mut().take_ast());
match config.decorator_version.clone().unwrap_or_default() {
DecoratorVersion::V202112 => {
ast.mutate(&mut decorators(decorators::Config {
legacy: config.legacy_decorator,
emit_metadata: config.decorator_metadata,
..Default::default()
}));
}
DecoratorVersion::V202203 => ast.mutate(&mut decorator_2022_03()),
}
let unresolved_mark = Mark::from_u32(param.meta.as_script().unresolved_mark);
ast.visit_mut_with(&mut inject_helpers(unresolved_mark));
param.meta.as_script_mut().set_ast(ast.expect_module());
})?;
}
Ok(())
}