-
-
Notifications
You must be signed in to change notification settings - Fork 594
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4d8472c
commit ca8aeed
Showing
9 changed files
with
962 additions
and
1,113 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
use rspack_error::Result; | ||
|
||
use super::{build::BuildTask, MakeTaskContext}; | ||
use crate::{ | ||
module_graph::{ModuleGraph, ModuleGraphModule}, | ||
utils::task_loop::{Task, TaskResult, TaskType}, | ||
DependencyId, Module, ModuleIdentifier, ModuleProfile, | ||
}; | ||
|
||
#[derive(Debug)] | ||
pub struct AddTask { | ||
pub original_module_identifier: Option<ModuleIdentifier>, | ||
pub module: Box<dyn Module>, | ||
pub module_graph_module: Box<ModuleGraphModule>, | ||
pub dependencies: Vec<DependencyId>, | ||
pub is_entry: bool, | ||
pub current_profile: Option<Box<ModuleProfile>>, | ||
} | ||
|
||
impl Task<MakeTaskContext> for AddTask { | ||
fn get_task_type(&self) -> TaskType { | ||
TaskType::Sync | ||
} | ||
fn sync_run(self: Box<Self>, context: &mut MakeTaskContext) -> TaskResult<MakeTaskContext> { | ||
if let Some(current_profile) = &self.current_profile { | ||
current_profile.mark_integration_start(); | ||
} | ||
|
||
let module_identifier = self.module.identifier(); | ||
let module_graph = &mut MakeTaskContext::get_module_graph(&mut context.module_graph_partial); | ||
|
||
if self.module.as_self_module().is_some() { | ||
let issuer = self | ||
.module_graph_module | ||
.get_issuer() | ||
.identifier() | ||
.expect("self module should have issuer"); | ||
|
||
set_resolved_module( | ||
module_graph, | ||
self.original_module_identifier, | ||
self.dependencies, | ||
*issuer, | ||
)?; | ||
|
||
// reused module | ||
return Ok(vec![]); | ||
} | ||
|
||
if module_graph | ||
.module_graph_module_by_identifier(&module_identifier) | ||
.is_some() | ||
{ | ||
set_resolved_module( | ||
module_graph, | ||
self.original_module_identifier, | ||
self.dependencies, | ||
module_identifier, | ||
)?; | ||
|
||
// reused module | ||
return Ok(vec![]); | ||
} | ||
|
||
module_graph.add_module_graph_module(*self.module_graph_module); | ||
|
||
set_resolved_module( | ||
module_graph, | ||
self.original_module_identifier, | ||
self.dependencies, | ||
module_identifier, | ||
)?; | ||
|
||
if self.is_entry { | ||
context.entry_module_identifiers.insert(module_identifier); | ||
} | ||
|
||
if let Some(current_profile) = &self.current_profile { | ||
current_profile.mark_integration_end(); | ||
} | ||
|
||
tracing::trace!("Module added: {}", self.module.identifier()); | ||
|
||
Ok(vec![Box::new(BuildTask { | ||
module: self.module, | ||
current_profile: self.current_profile, | ||
resolver_factory: context.resolver_factory.clone(), | ||
compiler_options: context.compiler_options.clone(), | ||
plugin_driver: context.plugin_driver.clone(), | ||
cache: context.cache.clone(), | ||
})]) | ||
} | ||
} | ||
|
||
fn set_resolved_module( | ||
module_graph: &mut ModuleGraph, | ||
original_module_identifier: Option<ModuleIdentifier>, | ||
dependencies: Vec<DependencyId>, | ||
module_identifier: ModuleIdentifier, | ||
) -> Result<()> { | ||
for dependency in dependencies { | ||
module_graph.set_resolved_module(original_module_identifier, dependency, module_identifier)?; | ||
} | ||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,230 @@ | ||
use std::{collections::VecDeque, sync::Arc}; | ||
|
||
use rspack_error::{Diagnostic, IntoTWithDiagnosticArray}; | ||
|
||
use super::{process_dependencies::ProcessDependenciesTask, MakeTaskContext}; | ||
use crate::{ | ||
cache::Cache, | ||
utils::task_loop::{Task, TaskResult, TaskType}, | ||
AsyncDependenciesBlock, BoxDependency, BuildContext, BuildResult, CompilerContext, | ||
CompilerOptions, DependencyParents, Module, ModuleProfile, ResolverFactory, SharedPluginDriver, | ||
}; | ||
|
||
#[derive(Debug)] | ||
pub struct BuildTask { | ||
pub module: Box<dyn Module>, | ||
pub current_profile: Option<Box<ModuleProfile>>, | ||
pub resolver_factory: Arc<ResolverFactory>, | ||
pub compiler_options: Arc<CompilerOptions>, | ||
pub plugin_driver: SharedPluginDriver, | ||
pub cache: Arc<Cache>, | ||
} | ||
|
||
#[async_trait::async_trait] | ||
impl Task<MakeTaskContext> for BuildTask { | ||
fn get_task_type(&self) -> TaskType { | ||
TaskType::Async | ||
} | ||
async fn async_run(self: Box<Self>) -> TaskResult<MakeTaskContext> { | ||
let Self { | ||
compiler_options, | ||
resolver_factory, | ||
plugin_driver, | ||
cache, | ||
current_profile, | ||
mut module, | ||
} = *self; | ||
if let Some(current_profile) = ¤t_profile { | ||
current_profile.mark_building_start(); | ||
} | ||
|
||
let (build_result, is_cache_valid) = cache | ||
.build_module_occasion | ||
.use_cache(&mut module, |module| async { | ||
plugin_driver | ||
.compilation_hooks | ||
.build_module | ||
.call(module) | ||
.await?; | ||
|
||
let result = module | ||
.build( | ||
BuildContext { | ||
compiler_context: CompilerContext { | ||
options: compiler_options.clone(), | ||
resolver_factory: resolver_factory.clone(), | ||
module: module.identifier(), | ||
module_context: module.as_normal_module().and_then(|m| m.get_context()), | ||
module_source_map_kind: module.get_source_map_kind().clone(), | ||
plugin_driver: plugin_driver.clone(), | ||
cache: cache.clone(), | ||
}, | ||
plugin_driver: plugin_driver.clone(), | ||
compiler_options: &compiler_options, | ||
}, | ||
None, | ||
) | ||
.await; | ||
|
||
plugin_driver | ||
.compilation_hooks | ||
.succeed_module | ||
.call(module) | ||
.await?; | ||
|
||
result.map(|t| { | ||
let diagnostics = module | ||
.clone_diagnostics() | ||
.into_iter() | ||
.map(|d| d.with_module_identifier(Some(module.identifier()))) | ||
.collect(); | ||
(t.with_diagnostic(diagnostics), module) | ||
}) | ||
}) | ||
.await?; | ||
|
||
if is_cache_valid { | ||
plugin_driver | ||
.compilation_hooks | ||
.still_valid_module | ||
.call(&mut module) | ||
.await?; | ||
} | ||
|
||
if let Some(current_profile) = ¤t_profile { | ||
current_profile.mark_building_end(); | ||
} | ||
|
||
build_result.map::<Vec<Box<dyn Task<MakeTaskContext>>>, _>(|build_result| { | ||
let (build_result, diagnostics) = build_result.split_into_parts(); | ||
vec![Box::new(BuildResultTask { | ||
module, | ||
build_result: Box::new(build_result), | ||
diagnostics, | ||
current_profile, | ||
from_cache: is_cache_valid, | ||
})] | ||
}) | ||
} | ||
} | ||
|
||
#[derive(Debug)] | ||
struct BuildResultTask { | ||
pub module: Box<dyn Module>, | ||
pub build_result: Box<BuildResult>, | ||
pub diagnostics: Vec<Diagnostic>, | ||
pub current_profile: Option<Box<ModuleProfile>>, | ||
pub from_cache: bool, | ||
} | ||
|
||
impl Task<MakeTaskContext> for BuildResultTask { | ||
fn get_task_type(&self) -> TaskType { | ||
TaskType::Sync | ||
} | ||
fn sync_run(self: Box<Self>, context: &mut MakeTaskContext) -> TaskResult<MakeTaskContext> { | ||
let BuildResultTask { | ||
mut module, | ||
build_result, | ||
diagnostics, | ||
current_profile, | ||
from_cache, | ||
} = *self; | ||
|
||
if let Some(counter) = &mut context.build_cache_counter { | ||
if from_cache { | ||
counter.hit(); | ||
} else { | ||
counter.miss(); | ||
} | ||
} | ||
|
||
let module_graph = &mut MakeTaskContext::get_module_graph(&mut context.module_graph_partial); | ||
if context.compiler_options.builtins.tree_shaking.enable() { | ||
context | ||
.optimize_analyze_result_map | ||
.insert(module.identifier(), build_result.analyze_result); | ||
} | ||
|
||
if !diagnostics.is_empty() { | ||
context.make_failed_module.insert(module.identifier()); | ||
} | ||
|
||
tracing::trace!("Module built: {}", module.identifier()); | ||
context.diagnostics.extend(diagnostics); | ||
module_graph | ||
.get_optimization_bailout_mut(&module.identifier()) | ||
.extend(build_result.optimization_bailouts); | ||
context | ||
.file_dependencies | ||
.extend(build_result.build_info.file_dependencies.clone()); | ||
context | ||
.context_dependencies | ||
.extend(build_result.build_info.context_dependencies.clone()); | ||
context | ||
.missing_dependencies | ||
.extend(build_result.build_info.missing_dependencies.clone()); | ||
context | ||
.build_dependencies | ||
.extend(build_result.build_info.build_dependencies.clone()); | ||
|
||
let mut queue = VecDeque::new(); | ||
let mut all_dependencies = vec![]; | ||
let mut handle_block = |dependencies: Vec<BoxDependency>, | ||
blocks: Vec<AsyncDependenciesBlock>, | ||
current_block: Option<AsyncDependenciesBlock>| | ||
-> Vec<AsyncDependenciesBlock> { | ||
for dependency in dependencies { | ||
let dependency_id = *dependency.id(); | ||
if current_block.is_none() { | ||
module.add_dependency_id(dependency_id); | ||
} | ||
all_dependencies.push(dependency_id); | ||
module_graph.set_parents( | ||
dependency_id, | ||
DependencyParents { | ||
block: current_block.as_ref().map(|block| block.identifier()), | ||
module: module.identifier(), | ||
}, | ||
); | ||
module_graph.add_dependency(dependency); | ||
} | ||
if let Some(current_block) = current_block { | ||
module.add_block_id(current_block.identifier()); | ||
module_graph.add_block(current_block); | ||
} | ||
blocks | ||
}; | ||
let blocks = handle_block(build_result.dependencies, build_result.blocks, None); | ||
queue.extend(blocks); | ||
|
||
while let Some(mut block) = queue.pop_front() { | ||
let dependencies = block.take_dependencies(); | ||
let blocks = handle_block(dependencies, block.take_blocks(), Some(block)); | ||
queue.extend(blocks); | ||
} | ||
|
||
{ | ||
let mgm = module_graph | ||
.module_graph_module_by_identifier_mut(&module.identifier()) | ||
.expect("Failed to get mgm"); | ||
mgm.__deprecated_all_dependencies = all_dependencies.clone(); | ||
if let Some(current_profile) = current_profile { | ||
mgm.set_profile(current_profile); | ||
} | ||
} | ||
|
||
let module_identifier = module.identifier(); | ||
|
||
module.set_build_info(build_result.build_info); | ||
module.set_build_meta(build_result.build_meta); | ||
|
||
let resolve_options = module.get_resolve_options(); | ||
module_graph.add_module(module); | ||
|
||
Ok(vec![Box::new(ProcessDependenciesTask { | ||
dependencies: all_dependencies, | ||
original_module_identifier: module_identifier, | ||
resolve_options, | ||
})]) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
use super::MakeTaskContext; | ||
use crate::{ | ||
utils::task_loop::{Task, TaskResult, TaskType}, | ||
ModuleIdentifier, | ||
}; | ||
|
||
pub struct CleanTask { | ||
pub module_identifier: ModuleIdentifier, | ||
} | ||
|
||
impl Task<MakeTaskContext> for CleanTask { | ||
fn get_task_type(&self) -> TaskType { | ||
TaskType::Sync | ||
} | ||
fn sync_run(self: Box<Self>, context: &mut MakeTaskContext) -> TaskResult<MakeTaskContext> { | ||
let module_identifier = self.module_identifier; | ||
let module_graph = &mut MakeTaskContext::get_module_graph(&mut context.module_graph_partial); | ||
let Some(mgm) = module_graph.module_graph_module_by_identifier(&module_identifier) else { | ||
tracing::trace!("Module is cleaned: {}", module_identifier); | ||
return Ok(vec![]); | ||
}; | ||
|
||
if !mgm.incoming_connections().is_empty() { | ||
tracing::trace!("Module is used: {}", module_identifier); | ||
return Ok(vec![]); | ||
} | ||
|
||
let dependent_module_identifiers: Vec<ModuleIdentifier> = module_graph | ||
.get_module_all_depended_modules(&module_identifier) | ||
.expect("should have module") | ||
.into_iter() | ||
.copied() | ||
.collect(); | ||
module_graph.revoke_module(&module_identifier); | ||
|
||
let mut res: Vec<Box<dyn Task<MakeTaskContext>>> = | ||
Vec::with_capacity(dependent_module_identifiers.len()); | ||
for module_identifier in dependent_module_identifiers { | ||
res.push(Box::new(CleanTask { module_identifier })) | ||
} | ||
Ok(res) | ||
} | ||
} |
Oops, something went wrong.