Skip to content

refactor: exports info setter #11051

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: refactor/remove-redirect-to
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions crates/rspack_binding_api/src/exports_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,12 @@ impl JsExportsInfo {
Either::A(str) => std::iter::once(str).map(Into::into).collect(),
Either::B(vec) => vec.into_iter().map(Into::into).collect(),
});
let exports_info = ExportsInfoGetter::prefetch_used_info_without_name(
let exports_info = ExportsInfoGetter::prefetch(
&self.exports_info,
&module_graph,
runtime.as_ref(),
false,
PrefetchExportsInfoMode::Default,
);
Ok(exports_info.is_used())
Ok(exports_info.is_used(runtime.as_ref()))
}

#[napi(ts_args_type = "runtime: string | string[] | undefined")]
Expand All @@ -62,13 +61,12 @@ impl JsExportsInfo {
Either::A(str) => std::iter::once(str).map(Into::into).collect(),
Either::B(vec) => vec.into_iter().map(Into::into).collect(),
});
let exports_info = ExportsInfoGetter::prefetch_used_info_without_name(
let exports_info = ExportsInfoGetter::prefetch(
&self.exports_info,
&module_graph,
runtime.as_ref(),
false,
PrefetchExportsInfoMode::Default,
);
Ok(exports_info.is_module_used())
Ok(exports_info.is_module_used(runtime.as_ref()))
}

#[napi(ts_args_type = "runtime: string | string[] | undefined")]
Expand All @@ -81,7 +79,8 @@ impl JsExportsInfo {
Ok(
self
.exports_info
.set_used_in_unknown_way(&mut module_graph, runtime.as_ref()),
.as_data_mut(&mut module_graph)
.set_used_in_unknown_way(runtime.as_ref()),
)
}

