-
Notifications
You must be signed in to change notification settings - Fork 503
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: generate the namespace variable on demand
- Loading branch information
Showing
150 changed files
with
221 additions
and
715 deletions.
There are no files selected for viewing
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
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
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
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
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
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
152 changes: 152 additions & 0 deletions
152
crates/rolldown/src/bundler/stages/link_stage/tree_shaking.rs
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,152 @@ | ||
use index_vec::IndexVec; | ||
use rolldown_common::{ModuleId, StmtInfoId, SymbolRef}; | ||
|
||
use crate::bundler::{ | ||
module::{Module, ModuleVec, NormalModule}, | ||
utils::symbols::Symbols, | ||
}; | ||
|
||
use super::LinkStage; | ||
|
||
struct Context<'a> { | ||
modules: &'a ModuleVec, | ||
symbols: &'a Symbols, | ||
is_included_vec: &'a mut IndexVec<ModuleId, IndexVec<StmtInfoId, bool>>, | ||
is_module_included_vec: &'a mut IndexVec<ModuleId, bool>, | ||
} | ||
|
||
fn include_module(ctx: &mut Context, module: &NormalModule) { | ||
let is_included = ctx.is_module_included_vec[module.id]; | ||
if is_included { | ||
return; | ||
} | ||
|
||
ctx.is_module_included_vec[module.id] = true; | ||
|
||
module.stmt_infos.iter_enumerated().for_each(|(stmt_info_id, stmt_info)| { | ||
if stmt_info.side_effect { | ||
include_statement(ctx, module, stmt_info_id); | ||
} | ||
}); | ||
|
||
module.import_records.iter().for_each(|import_record| { | ||
let importee = &ctx.modules[import_record.resolved_module]; | ||
if let Module::Normal(importee) = importee { | ||
include_module(ctx, importee); | ||
} | ||
}); | ||
} | ||
|
||
fn include_symbol(ctx: &mut Context, symbol_ref: SymbolRef) { | ||
let mut canonical_ref = ctx.symbols.par_canonical_ref_for(symbol_ref); | ||
let canonical_ref_module = &ctx.modules[canonical_ref.owner]; | ||
let canonical_ref_symbol = ctx.symbols.get(canonical_ref); | ||
if let Some(namespace_alias) = &canonical_ref_symbol.namespace_alias { | ||
canonical_ref = namespace_alias.namespace_ref; | ||
} | ||
let Module::Normal(canonical_ref_module) = canonical_ref_module else { | ||
return; | ||
}; | ||
include_module(ctx, canonical_ref_module); | ||
canonical_ref_module | ||
.stmt_infos | ||
.declared_stmts_by_symbol(&canonical_ref) | ||
.iter() | ||
.copied() | ||
.for_each(|stmt_info_id| { | ||
include_statement(ctx, canonical_ref_module, stmt_info_id); | ||
}); | ||
} | ||
|
||
fn include_statement(ctx: &mut Context, module: &NormalModule, stmt_info_id: StmtInfoId) { | ||
let is_included = &mut ctx.is_included_vec[module.id][stmt_info_id]; | ||
if *is_included { | ||
return; | ||
} | ||
|
||
// include the statement itself | ||
*is_included = true; | ||
|
||
let stmt_info = module.stmt_infos.get(stmt_info_id); | ||
|
||
// include statements that are referenced by this statement | ||
stmt_info.declared_symbols.iter().chain(stmt_info.referenced_symbols.iter()).for_each( | ||
|symbol_ref| { | ||
include_symbol(ctx, *symbol_ref); | ||
}, | ||
); | ||
} | ||
|
||
impl LinkStage { | ||
pub fn include_statements(&mut self) { | ||
use rayon::prelude::*; | ||
|
||
let mut is_included_vec: IndexVec<ModuleId, IndexVec<StmtInfoId, bool>> = self | ||
.modules | ||
.iter() | ||
.map(|m| match m { | ||
Module::Normal(m) => { | ||
m.stmt_infos.iter().map(|_| false).collect::<IndexVec<StmtInfoId, _>>() | ||
} | ||
Module::External(_) => IndexVec::default(), | ||
}) | ||
.collect::<IndexVec<ModuleId, _>>(); | ||
|
||
let mut is_module_included_vec: IndexVec<ModuleId, bool> = | ||
index_vec::index_vec![false; self.modules.len()]; | ||
|
||
let context = &mut Context { | ||
modules: &self.modules, | ||
symbols: &self.symbols, | ||
is_included_vec: &mut is_included_vec, | ||
is_module_included_vec: &mut is_module_included_vec, | ||
}; | ||
|
||
for module in &self.modules { | ||
match module { | ||
Module::Normal(module) => { | ||
let mut stmt_infos = module.stmt_infos.iter_enumerated(); | ||
// Skip the first one, because it's the namespace variable declaration. | ||
// We want to include it on demand. | ||
stmt_infos.next(); | ||
stmt_infos.for_each(|(stmt_info_id, stmt_info)| { | ||
if stmt_info.side_effect { | ||
include_statement(context, module, stmt_info_id); | ||
} | ||
}); | ||
if module.is_user_defined_entry { | ||
let linking_info = &self.linking_infos[module.id]; | ||
linking_info.resolved_exports.values().for_each(|resolved_export| { | ||
include_symbol(context, resolved_export.symbol_ref); | ||
}); | ||
} | ||
} | ||
Module::External(_) => {} | ||
} | ||
} | ||
|
||
self.entries.iter().for_each(|entry| { | ||
let module = &self.modules[entry.id]; | ||
let Module::Normal(module) = module else { | ||
return; | ||
}; | ||
|
||
include_module(context, module); | ||
|
||
let linking_info = &self.linking_infos[module.id]; | ||
linking_info.resolved_exports.values().for_each(|resolved_export| { | ||
include_symbol(context, resolved_export.symbol_ref); | ||
}); | ||
}); | ||
|
||
self.modules.iter_mut().par_bridge().for_each(|module| { | ||
let Module::Normal(module) = module else { | ||
return; | ||
}; | ||
module.is_included = is_module_included_vec[module.id]; | ||
is_included_vec[module.id].iter_enumerated().for_each(|(stmt_info_id, is_included)| { | ||
module.stmt_infos.get_mut(stmt_info_id).is_included = *is_included; | ||
}); | ||
}); | ||
} | ||
} |
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
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
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
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
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
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
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
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
Oops, something went wrong.