use async_trait::async_trait;
use rspack_error::Result;
use crate::{
Compilation, artifacts::IncrementalArtifacts, cache::Cache, incremental::IncrementalPasses,
logger::Logger,
};
#[async_trait]
pub trait PassExt: Send + Sync {
fn name(&self) -> &'static str;
async fn run_pass(&self, compilation: &mut Compilation) -> Result<()>;
async fn run_pass_with_cache(
&self,
compilation: &mut Compilation,
_cache: &mut dyn Cache,
) -> Result<()> {
self.run_pass(compilation).await
}
fn incremental_passes(&self) -> IncrementalPasses {
IncrementalPasses::empty()
}
async fn before_pass(&self, _compilation: &mut Compilation, _cache: &mut dyn Cache) {}
async fn after_pass(&self, _compilation: &mut Compilation, _cache: &mut dyn Cache) {}
fn is_enabled(&self, _compilation: &Compilation) -> bool {
true
}
async fn run(&self, compilation: &mut Compilation, cache: &mut dyn Cache) -> Result<()> {
run(self, compilation, None, cache).await
}
}
pub(crate) async fn run_with_incremental_artifacts(
pass: &dyn PassExt,
compilation: &mut Compilation,
incremental_artifacts: &mut IncrementalArtifacts,
cache: &mut dyn Cache,
) -> Result<()> {
run(pass, compilation, Some(incremental_artifacts), cache).await
}
async fn run<P: PassExt + ?Sized>(
pass: &P,
compilation: &mut Compilation,
mut incremental_artifacts: Option<&mut IncrementalArtifacts>,
cache: &mut dyn Cache,
) -> Result<()> {
if !pass.is_enabled(compilation) {
return Ok(());
}
let logger = compilation.get_logger("rspack.Compilation");
let start = logger.time(pass.name());
let incremental_passes = pass.incremental_passes();
if let Some(incremental_artifacts) = incremental_artifacts.as_deref_mut() {
incremental_artifacts.recover(incremental_passes, compilation);
}
pass.before_pass(compilation, cache).await;
let result = pass.run_pass_with_cache(compilation, cache).await;
if result.is_ok() {
if let Some(incremental_artifacts) = incremental_artifacts {
incremental_artifacts.capture(incremental_passes, compilation);
}
pass.after_pass(compilation, cache).await;
}
logger.time_end(start);
result
}