Skip to content

Commit 2604351

Browse files
committed
Consume new vargraph data to set liveness
1 parent 238e3d7 commit 2604351

File tree

58 files changed

+1621
-37
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+1621
-37
lines changed

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ async fn get_all_export_names(
387387
star_export_names
388388
.esm_exports
389389
.iter()
390-
.map(|(k, &v)| (k.clone(), v)),
390+
.map(|(k, (_liveness, v))| (k.clone(), *v)),
391391
);
392392
dynamic_exporting_modules
393393
.extend(star_export_names.dynamic_exporting_modules.iter().copied());
@@ -402,7 +402,7 @@ async fn get_all_export_names(
402402

403403
#[turbo_tasks::value]
404404
pub struct ExpandStarResult {
405-
pub esm_exports: FxIndexMap<RcStr, ResolvedVc<Box<dyn EcmascriptChunkPlaceable>>>,
405+
pub esm_exports: FxIndexMap<RcStr, (Liveness, ResolvedVc<Box<dyn EcmascriptChunkPlaceable>>)>,
406406
pub dynamic_exporting_modules: Vec<ResolvedVc<Box<dyn EcmascriptChunkPlaceable>>>,
407407
}
408408

@@ -419,11 +419,13 @@ pub async fn expand_star_exports(
419419
match &*exports.await? {
420420
EcmascriptExports::EsmExports(exports) => {
421421
let exports = exports.await?;
422-
for key in exports.exports.keys() {
422+
for (key, export) in exports.exports.iter() {
423423
if key == "default" {
424424
continue;
425425
}
426-
esm_exports.entry(key.clone()).or_insert_with(|| asset);
426+
esm_exports
427+
.entry(key.clone())
428+
.or_insert_with(|| (export.liveness(), asset));
427429
}
428430
for esm_ref in exports.star_exports.iter() {
429431
if let ReferencedAsset::Some(asset) =

turbopack/crates/turbopack-ecmascript/src/references/mod.rs

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -782,8 +782,12 @@ pub(crate) async fn analyse_ecmascript_module_internal(
782782
let (webpack_runtime, webpack_entry, webpack_chunks, mut esm_exports) =
783783
set_handler_and_globals(&handler, globals, || {
784784
// TODO migrate to effects
785-
let mut visitor =
786-
ModuleReferencesVisitor::new(eval_context, &import_references, &mut analysis);
785+
let mut visitor = ModuleReferencesVisitor::new(
786+
eval_context,
787+
&import_references,
788+
&mut analysis,
789+
&var_graph,
790+
);
787791
// ModuleReferencesVisitor has already called analysis.add_esm_reexport_reference
788792
// for any references in esm_exports
789793
program.visit_with_ast_path(&mut visitor, &mut Default::default());
@@ -3200,13 +3204,15 @@ struct ModuleReferencesVisitor<'a> {
32003204
webpack_runtime: Option<(RcStr, Span)>,
32013205
webpack_entry: bool,
32023206
webpack_chunks: Vec<Lit>,
3207+
var_graph: &'a VarGraph,
32033208
}
32043209

32053210
impl<'a> ModuleReferencesVisitor<'a> {
32063211
fn new(
32073212
eval_context: &'a EvalContext,
32083213
import_references: &'a [ResolvedVc<EsmAssetReference>],
32093214
analysis: &'a mut AnalyzeEcmascriptModuleResultBuilder,
3215+
var_graph: &'a VarGraph,
32103216
) -> Self {
32113217
Self {
32123218
eval_context,
@@ -3217,6 +3223,7 @@ impl<'a> ModuleReferencesVisitor<'a> {
32173223
webpack_runtime: None,
32183224
webpack_entry: false,
32193225
webpack_chunks: Vec::new(),
3226+
var_graph,
32203227
}
32213228
}
32223229
}
@@ -3225,10 +3232,10 @@ fn as_parent_path(ast_path: &AstNodePath<AstParentNodeRef<'_>>) -> Vec<AstParent
32253232
ast_path.iter().map(|n| n.kind()).collect()
32263233
}
32273234

3228-
fn for_each_ident_in_pat(pat: &Pat, f: &mut impl FnMut(RcStr)) {
3235+
fn for_each_ident_in_pat(pat: &Pat, f: &mut impl FnMut(&Ident)) {
32293236
match pat {
32303237
Pat::Ident(BindingIdent { id, .. }) => {
3231-
f(id.sym.as_str().into());
3238+
f(id);
32323239
}
32333240
Pat::Array(ArrayPat { elems, .. }) => elems.iter().for_each(|e| {
32343241
if let Some(e) = e {
@@ -3244,7 +3251,7 @@ fn for_each_ident_in_pat(pat: &Pat, f: &mut impl FnMut(RcStr)) {
32443251
for_each_ident_in_pat(value, f);
32453252
}
32463253
ObjectPatProp::Assign(AssignPatProp { key, .. }) => {
3247-
f(key.sym.as_str().into());
3254+
f(&key.id);
32483255
}
32493256
ObjectPatProp::Rest(RestPat { arg, .. }) => {
32503257
for_each_ident_in_pat(arg, f);
@@ -3283,6 +3290,7 @@ impl VisitAstPath for ModuleReferencesVisitor<'_> {
32833290
.map(find_turbopack_part_id_in_asserts)
32843291
.is_some();
32853292

3293+
// This is for a statement like `export {a, b as c}` with no `from` clause.
32863294
if export.src.is_none() {
32873295
for spec in export.specifiers.iter() {
32883296
fn to_rcstr(name: &ModuleExportName) -> RcStr {
@@ -3361,30 +3369,27 @@ impl VisitAstPath for ModuleReferencesVisitor<'_> {
33613369
) {
33623370
{
33633371
let decl: &Decl = &export.decl;
3364-
let insert_export_binding = &mut |name: RcStr, liveness: Liveness| {
3372+
let insert_export_binding = &mut |id: &Ident| {
3373+
let liveness = if self.is_export_ident_live(id) {
3374+
Liveness::Live
3375+
} else {
3376+
Liveness::Constant
3377+
};
3378+
let name: RcStr = id.sym.as_str().into();
33653379
self.esm_exports
33663380
.insert(name.clone(), EsmExport::LocalBinding(name, liveness));
33673381
};
33683382
match decl {
33693383
Decl::Class(ClassDecl { ident, .. }) | Decl::Fn(FnDecl { ident, .. }) => {
3370-
// TODO: examine whether the value is ever mutated rather than just checking
3371-
// 'const'
3372-
insert_export_binding(ident.sym.as_str().into(), Liveness::Live);
3384+
insert_export_binding(ident);
33733385
}
33743386
Decl::Var(var_decl) => {
3375-
// TODO: examine whether the value is ever mutated rather than just checking
3376-
// 'const'
3377-
let liveness = match var_decl.kind {
3378-
VarDeclKind::Var => Liveness::Live,
3379-
VarDeclKind::Let => Liveness::Live,
3380-
VarDeclKind::Const => Liveness::Constant,
3381-
};
3382-
let decls = &*var_decl.decls;
3383-
decls.iter().for_each(|VarDeclarator { name, .. }| {
3384-
for_each_ident_in_pat(name, &mut |name| {
3385-
insert_export_binding(name, liveness)
3386-
})
3387-
});
3387+
var_decl
3388+
.decls
3389+
.iter()
3390+
.for_each(|VarDeclarator { name, .. }| {
3391+
for_each_ident_in_pat(name, insert_export_binding);
3392+
});
33883393
}
33893394
Decl::Using(_) => {
33903395
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export#:~:text=You%20cannot%20use%20export%20on%20a%20using%20or%20await%20using%20declaration
@@ -3428,17 +3433,22 @@ impl VisitAstPath for ModuleReferencesVisitor<'_> {
34283433
) {
34293434
match &export.decl {
34303435
DefaultDecl::Class(ClassExpr { ident, .. }) | DefaultDecl::Fn(FnExpr { ident, .. }) => {
3431-
self.esm_exports.insert(
3432-
rcstr!("default"),
3433-
EsmExport::LocalBinding(
3434-
ident
3435-
.as_ref()
3436-
.map(|i| i.sym.as_str().into())
3437-
.unwrap_or_else(|| magic_identifier::mangle("default export").into()),
3438-
// Default export expressions cannot be mutated
3436+
let export = match ident {
3437+
Some(ident) => EsmExport::LocalBinding(
3438+
ident.sym.as_str().into(),
3439+
if self.is_export_ident_live(ident) {
3440+
Liveness::Live
3441+
} else {
3442+
Liveness::Constant
3443+
},
3444+
),
3445+
// If there is no name, like `export default function(){}` then it is not live.
3446+
None => EsmExport::LocalBinding(
3447+
magic_identifier::mangle("default export").into(),
34393448
Liveness::Constant,
34403449
),
3441-
);
3450+
};
3451+
self.esm_exports.insert(rcstr!("default"), export);
34423452
}
34433453
DefaultDecl::TsInterfaceDecl(..) => {
34443454
// ignore
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
error - [transform] /turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/index.js Error evaluating Node.js code
2+
3+
Error: Cannot find module './side-effects/reexport-internal.js'
4+
[at WORKSPACE_ROOT/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/output/40cd4_turbopack_async-modules_async-reexport-side-effects-split_input_eae6bde3._.js:6:15]
5+
[at {module evaluation} (WORKSPACE_ROOT/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/output/40cd4_turbopack_async-modules_async-reexport-side-effects-split_input_eae6bde3._.js:9:3)]
6+
at instantiateModule (turbopack:///[turbopack]/nodejs/runtime.ts:228:5) [WORKSPACE_ROOT/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/output/[turbopack]_runtime.js:713:9]
7+
at getOrInstantiateModuleFromParent (turbopack:///[turbopack]/nodejs/runtime.ts:261:10) [WORKSPACE_ROOT/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/output/[turbopack]_runtime.js:736:12]
8+
at Context.esmImport [as i] (turbopack:///[turbopack]/shared/runtime-utils.ts:347:18) [WORKSPACE_ROOT/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/output/[turbopack]_runtime.js:228:20]
9+
at <unknown> (turbopack/crates/turbopack-tests/js/jest-entry.ts:68:1) [WORKSPACE_ROOT/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/output/[root-of-the-server]__4a7dfbc1._.js:85:16]
10+
64 | jestResult,
11+
65 | uncaughtExceptions,
12+
66 | unhandledRejections,
13+
67 | }
14+
| v
15+
68 + }
16+
| ^
17+
69 |
18+
19+
[at process.processTicksAndRejections (node:internal/process/task_queues:95:5)]
20+
at async run (turbopack/crates/turbopack-tests/js/jest-entry.ts:40:3) [WORKSPACE_ROOT/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/output/[root-of-the-server]__4a7dfbc1._.js:49:5]
21+
36 |
22+
37 | export default async function run() {
23+
38 | setupGlobals()
24+
39 |
25+
| v
26+
40 + await import('TESTS')
27+
| ^
28+
41 |
29+
42 | let jestResult = await jest.run()
30+
43 | // Jest test results can contain references to arbitrary objects.
31+
44 | // Defensively remove circular references to avoid breaking our serialization protocol.
32+
33+
at async run (turbopack:///[turbopack-node]/ipc/evaluate.ts:92:23) [WORKSPACE_ROOT/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/output/[turbopack-node]__0ef06507._.js:407:31]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
error - [resolve] /turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effects/reexport-internal-test.js:1:0 Module not found: Can't resolve './reexport-internal.js'
2+
3+
+ v----------------------------------------------v
4+
1 + import { a, b, c } from './reexport-internal.js'
5+
+ ^----------------------------------------------^
6+
2 |
7+
3 | export default {
8+
4 | a,
9+
5 | b,
10+
11+
all exported names should be analyzed
12+
13+
Debug info:
14+
- Execution of <ModuleAssetContext as AssetContext>::process_resolve_result failed
15+
- Execution of apply_module_type failed
16+
- Execution of *EcmascriptExports::split_locals_and_reexports failed
17+
- Execution of <EcmascriptModuleAsset as EcmascriptChunkPlaceable>::get_exports failed
18+
- Execution of analyse_ecmascript_module failed
19+
- all exported names should be analyzed
20+
21+
22+
| An error happened during resolving.
23+
| Parsed request as written in source code: relative './reexport-internal.js'
24+
| Path where resolving has started: [project]/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effects/reexport-internal-test.js
25+
| Type of request: EcmaScript Modules (part) request
26+
|
27+
Import trace:
28+
test:
29+
./turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effects/reexport-internal-test.js
30+
./turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/index.js
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
error - [resolve] /turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/index.js:11:4 Module not found: Can't resolve './side-effect-free/reexport-internal.js'
2+
3+
7 | (await import('./side-effects/reexport-internal-test.js')).default,
4+
8 | 'async module with side effects via require': () =>
5+
9 | require('./side-effects/reexport-internal.js'),
6+
10 | 'async module flagged side-effect-free via dynamic import': () =>
7+
+ v-----------------------------------------------v
8+
11 + import('./side-effect-free/reexport-internal.js'),
9+
+ ^-----------------------------------------------^
10+
12 | 'async module flagged side-effect-free via esm import': async () =>
11+
13 | (await import('./side-effect-free/reexport-internal-test.js')).default,
12+
14 | 'async module flagged side-effect-free via require': () =>
13+
15 | require('./side-effect-free/reexport-internal.js'),
14+
15+
all exported names should be analyzed
16+
17+
Debug info:
18+
- Execution of <ModuleAssetContext as AssetContext>::process_resolve_result failed
19+
- Execution of apply_module_type failed
20+
- Execution of *EcmascriptExports::split_locals_and_reexports failed
21+
- Execution of <EcmascriptModuleAsset as EcmascriptChunkPlaceable>::get_exports failed
22+
- Execution of analyse_ecmascript_module failed
23+
- all exported names should be analyzed
24+
25+
26+
| An error happened during resolving.
27+
| Parsed request as written in source code: relative './side-effect-free/reexport-internal.js'
28+
| Path where resolving has started: [project]/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/index.js
29+
| Type of request: EcmaScript Modules request
30+
|
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
error - [resolve] /turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effects/reexport-external-test.js:1:0 Module not found: Can't resolve './reexport-external.js'
2+
3+
+ v----------------------------------------------v
4+
1 + import { a, b, c } from './reexport-external.js'
5+
+ ^----------------------------------------------^
6+
2 |
7+
3 | export default {
8+
4 | a,
9+
5 | b,
10+
11+
all exported names should be analyzed
12+
13+
Debug info:
14+
- Execution of <ModuleAssetContext as AssetContext>::process_resolve_result failed
15+
- Execution of apply_module_type failed
16+
- Execution of *EcmascriptExports::split_locals_and_reexports failed
17+
- Execution of <EcmascriptModuleAsset as EcmascriptChunkPlaceable>::get_exports failed
18+
- Execution of analyse_ecmascript_module failed
19+
- all exported names should be analyzed
20+
21+
22+
| An error happened during resolving.
23+
| Parsed request as written in source code: relative './reexport-external.js'
24+
| Path where resolving has started: [project]/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effects/reexport-external-test.js
25+
| Type of request: EcmaScript Modules (part) request
26+
|
27+
Import trace:
28+
test:
29+
./turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effects/reexport-external-test.js
30+
./turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/index.js
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
error - [resolve] /turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/index.js:15:4 Module not found: Can't resolve './side-effect-free/reexport-internal.js'
2+
3+
11 | import('./side-effect-free/reexport-internal.js'),
4+
12 | 'async module flagged side-effect-free via esm import': async () =>
5+
13 | (await import('./side-effect-free/reexport-internal-test.js')).default,
6+
14 | 'async module flagged side-effect-free via require': () =>
7+
+ v------------------------------------------------v
8+
15 + require('./side-effect-free/reexport-internal.js'),
9+
+ ^------------------------------------------------^
10+
16 | 'module with externals with side effects via dynamic import': () =>
11+
17 | import('./side-effects/reexport-external.js'),
12+
18 | 'module with externals with side effects via esm import': async () =>
13+
19 | (await import('./side-effects/reexport-external-test.js')).default,
14+
15+
all exported names should be analyzed
16+
17+
Debug info:
18+
- Execution of <ModuleAssetContext as AssetContext>::process_resolve_result failed
19+
- Execution of apply_module_type failed
20+
- Execution of *EcmascriptExports::split_locals_and_reexports failed
21+
- Execution of <EcmascriptModuleAsset as EcmascriptChunkPlaceable>::get_exports failed
22+
- Execution of analyse_ecmascript_module failed
23+
- all exported names should be analyzed
24+
25+
26+
| An error happened during resolving.
27+
| Parsed request as written in source code: relative './side-effect-free/reexport-internal.js'
28+
| Path where resolving has started: [project]/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/index.js
29+
| Type of request: commonjs request
30+
|
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
error - [resolve] /turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/index.js:5:4 Module not found: Can't resolve './side-effects/reexport-internal.js'
2+
3+
1 | import { a as a1, b as b1, c as c1 } from './side-effects/reexport-internal.js'
4+
2 |
5+
3 | const cases = {
6+
4 | 'async module with side effects via dynamic import': () =>
7+
+ v-------------------------------------------v
8+
5 + import('./side-effects/reexport-internal.js'),
9+
+ ^-------------------------------------------^
10+
6 | 'async module with side effects via esm import': async () =>
11+
7 | (await import('./side-effects/reexport-internal-test.js')).default,
12+
8 | 'async module with side effects via require': () =>
13+
9 | require('./side-effects/reexport-internal.js'),
14+
15+
all exported names should be analyzed
16+
17+
Debug info:
18+
- Execution of <ModuleAssetContext as AssetContext>::process_resolve_result failed
19+
- Execution of apply_module_type failed
20+
- Execution of *EcmascriptExports::split_locals_and_reexports failed
21+
- Execution of <EcmascriptModuleAsset as EcmascriptChunkPlaceable>::get_exports failed
22+
- Execution of analyse_ecmascript_module failed
23+
- all exported names should be analyzed
24+
25+
26+
| An error happened during resolving.
27+
| Parsed request as written in source code: relative './side-effects/reexport-internal.js'
28+
| Path where resolving has started: [project]/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/index.js
29+
| Type of request: EcmaScript Modules request
30+
|

0 commit comments

Comments
 (0)