Skip to content

Commit 52d60b2

Browse files
committed
use EsmExport in FindExportFromReexportsResult
1 parent 6ae4a80 commit 52d60b2

File tree

1 file changed

+80
-41
lines changed
  • turbopack/crates/turbopack-ecmascript/src/references/esm

1 file changed

+80
-41
lines changed

turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs

Lines changed: 80 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::{borrow::Cow, collections::BTreeMap, ops::ControlFlow};
22

33
use anyhow::{Result, bail};
4+
use indexmap::map::Entry;
45
use rustc_hash::FxHashSet;
56
use serde::{Deserialize, Serialize};
67
use smallvec::{SmallVec, smallvec};
@@ -189,30 +190,44 @@ pub async fn follow_reexports(
189190
// Try to find the export in the star exports
190191
if !exports_ref.star_exports.is_empty() && &*export_name != "default" {
191192
let result = find_export_from_reexports(*module, export_name.clone()).await?;
192-
if let Some(m) = result.esm_export {
193-
module = m;
194-
continue;
195-
}
196-
return match &result.dynamic_exporting_modules[..] {
197-
[] => Ok(FollowExportsResult {
198-
module,
199-
export_name: Some(export_name),
200-
ty: FoundExportType::NotFound,
193+
match &*result {
194+
FindExportFromReexportsResult::NotFound => {
195+
return Ok(FollowExportsResult::cell(FollowExportsResult {
196+
module,
197+
export_name: Some(export_name),
198+
ty: FoundExportType::NotFound,
199+
}));
201200
}
202-
.cell()),
203-
[module] => Ok(FollowExportsResult {
204-
module: *module,
205-
export_name: Some(export_name),
206-
ty: FoundExportType::Dynamic,
201+
FindExportFromReexportsResult::EsmExport(esm_export) => {
202+
match handle_declared_export(module, export_name, esm_export).await? {
203+
ControlFlow::Continue((m, n)) => {
204+
module = m.to_resolved().await?;
205+
export_name = n;
206+
continue;
207+
}
208+
ControlFlow::Break(result) => {
209+
return Ok(result.cell());
210+
}
211+
}
207212
}
208-
.cell()),
209-
_ => Ok(FollowExportsResult {
210-
module,
211-
export_name: Some(export_name),
212-
ty: FoundExportType::Dynamic,
213+
FindExportFromReexportsResult::Dynamic(dynamic_exporting_modules) => {
214+
return match &dynamic_exporting_modules[..] {
215+
[] => unreachable!(),
216+
[module] => Ok(FollowExportsResult {
217+
module: *module,
218+
export_name: Some(export_name),
219+
ty: FoundExportType::Dynamic,
220+
}
221+
.cell()),
222+
_ => Ok(FollowExportsResult {
223+
module,
224+
export_name: Some(export_name),
225+
ty: FoundExportType::Dynamic,
226+
}
227+
.cell()),
228+
};
213229
}
214-
.cell()),
215-
};
230+
}
216231
}
217232

218233
return Ok(FollowExportsResult::cell(FollowExportsResult {
@@ -270,9 +285,10 @@ async fn handle_declared_export(
270285
}
271286

272287
#[turbo_tasks::value]
273-
struct FindExportFromReexportsResult {
274-
esm_export: Option<ResolvedVc<Box<dyn EcmascriptChunkPlaceable>>>,
275-
dynamic_exporting_modules: Vec<ResolvedVc<Box<dyn EcmascriptChunkPlaceable>>>,
288+
enum FindExportFromReexportsResult {
289+
NotFound,
290+
EsmExport(EsmExport),
291+
Dynamic(Vec<ResolvedVc<Box<dyn EcmascriptChunkPlaceable>>>),
276292
}
277293

278294
#[turbo_tasks::function]
@@ -301,17 +317,25 @@ async fn find_export_from_reexports(
301317
}
302318

303319
let all_export_names = get_all_export_names(*module).await?;
304-
let esm_export = all_export_names.esm_exports.get(&export_name).copied();
305-
Ok(FindExportFromReexportsResult {
306-
esm_export,
307-
dynamic_exporting_modules: all_export_names.dynamic_exporting_modules.clone(),
308-
}
309-
.cell())
320+
Ok(
321+
if let Some(esm_export) = all_export_names.esm_exports.get(&export_name) {
322+
FindExportFromReexportsResult::EsmExport(esm_export.clone())
323+
} else if all_export_names.dynamic_exporting_modules.is_empty() {
324+
FindExportFromReexportsResult::NotFound
325+
} else {
326+
FindExportFromReexportsResult::Dynamic(
327+
all_export_names.dynamic_exporting_modules.clone(),
328+
)
329+
}
330+
.cell(),
331+
)
310332
}
311333

312334
#[turbo_tasks::value]
313335
struct AllExportNamesResult {
314-
esm_exports: FxIndexMap<RcStr, ResolvedVc<Box<dyn EcmascriptChunkPlaceable>>>,
336+
/// A map from export name to the immediate referenced module.
337+
esm_exports: FxIndexMap<RcStr, EsmExport>,
338+
/// A list of all direct or indirectly referenced modules that are dynamically exporting
315339
dynamic_exporting_modules: Vec<ResolvedVc<Box<dyn EcmascriptChunkPlaceable>>>,
316340
}
317341

@@ -331,7 +355,12 @@ async fn get_all_export_names(
331355
let exports = exports.await?;
332356
let mut esm_exports = FxIndexMap::default();
333357
let mut dynamic_exporting_modules = Vec::new();
334-
esm_exports.extend(exports.exports.keys().cloned().map(|n| (n, module)));
358+
esm_exports.extend(
359+
exports
360+
.exports
361+
.iter()
362+
.map(|(name, esm_export)| (name.clone(), esm_export.clone())),
363+
);
335364
let star_export_names = exports
336365
.star_exports
337366
.iter()
@@ -340,7 +369,7 @@ async fn get_all_export_names(
340369
if let ReferencedAsset::Some(m) =
341370
*ReferencedAsset::from_resolve_result(esm_ref.resolve_reference()).await?
342371
{
343-
Some(expand_star_exports(*m))
372+
Some(expand_star_exports(**esm_ref, *m))
344373
} else {
345374
None
346375
},
@@ -354,7 +383,7 @@ async fn get_all_export_names(
354383
star_export_names
355384
.esm_exports
356385
.iter()
357-
.map(|(k, &v)| (k.clone(), v)),
386+
.map(|(k, v)| (k.clone(), v.clone())),
358387
);
359388
dynamic_exporting_modules
360389
.extend(star_export_names.dynamic_exporting_modules.iter().copied());
@@ -369,35 +398,45 @@ async fn get_all_export_names(
369398

370399
#[turbo_tasks::value]
371400
pub struct ExpandStarResult {
372-
pub esm_exports: FxIndexMap<RcStr, ResolvedVc<Box<dyn EcmascriptChunkPlaceable>>>,
401+
pub esm_exports: FxIndexMap<RcStr, EsmExport>,
373402
pub dynamic_exporting_modules: Vec<ResolvedVc<Box<dyn EcmascriptChunkPlaceable>>>,
374403
}
375404

376405
#[turbo_tasks::function]
377406
pub async fn expand_star_exports(
407+
root_reference: ResolvedVc<Box<dyn ModuleReference>>,
378408
root_module: ResolvedVc<Box<dyn EcmascriptChunkPlaceable>>,
379409
) -> Result<Vc<ExpandStarResult>> {
380410
let mut esm_exports = FxIndexMap::default();
381411
let mut dynamic_exporting_modules = Vec::new();
382412
let mut checked_modules = FxHashSet::default();
383413
checked_modules.insert(root_module);
384-
let mut queue = vec![(root_module, root_module.get_exports())];
385-
while let Some((asset, exports)) = queue.pop() {
414+
let mut queue = vec![(root_reference, root_module, root_module.get_exports())];
415+
while let Some((reference, asset, exports)) = queue.pop() {
386416
match &*exports.await? {
387417
EcmascriptExports::EsmExports(exports) => {
388418
let exports = exports.await?;
389-
for key in exports.exports.keys() {
419+
for (key, esm_export) in exports.exports.iter() {
390420
if key == "default" {
391421
continue;
392422
}
393-
esm_exports.entry(key.clone()).or_insert_with(|| asset);
423+
if let Entry::Vacant(entry) = esm_exports.entry(key.clone()) {
424+
entry.insert(match esm_export {
425+
&EsmExport::LocalBinding(_, mutable) => EsmExport::ImportedBinding(
426+
ResolvedVc::upcast(reference),
427+
key.clone(),
428+
mutable,
429+
),
430+
_ => esm_export.clone(),
431+
});
432+
}
394433
}
395434
for esm_ref in exports.star_exports.iter() {
396435
if let ReferencedAsset::Some(asset) =
397436
&*ReferencedAsset::from_resolve_result(esm_ref.resolve_reference()).await?
398437
&& checked_modules.insert(*asset)
399438
{
400-
queue.push((*asset, asset.get_exports()));
439+
queue.push((*esm_ref, *asset, asset.get_exports()));
401440
}
402441
}
403442
}
@@ -518,7 +557,7 @@ impl EsmExports {
518557
continue;
519558
};
520559

521-
let export_info = expand_star_exports(**asset).await?;
560+
let export_info = expand_star_exports(*esm_ref, **asset).await?;
522561

523562
for export in export_info.esm_exports.keys() {
524563
if export == "default" {

0 commit comments

Comments
 (0)