Skip to content
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

fix(turbopack): Fix edge cases of tree shaking #7986

Draft
wants to merge 309 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
309 commits
Select commit Hold shift + click to select a range
3b1ba2c
Update test refs
kdy1 Apr 22, 2024
22584f9
Use correct local for reexports
kdy1 Apr 23, 2024
fc1e8df
fixup for namespace
kdy1 Apr 23, 2024
61233a2
move
kdy1 Apr 23, 2024
df7d279
Fix graph for reexports
kdy1 Apr 23, 2024
60e452d
GLOBALS
kdy1 Apr 23, 2024
e11a7db
Fix graph
kdy1 Apr 23, 2024
353d9cd
fixup
kdy1 Apr 23, 2024
ad03ded
Allow renamed reexports
kdy1 Apr 23, 2024
723973c
Rename export
kdy1 Apr 23, 2024
606279b
Rename
kdy1 Apr 23, 2024
cdee93b
Add a test
kdy1 Apr 23, 2024
514d3a4
IdentUsageCollector: Export
kdy1 Apr 23, 2024
8d26668
Item for reexports
kdy1 Apr 23, 2024
adcd226
Default
kdy1 Apr 23, 2024
803ffd9
Update test refs
kdy1 Apr 23, 2024
3cd3280
Remove Item for reexports
kdy1 Apr 23, 2024
f5f7ad6
Update test refs
kdy1 Apr 23, 2024
e5600ef
`export` field
kdy1 Apr 23, 2024
e1ec7dc
Update test refs
kdy1 Apr 23, 2024
82d4782
type
kdy1 Apr 23, 2024
dde7ead
fix name
kdy1 Apr 23, 2024
a39f580
Update test refs
kdy1 Apr 23, 2024
6c93818
Reduce input
kdy1 Apr 23, 2024
3364d31
Print log
kdy1 Apr 23, 2024
9c3e732
dbg
kdy1 Apr 24, 2024
c1e95ae
Two fields
kdy1 Apr 24, 2024
3bdab32
Update test refs
kdy1 Apr 24, 2024
050c58a
Update test refs
kdy1 Apr 24, 2024
ea57fdc
import * as
kdy1 Apr 24, 2024
0a5813f
Update test refs
kdy1 Apr 24, 2024
29b966c
move
kdy1 Apr 24, 2024
bd51d73
Remove logging
kdy1 Apr 24, 2024
9831713
review
kdy1 Apr 24, 2024
435dd2d
Update test refs
kdy1 Apr 24, 2024
bfe4a54
clippy
kdy1 Apr 24, 2024
2e81617
facade => None
kdy1 Apr 24, 2024
88b23a2
add test case
sokra Apr 25, 2024
1687143
fix test case
sokra Apr 25, 2024
c86da53
Remove wrong
kdy1 Apr 26, 2024
ba1f7cc
Fix
kdy1 Apr 26, 2024
678b20a
Update test refs
kdy1 Apr 26, 2024
71ba460
fix mermaid escape
kdy1 Apr 26, 2024
158daa4
Update test refs
kdy1 Apr 26, 2024
3d02b7b
impl EvaluatableAsset for EcmascriptModulePartAsset
kdy1 Apr 26, 2024
9b03c5b
Improve assertion
kdy1 Apr 26, 2024
04133e5
split_module: Handle no-dep
kdy1 Apr 26, 2024
df377ee
magic_identifier::mangle
kdy1 Apr 26, 2024
2ea406a
reexport vs export
kdy1 Apr 26, 2024
a373272
Add a debug assertion
kdy1 Apr 26, 2024
52bdc45
WIP: `default`
kdy1 Apr 26, 2024
eb48c0f
Update test refs
kdy1 Apr 26, 2024
708a09e
default exports
kdy1 Apr 26, 2024
b18cdae
Remove dbg
kdy1 Apr 26, 2024
485cc93
Add assertion
kdy1 Apr 26, 2024
b6a3de7
`get_var`
kdy1 Apr 26, 2024
1cf1810
`globalThis`
kdy1 Apr 26, 2024
aecdf69
fixup
kdy1 Apr 26, 2024
8c5516b
`unresolved_ctxt`
kdy1 Apr 27, 2024
ffd7216
Fix clippy
kdy1 Apr 27, 2024
794fcdb
Remove dbg
kdy1 Apr 27, 2024
334dd3a
Update test refs
kdy1 Apr 29, 2024
8436233
[TMP] Default
kdy1 May 7, 2024
44e168f
bail with more details
kdy1 May 7, 2024
7661a31
Fail-safe references()
kdy1 May 7, 2024
f384048
More context on failure
kdy1 May 7, 2024
295ccbe
Common JS modules have only one part.
kdy1 May 7, 2024
a553847
Add a test
kdy1 May 7, 2024
171b9ca
Make `add_strong_deps` not lazy about from
kdy1 May 7, 2024
d104d2b
Rename for consistency
kdy1 May 7, 2024
3b15137
grammar
kdy1 May 7, 2024
95a0527
Add a debug assertion
kdy1 May 7, 2024
cd8510f
Add a debug assertion about module count
kdy1 May 7, 2024
96490e7
Convert debug assertions to non-debug assertions
kdy1 May 7, 2024
6266217
Add a test for the analyzer
kdy1 May 7, 2024
4354857
Rename for consistency
kdy1 May 7, 2024
6357f69
Pass top_level_mark down
kdy1 May 7, 2024
2b5a436
Use only
kdy1 May 7, 2024
3e6bc5b
Document
kdy1 May 7, 2024
a9a6003
fix
kdy1 May 8, 2024
7f55fca
print entrypoints while testing
kdy1 May 8, 2024
9e118ab
Update test refs
kdy1 May 8, 2024
cb88f17
More context on error
kdy1 May 8, 2024
4b87a40
Some
kdy1 May 8, 2024
b77b726
Add more detail for bail
kdy1 May 8, 2024
3a3ead9
Add a test
kdy1 May 8, 2024
457fe38
Remove some debug_ignore
kdy1 May 8, 2024
463be47
find_turbopack_part_id_in_asserts && PartId
kdy1 May 8, 2024
14a6513
Use create_turbopack_part_id_assert
kdy1 May 8, 2024
c6619d9
Rename & add dbg
kdy1 May 8, 2024
f88a139
More information on exception
kdy1 May 8, 2024
15730bd
dbg
kdy1 May 8, 2024
e7bb489
debug_ignore
kdy1 May 8, 2024
fc9dd89
Use asset ident for tree shaking
kdy1 May 9, 2024
33ce3ae
Lint
kdy1 May 9, 2024
0a52d28
WIP
kdy1 May 9, 2024
055d019
clipy
kdy1 May 9, 2024
6c5ef79
revert module part
kdy1 May 9, 2024
0026c82
pub(crate)
kdy1 May 9, 2024
e0ea7da
Use downcast in EsmAssetReference::resolve_reference
kdy1 May 9, 2024
109674a
Remove dbg
kdy1 May 9, 2024
33cb242
Enable CJS test
kdy1 May 9, 2024
6e83489
Make `only` array
kdy1 May 9, 2024
03c75be
Dummy EcmascriptModulePartAsset::content
kdy1 May 9, 2024
a1b3379
Add a test
kdy1 May 9, 2024
7195332
Update test refs
kdy1 May 9, 2024
9c67754
Revert "[TMP] Default"
kdy1 May 9, 2024
49981c8
Remove wrong test output
kdy1 May 9, 2024
bb6c711
fn decl && class decl
kdy1 May 9, 2024
8ffe200
Update test refs
kdy1 May 9, 2024
23c1be9
Revert "Revert "[TMP] Default""
kdy1 May 9, 2024
7ae0f57
Add a test
kdy1 May 9, 2024
e9c6ae1
Update test refs
kdy1 May 9, 2024
e31b584
SplitResult::Unparseable.messages
kdy1 May 9, 2024
a0e434d
Handle scripts
kdy1 May 9, 2024
a7e95f2
SplitResult::Failed
kdy1 May 10, 2024
0b926c4
Remove dbg
kdy1 May 10, 2024
692aea9
Script as a module
kdy1 May 10, 2024
ab35948
Check for common js
kdy1 May 10, 2024
3cde438
always analyze references
kdy1 May 10, 2024
b0e8c65
Revert useless changes
kdy1 May 10, 2024
96e4ab9
Replace import bindings in LHS
kdy1 May 10, 2024
b9a14fc
visit ident in simple assign target
kdy1 May 10, 2024
6bf91df
ast_path.len() - 2
kdy1 May 10, 2024
747a128
WIP!!!
kdy1 May 10, 2024
fdc00c4
We need to create a separate binding
kdy1 May 10, 2024
f1c0939
replace with a new variable
kdy1 May 10, 2024
650cfa3
Use `var` instead of `const`
kdy1 May 10, 2024
a8979e4
Remove dbg
kdy1 May 10, 2024
786cfe2
Use different
kdy1 May 10, 2024
240a671
Add dbg
kdy1 May 10, 2024
5af821e
Add dbg
kdy1 May 10, 2024
bcd9970
dbg
kdy1 May 13, 2024
7ce3c41
SimpleAssignTarget
kdy1 May 13, 2024
d8da680
dbg
kdy1 May 13, 2024
ddbd092
Add a test
kdy1 May 13, 2024
46696b2
Revert
kdy1 May 13, 2024
7d5f80e
WIP: Mutable export
kdy1 May 13, 2024
ee53395
fixup for mutable exports
kdy1 May 13, 2024
aa1048a
fixup: Fix compilation
kdy1 May 13, 2024
16b2fe1
Patch runtime
kdy1 May 13, 2024
63e43f7
Update test refs
kdy1 May 13, 2024
fdc873f
Fix input
kdy1 May 13, 2024
6e1f6d6
Update test refs
kdy1 May 13, 2024
ff22123
Reexport if read-write
kdy1 May 13, 2024
84eed67
kdy1 May 13, 2024
3175654
Add a unit test
kdy1 May 13, 2024
7e7abb8
Update test refs
kdy1 May 13, 2024
777e1cb
Full test
kdy1 May 13, 2024
ba341ef
UPdate test refs
kdy1 May 13, 2024
e93337d
Detect `module.hot`
kdy1 May 13, 2024
f653f43
Improve `bai!l`
kdy1 May 13, 2024
79c0fca
Add a test
kdy1 May 13, 2024
dedd0d6
syntaxcontext empty
kdy1 May 13, 2024
710e1a8
Improve cjs detection
kdy1 May 14, 2024
fc41b4d
fixup
kdy1 May 14, 2024
05d92ff
Remove dbg
kdy1 May 14, 2024
10bb270
Fix wrong test refs
kdy1 May 14, 2024
f022727
Remove wrong logic
kdy1 May 14, 2024
0507831
fixup
kdy1 May 14, 2024
df866d8
Update test refs
kdy1 May 14, 2024
7715d2b
only test
kdy1 May 14, 2024
ad00d40
Rename var
kdy1 May 14, 2024
7f453c5
Hack
kdy1 May 14, 2024
36c3e9f
Update test refs
kdy1 May 14, 2024
d658481
Revert hack
kdy1 May 14, 2024
76fc679
Exclude declared
kdy1 May 14, 2024
630fdfd
Update test refs
kdy1 May 14, 2024
f6cae09
read-write
kdy1 May 14, 2024
d441055
Update test refs
kdy1 May 14, 2024
5cbabfa
dbg
kdy1 May 14, 2024
c28d607
log error
kdy1 May 14, 2024
6dd7224
ChunkItem::is_self_async
kdy1 May 14, 2024
c3c5eb0
LOG
kdy1 May 16, 2024
3733c9e
[TMP] More log
kdy1 May 16, 2024
6b8eae3
add duplicate modules test case
sokra May 16, 2024
3a0af09
Revert logging
kdy1 May 16, 2024
3bb7931
Fix `is_async_module`
kdy1 May 16, 2024
7fcff73
fixup: `is_async_module`
kdy1 May 16, 2024
8260dcb
ESM input
kdy1 May 17, 2024
b1074eb
todo
kdy1 May 17, 2024
974ebe8
Remove return (0)
kdy1 May 17, 2024
d98c869
Fix `contains_cjs`
kdy1 May 17, 2024
dc8703f
Remove wrong
kdy1 May 17, 2024
681a1a7
Remove needless
kdy1 May 17, 2024
af55565
data.var_decls.contains(var)
kdy1 May 17, 2024
1c33c21
ESM
kdy1 May 17, 2024
e06f869
Fix reexports
kdy1 May 17, 2024
9c72b26
Use ModulePart::facade
kdy1 May 17, 2024
5e1e362
Update test refs
kdy1 May 17, 2024
7bcda9e
Remove dbg
kdy1 May 17, 2024
18b57a0
Remove wrong logic
kdy1 May 17, 2024
e2bc75a
bail for invalid import
kdy1 May 17, 2024
a413d6a
ImportedSymbol::Exports
kdy1 May 17, 2024
956054a
Use ImportedSymbol::Exports for more
kdy1 May 17, 2024
dabcf4b
`visit_export_all`: parse_with
kdy1 May 17, 2024
191899b
Make named re-exports
kdy1 May 17, 2024
860d53a
Make facade specific
kdy1 May 17, 2024
b3a37c9
Add a test
kdy1 May 17, 2024
fb85868
export is read
kdy1 May 17, 2024
112d25a
Update test refs
kdy1 May 17, 2024
c8c7f32
export default expr
kdy1 May 17, 2024
a3ce685
side effect
kdy1 May 17, 2024
c531148
ㄷ테ㅐㄱㅅ
kdy1 May 17, 2024
dfec407
used_ids
kdy1 May 17, 2024
5a8f6c3
Revert useless changes
kdy1 May 17, 2024
dc4c213
lint
kdy1 May 17, 2024
ec99a17
fix lint
kdy1 May 17, 2024
714e3c9
fix lint
kdy1 May 17, 2024
b072224
Update test refs
kdy1 May 17, 2024
6054333
split
kdy1 May 17, 2024
9cc91b0
Remove part from asset ident if spliting is disabled
kdy1 May 17, 2024
06f2580
seal namespace object
sokra May 17, 2024
1f072da
add test case
sokra May 17, 2024
f1a1971
reorganize test cases
sokra May 17, 2024
654e4d9
add test case
sokra May 17, 2024
123b23b
correct test case for side-effects-optimization
sokra May 17, 2024
5ef8f51
star reexports
kdy1 May 20, 2024
fdd9991
Use module eval
kdy1 May 20, 2024
57846a2
Add a test
kdy1 May 20, 2024
7c2e699
fix import map
kdy1 May 21, 2024
5f6ba4a
Update test refs
kdy1 May 21, 2024
2de66ae
ImportedSymbol::Exports
kdy1 May 21, 2024
57c8b6d
fix resolving issue
kdy1 May 21, 2024
5d241f4
ImportedSymbol::Namespace
kdy1 May 21, 2024
6fad5b8
`ImportedSymbol::Exports`
kdy1 May 22, 2024
41607ae
This test is wrong
kdy1 May 22, 2024
389d7da
Remove wrong test
kdy1 May 22, 2024
4081745
Workaround wrong async module thing
kdy1 May 22, 2024
44199ca
Why
kdy1 May 22, 2024
5198a08
Why not asynxc
kdy1 May 22, 2024
536b8ea
I think this is crazy
kdy1 May 22, 2024
44020cb
turbo task system is...
kdy1 May 22, 2024
0d46b8a
I hate this task
kdy1 May 22, 2024
40e72eb
`ImportMap.has_top_level_await`
kdy1 May 22, 2024
ebea537
dbg
kdy1 May 22, 2024
72fcb0a
dbg
kdy1 May 22, 2024
d562893
dbg
kdy1 May 22, 2024
9108e6a
Do not ignroe
kdy1 May 22, 2024
86a9129
TreeShakingMode::ReexportsOnly
kdy1 May 22, 2024
d1d4871
[TMP] Update tests
kdy1 May 22, 2024
84f61f4
Remove wrong test results
kdy1 May 23, 2024
03d0444
Update test snapshots
kdy1 May 23, 2024
7ca7203
Remove issues
kdy1 May 24, 2024
a3b2af5
side effect free
kdy1 May 24, 2024
5406130
ModulePart::Exports
kdy1 May 24, 2024
13448fd
Named export
kdy1 May 24, 2024
df4fe28
WIP: ModuleResolveResult::ignored
kdy1 May 24, 2024
ab7f915
side_effect_free_packages
kdy1 May 24, 2024
6e6633a
Remove vdbg
kdy1 May 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions crates/turbo-tasks-memory/src/aggregation/tests.rs
Expand Up @@ -116,6 +116,7 @@ fn check_invariants<'a>(
false
}
});
#[allow(clippy::never_loop)]
for missing_upper in missing_uppers {
let upper_value = {
let upper = ctx.node(missing_upper);
Expand Down
4 changes: 3 additions & 1 deletion crates/turbopack-core/src/context.rs
@@ -1,6 +1,6 @@
use anyhow::{bail, Result};
use turbo_tasks::{Value, Vc};
use turbo_tasks_fs::FileSystemPath;
use turbo_tasks_fs::{glob::Glob, FileSystemPath};

use crate::{
compile_time_info::CompileTimeInfo,
Expand Down Expand Up @@ -76,4 +76,6 @@ pub trait AssetContext {

/// Gets a new AssetContext with the transition applied.
fn with_transition(self: Vc<Self>, transition: String) -> Vc<Box<dyn AssetContext>>;

fn side_effect_free_packages(self: Vc<Self>) -> Vc<Glob>;
}
11 changes: 11 additions & 0 deletions crates/turbopack-core/src/resolve/mod.rs
Expand Up @@ -103,6 +103,17 @@ impl ModuleResolveResult {
}
}

pub fn ignored() -> ModuleResolveResult {
Self::ignored_with_key(RequestKey::default())
}

pub fn ignored_with_key(request_key: RequestKey) -> ModuleResolveResult {
ModuleResolveResult {
primary: indexmap! { request_key => ModuleResolveResultItem::Ignore },
affecting_sources: Vec::new(),
}
}

pub fn module(module: Vc<Box<dyn Module>>) -> ModuleResolveResult {
Self::module_with_key(RequestKey::default(), module)
}
Expand Down
Expand Up @@ -74,12 +74,25 @@ function defineProp(
/**
* Adds the getters to the exports object.
*/
function esm(exports: Exports, getters: Record<string, () => any>) {
function esm(
exports: Exports,
getters: Record<string, (() => any) | [() => any, (v: any) => void]>
) {
defineProp(exports, "__esModule", { value: true });
if (toStringTag) defineProp(exports, toStringTag, { value: "Module" });
for (const key in getters) {
defineProp(exports, key, { get: getters[key], enumerable: true });
const item = getters[key];
if (Array.isArray(item)) {
defineProp(exports, key, {
get: item[0],
set: item[1],
enumerable: true,
});
} else {
defineProp(exports, key, { get: item, enumerable: true });
}
}
Object.seal(exports);
}

/**
Expand Down
3 changes: 2 additions & 1 deletion crates/turbopack-ecmascript/benches/analyzer.rs
Expand Up @@ -55,7 +55,8 @@ pub fn benchmark(c: &mut Criterion) {
let top_level_mark = Mark::new();
program.visit_mut_with(&mut resolver(unresolved_mark, top_level_mark, false));

let eval_context = EvalContext::new(&program, unresolved_mark, None);
let eval_context =
EvalContext::new(&program, unresolved_mark, top_level_mark, false, None);
let var_graph = create_graph(&program, &eval_context);

let input = BenchInput {
Expand Down
19 changes: 16 additions & 3 deletions crates/turbopack-ecmascript/src/analyzer/graph.rs
Expand Up @@ -261,18 +261,22 @@ pub fn create_graph(m: &Program, eval_context: &EvalContext) -> VarGraph {

pub struct EvalContext {
pub(crate) unresolved_mark: Mark,
pub(crate) top_level_mark: Mark,
pub(crate) imports: ImportMap,
}

impl EvalContext {
pub fn new(
module: &Program,
unresolved_mark: Mark,
top_level_mark: Mark,
skip_namespace: bool,
source: Option<Vc<Box<dyn Source>>>,
) -> Self {
Self {
unresolved_mark,
imports: ImportMap::analyze(module, source),
top_level_mark,
imports: ImportMap::analyze(module, skip_namespace, source),
}
}

Expand Down Expand Up @@ -1460,6 +1464,8 @@ impl VisitAstPath for Analyzer<'_> {
) {
let value = self.current_value.take();
if let SimpleAssignTarget::Ident(i) = n {
n.visit_children_with_path(self, ast_path);

self.add_value(
i.to_id(),
value.unwrap_or_else(|| {
Expand Down Expand Up @@ -1572,13 +1578,20 @@ impl VisitAstPath for Analyzer<'_> {
ident: &'ast Ident,
ast_path: &mut AstNodePath<AstParentNodeRef<'r>>,
) {
if !matches!(
if !(matches!(
ast_path.last(),
Some(AstParentNodeRef::Expr(_, ExprField::Ident))
| Some(AstParentNodeRef::Prop(_, PropField::Shorthand))
) {
) || matches!(
ast_path.get(ast_path.len() - 2),
Some(AstParentNodeRef::SimpleAssignTarget(
_,
SimpleAssignTargetField::Ident,
))
)) {
return;
}

if let Some((esm_reference_index, export)) =
self.eval_context.imports.get_binding(&ident.to_id())
{
Expand Down
88 changes: 74 additions & 14 deletions crates/turbopack-ecmascript/src/analyzer/imports.rs
Expand Up @@ -13,7 +13,8 @@ use swc_core::{
use turbo_tasks::Vc;
use turbopack_core::{issue::IssueSource, source::Source};

use super::{JsValue, ModuleValue};
use super::{top_level_await::has_top_level_await, JsValue, ModuleValue};
use crate::tree_shake::{find_turbopack_part_id_in_asserts, PartId};

#[turbo_tasks::value(serialization = "auto_for_input")]
#[derive(Default, Debug, Clone, Hash, PartialOrd, Ord)]
Expand Down Expand Up @@ -129,13 +130,18 @@ pub(crate) struct ImportMap {

/// True, when the module has exports
has_exports: bool,

/// True if the module is an ESM module due to top-level await.
has_top_level_await: bool,
}

#[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub(crate) enum ImportedSymbol {
ModuleEvaluation,
Symbol(JsWord),
Namespace,
Exports,
Part(u32),
}

#[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
Expand All @@ -148,7 +154,10 @@ pub(crate) struct ImportMapReference {

impl ImportMap {
pub fn is_esm(&self) -> bool {
self.has_exports || !self.imports.is_empty() || !self.namespace_imports.is_empty()
self.has_exports
|| self.has_top_level_await
|| !self.imports.is_empty()
|| !self.namespace_imports.is_empty()
}

pub fn get_import(&self, id: &Id) -> Option<JsValue> {
Expand Down Expand Up @@ -192,11 +201,16 @@ impl ImportMap {
}

/// Analyze ES import
pub(super) fn analyze(m: &Program, source: Option<Vc<Box<dyn Source>>>) -> Self {
pub(super) fn analyze(
m: &Program,
skip_namespace: bool,
source: Option<Vc<Box<dyn Source>>>,
) -> Self {
let mut data = ImportMap::default();

m.visit_with(&mut Analyzer {
data: &mut data,
skip_namespace,
source,
});

Expand All @@ -206,6 +220,7 @@ impl ImportMap {

struct Analyzer<'a> {
data: &'a mut ImportMap,
skip_namespace: bool,
source: Option<Vc<Box<dyn Source>>>,
}

Expand All @@ -216,7 +231,11 @@ impl<'a> Analyzer<'a> {
module_path: JsWord,
imported_symbol: ImportedSymbol,
annotations: ImportAnnotations,
) -> usize {
) -> Option<usize> {
if self.skip_namespace && matches!(imported_symbol, ImportedSymbol::Namespace) {
return None;
}

let issue_source = self
.source
.map(|s| IssueSource::from_swc_offsets(s, span.lo.to_usize(), span.hi.to_usize()));
Expand All @@ -228,11 +247,11 @@ impl<'a> Analyzer<'a> {
annotations,
};
if let Some(i) = self.data.references.get_index_of(&r) {
i
Some(i)
} else {
let i = self.data.references.len();
self.data.references.insert(r);
i
Some(i)
}
}
}
Expand All @@ -256,13 +275,17 @@ impl Visit for Analyzer<'_> {
);

for s in &import.specifiers {
let symbol = get_import_symbol_from_import(s);
let symbol = get_import_symbol_from_import(s, import.with.as_deref());
let i = self.ensure_reference(
import.span,
import.src.value.clone(),
symbol,
annotations.clone(),
);
let i = match i {
Some(v) => v,
None => continue,
};

let (local, orig_sym) = match s {
ImportSpecifier::Named(ImportNamedSpecifier {
Expand Down Expand Up @@ -293,13 +316,17 @@ impl Visit for Analyzer<'_> {
ImportedSymbol::ModuleEvaluation,
annotations.clone(),
);
let symbol = parse_with(export.with.as_deref());

let i = self.ensure_reference(
export.span,
export.src.value.clone(),
ImportedSymbol::Namespace,
symbol.unwrap_or(ImportedSymbol::Namespace),
annotations,
);
self.data.reexports.push((i, Reexport::Star));
if let Some(i) = i {
self.data.reexports.push((i, Reexport::Star));
}
}

fn visit_named_export(&mut self, export: &NamedExport) {
Expand All @@ -319,10 +346,14 @@ impl Visit for Analyzer<'_> {
);

for spec in export.specifiers.iter() {
let symbol = get_import_symbol_from_export(spec);
let symbol = get_import_symbol_from_export(spec, export.with.as_deref());

let i =
self.ensure_reference(export.span, src.value.clone(), symbol, annotations.clone());
let i = match i {
Some(v) => v,
None => continue,
};

match spec {
ExportSpecifier::Namespace(n) => {
Expand Down Expand Up @@ -367,6 +398,12 @@ impl Visit for Analyzer<'_> {
fn visit_stmt(&mut self, _: &Stmt) {
// don't visit children
}

fn visit_program(&mut self, m: &Program) {
self.data.has_top_level_await = has_top_level_await(m).is_some();

m.visit_children_with(self);
}
}

pub(crate) fn orig_name(n: &ModuleExportName) -> JsWord {
Expand All @@ -376,7 +413,23 @@ pub(crate) fn orig_name(n: &ModuleExportName) -> JsWord {
}
}

fn get_import_symbol_from_import(specifier: &ImportSpecifier) -> ImportedSymbol {
fn parse_with(with: Option<&ObjectLit>) -> Option<ImportedSymbol> {
find_turbopack_part_id_in_asserts(with?).map(|v| match v {
PartId::Internal(index) => ImportedSymbol::Part(index),
PartId::ModuleEvaluation => ImportedSymbol::ModuleEvaluation,
PartId::Export(e) => ImportedSymbol::Symbol(e.into()),
PartId::Exports => ImportedSymbol::Exports,
})
}

fn get_import_symbol_from_import(
specifier: &ImportSpecifier,
with: Option<&ObjectLit>,
) -> ImportedSymbol {
if let Some(part) = parse_with(with) {
return part;
}

match specifier {
ImportSpecifier::Named(ImportNamedSpecifier {
local, imported, ..
Expand All @@ -385,16 +438,23 @@ fn get_import_symbol_from_import(specifier: &ImportSpecifier) -> ImportedSymbol
_ => local.sym.clone(),
}),
ImportSpecifier::Default(..) => ImportedSymbol::Symbol(js_word!("default")),
ImportSpecifier::Namespace(..) => ImportedSymbol::Namespace,
ImportSpecifier::Namespace(..) => ImportedSymbol::Exports,
}
}

fn get_import_symbol_from_export(specifier: &ExportSpecifier) -> ImportedSymbol {
fn get_import_symbol_from_export(
specifier: &ExportSpecifier,
with: Option<&ObjectLit>,
) -> ImportedSymbol {
if let Some(part) = parse_with(with) {
return part;
}

match specifier {
ExportSpecifier::Named(ExportNamedSpecifier { orig, .. }) => {
ImportedSymbol::Symbol(orig_name(orig))
}
ExportSpecifier::Default(..) => ImportedSymbol::Symbol(js_word!("default")),
ExportSpecifier::Namespace(..) => ImportedSymbol::Namespace,
ExportSpecifier::Namespace(..) => ImportedSymbol::Exports,
}
}
3 changes: 2 additions & 1 deletion crates/turbopack-ecmascript/src/analyzer/mod.rs
Expand Up @@ -3574,7 +3574,8 @@ mod tests {
let top_level_mark = Mark::new();
m.visit_mut_with(&mut resolver(unresolved_mark, top_level_mark, false));

let eval_context = EvalContext::new(&m, unresolved_mark, None);
let eval_context =
EvalContext::new(&m, unresolved_mark, top_level_mark, false, None);

let mut var_graph = create_graph(&m, &eval_context);

Expand Down
1 change: 1 addition & 0 deletions crates/turbopack-ecmascript/src/lib.rs
Expand Up @@ -193,6 +193,7 @@ struct MemoizedSuccessfulAnalysis {
source_map: Option<ReadRef<SourceMap>>,
}

#[derive(Clone)]
pub struct EcmascriptModuleAssetBuilder {
source: Vc<Box<dyn Source>>,
asset_context: Vc<Box<dyn AssetContext>>,
Expand Down