Expand Down
5 changes: 4 additions & 1 deletion crates/rspack_binding_api/src/module_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,10 @@ impl JsModuleGraph {
#[napi(ts_args_type = "module: Module")]
pub fn get_exports_info(&self, module: ModuleObjectRef) -> napi::Result<JsExportsInfo> {
let (compilation, module_graph) = self.as_ref()?;
let exports_info = module_graph.get_exports_info(&module.identifier);
let exports_info = module_graph
.module_graph_module_by_identifier(&module.identifier)
.expect("should have mgm")
.exports;
Ok(JsExportsInfo::new(exports_info, compilation))
}

Expand Down
27 changes: 8 additions & 19 deletions crates/rspack_core/src/concatenated_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ use crate::{
CodeGenerationDataTopLevelDeclarations, CodeGenerationExportsFinalNames,
CodeGenerationPublicPathAutoReplace, CodeGenerationResult, Compilation, ConcatenatedModuleIdent,
ConcatenationScope, ConditionalInitFragment, ConnectionState, Context, DependenciesBlock,
DependencyId, DependencyType, ErrorSpan, ExportProvided, ExportsArgument, ExportsInfoGetter,
ExportsType, FactoryMeta, GetUsedNameParam, IdentCollector, InitFragment, InitFragmentStage,
LibIdentOptions, MaybeDynamicTargetExportInfoHashKey, Module, ModuleArgument, ModuleGraph,
DependencyId, DependencyType, ErrorSpan, ExportProvided, ExportsArgument, ExportsType,
FactoryMeta, IdentCollector, InitFragment, InitFragmentStage, LibIdentOptions,
MaybeDynamicTargetExportInfoHashKey, Module, ModuleArgument, ModuleGraph,
ModuleGraphCacheArtifact, ModuleGraphConnection, ModuleIdentifier, ModuleLayer,
ModuleStaticCacheArtifact, ModuleType, PrefetchExportsInfoMode, Resolve, RuntimeCondition,
RuntimeGlobals, RuntimeSpec, SourceType, SpanExt, UsageState, UsedName, UsedNameItem,
Expand Down Expand Up @@ -2425,11 +2425,7 @@ impl ConcatenatedModule {
if let Some(ref export_id) = export_id
&& let Some(direct_export) = info.export_map.as_ref().and_then(|map| map.get(export_id))
{
if let Some(used_name) = ExportsInfoGetter::get_used_name(
GetUsedNameParam::WithNames(&exports_info),
runtime,
&export_name,
) {
if let Some(used_name) = exports_info.get_used_name(runtime, &export_name) {
match used_name {
UsedName::Normal(used_name) => {
// https://github.com/webpack/webpack/blob/1f99ad6367f2b8a6ef17cce0e058f7a67fb7db18/lib/optimize/ConcatenatedModule.js#L402-L404
Expand Down Expand Up @@ -2527,12 +2523,9 @@ impl ConcatenatedModule {

if info.namespace_export_symbol.is_some() {
// That's how webpack write https://github.com/webpack/webpack/blob/1f99ad6367f2b8a6ef17cce0e058f7a67fb7db18/lib/optimize/ConcatenatedModule.js#L463-L471
let used_name = ExportsInfoGetter::get_used_name(
GetUsedNameParam::WithNames(&exports_info),
runtime,
&export_name,
)
.expect("should have export name");
let used_name = exports_info
.get_used_name(runtime, &export_name)
.expect("should have export name");
return FinalBindingResult::from_binding(match used_name {
UsedName::Normal(used_name) => Binding::Raw(RawBinding {
info_id: info.module,
Expand Down Expand Up @@ -2565,11 +2558,7 @@ impl ConcatenatedModule {
);
}
ModuleInfo::External(info) => {
let binding = if let Some(used_name) = ExportsInfoGetter::get_used_name(
GetUsedNameParam::WithNames(&exports_info),
runtime,
&export_name,
) {
let binding = if let Some(used_name) = exports_info.get_used_name(runtime, &export_name) {
match used_name {
UsedName::Normal(used_name) => {
let comment = if used_name == export_name {
Expand Down
22 changes: 11 additions & 11 deletions crates/rspack_core/src/dependency/runtime_template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ use swc_core::ecma::atoms::Atom;
use crate::{
compile_boolean_matcher_from_lists, contextify, property_access, to_comment, to_normal_comment,
AsyncDependenciesBlockIdentifier, ChunkGraph, Compilation, CompilerOptions, DependenciesBlock,
DependencyId, Environment, ExportsArgument, ExportsInfoGetter, ExportsType,
FakeNamespaceObjectMode, GetUsedNameParam, InitFragmentExt, InitFragmentKey, InitFragmentStage,
Module, ModuleGraph, ModuleGraphCacheArtifact, ModuleId, ModuleIdentifier, NormalInitFragment,
PathInfo, PrefetchExportsInfoMode, RuntimeCondition, RuntimeGlobals, RuntimeSpec,
TemplateContext, UsedName,
DependencyId, Environment, ExportsArgument, ExportsType, FakeNamespaceObjectMode,
InitFragmentExt, InitFragmentKey, InitFragmentStage, Module, ModuleGraph,
ModuleGraphCacheArtifact, ModuleId, ModuleIdentifier, NormalInitFragment, PathInfo,
PrefetchExportsInfoMode, RuntimeCondition, RuntimeGlobals, RuntimeSpec, TemplateContext,
UsedName,
};

pub fn runtime_condition_expression(
Expand Down Expand Up @@ -214,14 +214,14 @@ pub fn export_from_import(
.as_deref()
.unwrap_or(export_name);
if !export_name.is_empty() {
let used_name = match ExportsInfoGetter::get_used_name(
GetUsedNameParam::WithNames(&compilation.get_module_graph().get_prefetched_exports_info(
let used_name = match compilation
.get_module_graph()
.get_prefetched_exports_info(
&module_identifier,
PrefetchExportsInfoMode::Nested(export_name),
)),
*runtime,
export_name,
) {
)
.get_used_name(*runtime, export_name)
{
Some(UsedName::Normal(used_name)) => used_name,
Some(UsedName::Inlined(inlined)) => {
return format!(
Expand Down
200 changes: 2 additions & 198 deletions crates/rspack_core/src/exports/exports_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ use std::{collections::BTreeMap, hash::Hash, sync::atomic::Ordering::Relaxed};
use rspack_cacheable::cacheable;
use rspack_collections::{impl_item_ukey, Ukey};
use rspack_util::atom::Atom;
use rustc_hash::FxHashSet;
use serde::Serialize;

use super::{ExportInfo, ExportInfoData, ExportProvided, UsageState, NEXT_EXPORTS_INFO_UKEY};
use crate::{DependencyId, ModuleGraph, Nullable, RuntimeSpec};
use super::{ExportInfoData, NEXT_EXPORTS_INFO_UKEY};
use crate::ModuleGraph;

#[cacheable]
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize)]
Expand All @@ -28,201 +27,6 @@ impl ExportsInfo {
pub fn as_data_mut<'a>(&self, mg: &'a mut ModuleGraph) -> &'a mut ExportsInfoData {
mg.get_exports_info_mut_by_id(self)
}

// TODO: remove this, we should refactor ExportInfo into ExportName and ExportProvideInfo and ExportUsedInfo
// ExportProvideInfo is created by FlagDependencyExportsPlugin, and should not mutate after create
// ExportUsedInfo is created by FlagDependencyUsagePlugin or Plugin::finish_modules, and should not mutate after create
pub fn reset_provide_info(&self, mg: &mut ModuleGraph) {
let exports_info = self.as_data_mut(mg);
for export_info in exports_info.exports_mut().values_mut() {
export_info.reset_provide_info();
}
exports_info
.side_effects_only_info_mut()
.reset_provide_info();
exports_info.other_exports_info_mut().reset_provide_info();
}

/// # Panic
/// it will panic if you provide a export info that does not exists in the module graph
pub fn set_has_provide_info(&self, mg: &mut ModuleGraph) {
let exports_info = self.as_data_mut(mg);

for export_info in exports_info.exports_mut().values_mut() {
if export_info.provided().is_none() {
export_info.set_provided(Some(ExportProvided::NotProvided));
}
if export_info.can_mangle_provide().is_none() {
export_info.set_can_mangle_provide(Some(true));
}
}
let other_exports_info = exports_info.other_exports_info_mut();
if other_exports_info.provided().is_none() {
other_exports_info.set_provided(Some(ExportProvided::NotProvided));
}
if other_exports_info.can_mangle_provide().is_none() {
other_exports_info.set_can_mangle_provide(Some(true));
}
}

pub fn set_unknown_exports_provided(
&self,
mg: &mut ModuleGraph,
can_mangle: bool,
exclude_exports: Option<&FxHashSet<Atom>>,
target_key: Option<DependencyId>,
target_module: Option<DependencyId>,
priority: Option<u8>,
) -> bool {
let mut changed = false;

if let Some(exclude_exports) = &exclude_exports {
for name in exclude_exports.iter() {
self.get_export_info(mg, name);
}
}

let exports_info = self.as_data_mut(mg);
for export_info in exports_info.exports_mut().values_mut() {
if !can_mangle && export_info.can_mangle_provide() != Some(false) {
export_info.set_can_mangle_provide(Some(false));
changed = true;
}
if let Some(exclude_exports) = &exclude_exports {
if let Some(export_name) = export_info.name()
&& exclude_exports.contains(export_name)
{
continue;
}
}
if !matches!(
export_info.provided(),
Some(ExportProvided::Provided | ExportProvided::Unknown)
) {
export_info.set_provided(Some(ExportProvided::Unknown));
changed = true;
}
if let Some(target_key) = target_key {
let name = export_info
.name()
.map(|name| Nullable::Value(vec![name.clone()]));
export_info.set_target(Some(target_key), target_module, name.as_ref(), priority);
}
}

let other_exports_info_data = exports_info.other_exports_info_mut();
if !matches!(
other_exports_info_data.provided(),
Some(ExportProvided::Provided | ExportProvided::Unknown)
) {
other_exports_info_data.set_provided(Some(ExportProvided::Unknown));
changed = true;
}

if let Some(target_key) = target_key {
other_exports_info_data.set_target(Some(target_key), target_module, None, priority);
}

if !can_mangle && other_exports_info_data.can_mangle_provide() != Some(false) {
other_exports_info_data.set_can_mangle_provide(Some(false));
changed = true;
}

changed
}

pub fn get_export_info(&self, mg: &mut ModuleGraph, name: &Atom) -> ExportInfo {
let exports_info = self.as_data_mut(mg);
if let Some(export_info) = exports_info.named_exports(name) {
return export_info.id();
}

let other_export_info = exports_info.other_exports_info();
let new_info = ExportInfoData::new(*self, Some(name.clone()), Some(other_export_info));
let new_info_id = new_info.id();
exports_info.exports_mut().insert(name.clone(), new_info);
new_info_id
}

pub fn set_has_use_info(&self, mg: &mut ModuleGraph) {
let mut nested_exports_info = vec![];
let exports_info = self.as_data_mut(mg);
for export_info in exports_info.exports_mut().values_mut() {
export_info.set_has_use_info(&mut nested_exports_info);
}
exports_info
.side_effects_only_info_mut()
.set_has_use_info(&mut nested_exports_info);
let other_exports_info = exports_info.other_exports_info_mut();
other_exports_info.set_has_use_info(&mut nested_exports_info);
if other_exports_info.can_mangle_use().is_none() {
other_exports_info.set_can_mangle_use(Some(true));
}

for nested_exports_info in nested_exports_info {
nested_exports_info.set_has_use_info(mg);
}
}

pub fn set_used_without_info(&self, mg: &mut ModuleGraph, runtime: Option<&RuntimeSpec>) -> bool {
let mut changed = false;
let exports_info = self.as_data_mut(mg);
for export_info in exports_info.exports_mut().values_mut() {
let flag = export_info.set_used_without_info(runtime);
changed |= flag;
}
let other_exports_info = exports_info.other_exports_info_mut();
let flag = other_exports_info.set_used(UsageState::NoInfo, None);
changed |= flag;
if other_exports_info.can_mangle_use() != Some(false) {
other_exports_info.set_can_mangle_use(Some(false));
changed = true;
}
changed
}

pub fn set_all_known_exports_used(
&self,
mg: &mut ModuleGraph,
runtime: Option<&RuntimeSpec>,
) -> bool {
let mut changed = false;
let exports_info = self.as_data_mut(mg);
for export_info in exports_info.exports_mut().values_mut() {
if !matches!(export_info.provided(), Some(ExportProvided::Provided)) {
continue;
}
changed |= export_info.set_used(UsageState::Used, runtime);
}
changed
}

pub fn set_used_in_unknown_way(
&self,
mg: &mut ModuleGraph,
runtime: Option<&RuntimeSpec>,
) -> bool {
let mut changed = false;
let exports_info = self.as_data_mut(mg);
for export_info in exports_info.exports_mut().values_mut() {
if export_info.set_used_in_unknown_way(runtime) {
changed = true;
}
}
let other_exports_info = exports_info.other_exports_info_mut();
if other_exports_info.set_used_conditionally(
Box::new(|value| value < &UsageState::Unknown),
UsageState::Unknown,
runtime,
) {
changed = true;
}
if other_exports_info.can_mangle_use() != Some(false) {
other_exports_info.set_can_mangle_use(Some(false));
changed = true;
}
changed
}
}

#[derive(Debug, Clone)]
Expand Down
Loading
Loading