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(bundler): Fix statement ordering issue #1264

Merged
merged 208 commits into from
Dec 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
208 commits
Select commit Hold shift + click to select a range
ae61328
Add a test for denoland/deno#8679
kdy1 Dec 9, 2020
907651d
Add tests for denoland/deno#8211
kdy1 Dec 9, 2020
6f71047
Rename tests
kdy1 Dec 9, 2020
ee42920
Fix `export *`
kdy1 Dec 11, 2020
78cfe37
Fix export default problem
kdy1 Dec 11, 2020
3646668
Update test ref
kdy1 Dec 11, 2020
23bc1a7
Ignore 8211 test for now
kdy1 Dec 16, 2020
c048057
Ignore 8211 test for now
kdy1 Dec 16, 2020
39cd60f
Add `Modules`
kdy1 Dec 16, 2020
436e0ac
Don't merge imports
kdy1 Dec 16, 2020
835d4a8
Fix addmore
kdy1 Dec 16, 2020
0e65ddf
comment
kdy1 Dec 16, 2020
bf048f3
Backup
kdy1 Dec 16, 2020
9623584
modules: Reduce direct field usage
kdy1 Dec 16, 2020
5a8d3e8
fixup
kdy1 Dec 16, 2020
7a67f3b
cjs load functions should be prepended
kdy1 Dec 16, 2020
3fde01c
circular imports: Preserve current semantics
kdy1 Dec 16, 2020
428bfdd
replace_import_specifiers: Don't use field
kdy1 Dec 16, 2020
00aafd0
Modules.map
kdy1 Dec 16, 2020
5c02bd8
Revert "replace_import_specifiers: Don't use field"
kdy1 Dec 16, 2020
a346ca0
handle_reexport: Use modules.map
kdy1 Dec 16, 2020
abcfe25
replace_import_specifiers: Use modules.map
kdy1 Dec 16, 2020
cbcedfa
uaw subdirectory
kdy1 Dec 16, 2020
4ba2c6e
cjs: Replace simple VisitMut with function
kdy1 Dec 16, 2020
6961400
Migrate `UnexportAsVar`
kdy1 Dec 16, 2020
a3abdf6
Modules.into_items()
kdy1 Dec 16, 2020
867a402
Convert export injector into a function
kdy1 Dec 16, 2020
293ffc4
typo
kdy1 Dec 16, 2020
8f1e78f
Change es6 module injector into a function
kdy1 Dec 16, 2020
3ca4e31
fixup
kdy1 Dec 16, 2020
7e60d69
Hide `Modules.body`
kdy1 Dec 16, 2020
22046af
Update test refs
kdy1 Dec 16, 2020
0ee78b3
Update test refs
kdy1 Dec 16, 2020
c3ebb06
Convert `Modules.body` from `Vec<ModuleItem>` to `Vec<Module>`
kdy1 Dec 16, 2020
1496031
Update test refs
kdy1 Dec 17, 2020
557ae28
Remove dead code
kdy1 Dec 17, 2020
6dc0b55
Circular deps should be prepended
kdy1 Dec 17, 2020
c5cd188
Update test refs
kdy1 Dec 17, 2020
48927fa
Update test refs
kdy1 Dec 17, 2020
50b2055
Update test refs
kdy1 Dec 17, 2020
eafa6e7
Add a test for sort
kdy1 Dec 17, 2020
5e66dba
Fix sorter
kdy1 Dec 17, 2020
6090d6a
Update test script
kdy1 Dec 17, 2020
7b879c2
Unignore
kdy1 Dec 17, 2020
8bab0db
Add one more test for `sort`
kdy1 Dec 17, 2020
f49db5c
Sort items of a wrapped module
kdy1 Dec 17, 2020
d85ffed
TRY: Handle `export default expr` while handling reexports
kdy1 Dec 17, 2020
0d10a3d
Allow `export *` and `export { default }` from same source
kdy1 Dec 17, 2020
0ed3d70
Update test refs
kdy1 Dec 17, 2020
d2211ca
Exclude `export default expr` while merging `export *`
kdy1 Dec 17, 2020
1108d68
Allow `export *` and `export { default }` from same module
kdy1 Dec 17, 2020
9037aba
fixer: Handle assignments in the callee of new correctly.
kdy1 Dec 17, 2020
f1cb328
fixer: Handle seqence expression in the callee of new correctly
kdy1 Dec 17, 2020
fa78e87
`export { default }` is default export.
kdy1 Dec 17, 2020
ec7adca
fixup
kdy1 Dec 17, 2020
98a91f9
Extract `remove_default_export`
kdy1 Dec 17, 2020
b78780d
Add an execution test
kdy1 Dec 17, 2020
e610d03
Add a test for hoisting
kdy1 Dec 17, 2020
364d90a
fixup
kdy1 Dec 17, 2020
390243e
Move retain
kdy1 Dec 17, 2020
26c43f2
lint
kdy1 Dec 17, 2020
72fd984
Merge same module first
kdy1 Dec 17, 2020
fb96a0e
fixup
kdy1 Dec 17, 2020
884682a
Update test refs
kdy1 Dec 17, 2020
a5c161b
Debugging sort
kdy1 Dec 17, 2020
94c10de
Move insert_orders to top level
kdy1 Dec 17, 2020
cbb80d3
Fix sort
kdy1 Dec 18, 2020
79cf0d0
sort: Handle empty module
kdy1 Dec 18, 2020
56ba591
TRY: Use inject_all if possible
kdy1 Dec 18, 2020
86233b0
TRY: Dummy span indicates injected
kdy1 Dec 18, 2020
37dc883
Update test refs
kdy1 Dec 18, 2020
b3d9be1
Update test refs
kdy1 Dec 18, 2020
8e72653
Update test refs
kdy1 Dec 18, 2020
448e1bd
Update test refs
kdy1 Dec 18, 2020
d59a097
Add a test
kdy1 Dec 19, 2020
49d1dab
Update test ref
kdy1 Dec 19, 2020
bfe3fff
TRY: sort.in_dejavu_mode
kdy1 Dec 19, 2020
95130d8
Revert "TRY: sort.in_dejavu_mode"
kdy1 Dec 19, 2020
23a8d39
TRY: delayed
kdy1 Dec 19, 2020
08a2103
sort: Concept of `delayed`
kdy1 Dec 19, 2020
8dd6063
Update test ref
kdy1 Dec 19, 2020
f051d10
Correcntly use`delayed`
kdy1 Dec 19, 2020
c30087a
Update test refs
kdy1 Dec 19, 2020
986c76f
Update test refs
kdy1 Dec 19, 2020
167a969
Update test refs
kdy1 Dec 19, 2020
b297779
Update test refs
kdy1 Dec 19, 2020
c693615
Update test refs
kdy1 Dec 19, 2020
361f5e3
Update test refs
kdy1 Dec 19, 2020
cda9b6e
Update
kdy1 Dec 19, 2020
4024d5a
Add Sorter
kdy1 Dec 19, 2020
5147964
Nodes with dummy span is injected
kdy1 Dec 19, 2020
8247c93
Single sort is enough
kdy1 Dec 19, 2020
8a8f992
Update test refs
kdy1 Dec 19, 2020
b43a71c
Update test refs
kdy1 Dec 19, 2020
d11e354
Update test refs
kdy1 Dec 19, 2020
252df9c
Update test refs
kdy1 Dec 19, 2020
4deea8e
Update test refs
kdy1 Dec 19, 2020
657f48f
Update test refs
kdy1 Dec 19, 2020
bdb4cdb
Update test refs
kdy1 Dec 19, 2020
9ae4384
Update test refs
kdy1 Dec 19, 2020
67c8a3c
Unignore a test for statement ordering
kdy1 Dec 19, 2020
069199f
Let's use injected context to track injected vars
kdy1 Dec 19, 2020
b2b2bdd
Mark injected statements
kdy1 Dec 19, 2020
32e0709
Fix mark
kdy1 Dec 19, 2020
98802d6
sort from Modules.into_items
kdy1 Dec 19, 2020
51ac3d8
Correct usage of injected_ctxt
kdy1 Dec 19, 2020
34af596
Add a test for stmt orderings
kdy1 Dec 19, 2020
7d5484f
WIP: Single sort is enough
kdy1 Dec 19, 2020
3399c1c
Finally, fix for statement orderings
kdy1 Dec 19, 2020
0d64b93
Revert "Finally, fix for statement orderings"
kdy1 Dec 19, 2020
0c2454c
debugging sort: Print var decls
kdy1 Dec 19, 2020
ea39c66
Revert "Revert "Finally, fix for statement orderings""
kdy1 Dec 19, 2020
36640b7
WIP
kdy1 Dec 19, 2020
8d143a4
WIP
kdy1 Dec 20, 2020
aa1ea03
sort: Add assertion
kdy1 Dec 20, 2020
0ef1c72
fixup
kdy1 Dec 20, 2020
b5627c3
Don't move to start while handling non cyclic deps
kdy1 Dec 20, 2020
1f565df
WIP: Emit free items while printing in dep-only mode
kdy1 Dec 20, 2020
db5ea75
Emit non-circular modules correctly
kdy1 Dec 20, 2020
84fb032
Print unsorted
kdy1 Dec 20, 2020
e0d11da
less logging
kdy1 Dec 20, 2020
f023710
Inserting seems fine
kdy1 Dec 20, 2020
f638ee4
Sort wrapped modules
kdy1 Dec 20, 2020
ce18176
fixup
kdy1 Dec 20, 2020
41d80ea
Fix range
kdy1 Dec 20, 2020
b08183c
I find the root cause.
kdy1 Dec 20, 2020
3082258
Enable weak dependency detection for classes
kdy1 Dec 20, 2020
6f0b017
Handle weak deps
kdy1 Dec 20, 2020
5c464a0
I found that it's bug of petgraph...
kdy1 Dec 20, 2020
eb5876b
Fix emit
kdy1 Dec 20, 2020
4249c8b
Fix assertion
kdy1 Dec 20, 2020
9b895f9
Fix emit: correct check for dependants
kdy1 Dec 20, 2020
4ecb55f
More logging
kdy1 Dec 20, 2020
6e5d5d6
FnDecl should be analyzed, to prevent being emitted to early
kdy1 Dec 20, 2020
d16fe99
lints
kdy1 Dec 20, 2020
3cb25f5
We need to record graph operations
kdy1 Dec 23, 2020
53183be
Wrapped
kdy1 Dec 23, 2020
2008da6
Migrate a test to deno-exec
kdy1 Dec 23, 2020
efe8470
Migrate more
kdy1 Dec 23, 2020
d43ba04
Test for 8545 should be terminated normally
kdy1 Dec 23, 2020
32c96df
Migrate one more
kdy1 Dec 23, 2020
640c82f
fixup
kdy1 Dec 23, 2020
fc1ef6d
Test can be faster
kdy1 Dec 23, 2020
c64091f
lint
kdy1 Dec 23, 2020
8376644
Rename some tests
kdy1 Dec 23, 2020
a937ae2
Look for prototype usages. (8620)
kdy1 Dec 24, 2020
ff8dc6d
Actually add prototype usage info to the graph
kdy1 Dec 24, 2020
bfac082
More logging
kdy1 Dec 24, 2020
1a6eb71
fixup
kdy1 Dec 24, 2020
1d275c5
Logging
kdy1 Dec 24, 2020
cf20cda
Enable logging
kdy1 Dec 24, 2020
919775f
Use stdout instead of stderr
kdy1 Dec 24, 2020
00bdb4e
WIP
kdy1 Dec 24, 2020
ceac078
Implement sorter using iterator
kdy1 Dec 24, 2020
e660f70
More work
kdy1 Dec 25, 2020
2391580
Improve sorting test
kdy1 Dec 25, 2020
a99a5c7
Remove stack.contains
kdy1 Dec 25, 2020
f33475b
Add an unit test for sort
kdy1 Dec 25, 2020
04052e7
Fix sorter?
kdy1 Dec 25, 2020
5b09ed1
Prevent panic
kdy1 Dec 25, 2020
fd620fd
More logic for moving
kdy1 Dec 26, 2020
62bd4a1
Print item
kdy1 Dec 26, 2020
56895ea
Print before sorting
kdy1 Dec 26, 2020
c3ee68f
Fixed?
kdy1 Dec 26, 2020
381b6d8
More logic for skipping dependency checks
kdy1 Dec 26, 2020
a4f88ba
Remove wrong todo
kdy1 Dec 26, 2020
aee5b65
Make checking logic efficient
kdy1 Dec 26, 2020
4a94ec3
fmt
kdy1 Dec 26, 2020
10f5c80
Remove useless sort call
kdy1 Dec 26, 2020
3230ad4
Add can_ignore_weak_deps
kdy1 Dec 26, 2020
2a31c50
Backiup: Same semantic
kdy1 Dec 26, 2020
754514a
Add logging
kdy1 Dec 26, 2020
5bf4fda
Cleanup
kdy1 Dec 26, 2020
6c1f92d
More assertions
kdy1 Dec 26, 2020
78290b1
More logic for handling prototypes
kdy1 Dec 26, 2020
21b5285
sort/graph: Optimize for read
kdy1 Dec 26, 2020
61bdbaf
WIP
kdy1 Dec 26, 2020
186825d
sort/graph: Fix insert_transitives
kdy1 Dec 26, 2020
28979be
More time
kdy1 Dec 26, 2020
00343bb
Add a minimal reproduction case for 8597
kdy1 Dec 26, 2020
e9824c0
Test should respect original
kdy1 Dec 26, 2020
a2a33c8
Smaller repro
kdy1 Dec 26, 2020
25d0ba0
Found repro
kdy1 Dec 26, 2020
46bcca6
Reduced
kdy1 Dec 26, 2020
2d2cc5f
sort: Remove logging
kdy1 Dec 26, 2020
bc7a1e4
Print `done` instead of module before sorting
kdy1 Dec 26, 2020
2b3032d
lint
kdy1 Dec 26, 2020
6c58c46
lint
kdy1 Dec 26, 2020
007caac
lint
kdy1 Dec 26, 2020
887094a
Postpone 8597
kdy1 Dec 26, 2020
281c932
fixup for the rebase
kdy1 Dec 26, 2020
4c4f3da
Update test refs
kdy1 Dec 26, 2020
99e2112
Update test refs
kdy1 Dec 26, 2020
5b9db39
Update test refs
kdy1 Dec 26, 2020
6265ff8
Update test refs
kdy1 Dec 26, 2020
fb6047f
Update test refs
kdy1 Dec 26, 2020
08c4b08
Update test refs
kdy1 Dec 26, 2020
aa5e08e
Udpate test refs
kdy1 Dec 26, 2020
81cf8d7
Update test refs
kdy1 Dec 26, 2020
f235f4b
Update test refs
kdy1 Dec 26, 2020
897de17
Update test refs
kdy1 Dec 26, 2020
1fd4d4e
Update test refs
kdy1 Dec 26, 2020
e4a3f8f
Remove patch
kdy1 Dec 26, 2020
48495a5
Fix
kdy1 Dec 27, 2020
fd95870
Fix
kdy1 Dec 27, 2020
ad20ff3
lint
kdy1 Dec 27, 2020
2004901
Update test refs
kdy1 Dec 27, 2020
622a187
Merge branch 'master' into bundler
kdy1 Dec 27, 2020
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
1 change: 1 addition & 0 deletions bundler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ swc_ecma_visit = {version = "0.22.0", path = "../ecmascript/visit"}

[dev-dependencies]
hex = "0.4"
ntest = "0.7.2"
reqwest = {version = "0.10.8", features = ["blocking"]}
sha-1 = "0.9"
swc_ecma_transforms = {version = "0.31.0", path = "../ecmascript/transforms", features = ["react"]}
Expand Down
3 changes: 3 additions & 0 deletions bundler/scripts/test.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#!/usr/bin/env bash
set -eux

cargo test --no-run

cargo test --lib
cargo test --test fixture
(cd ../spack && cargo test --test fixture)
cargo test --test deno $@ -- --nocapture
64 changes: 19 additions & 45 deletions bundler/src/bundler/chunk/circular.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
use super::plan::CircularPlan;
use crate::{
bundler::chunk::{merge::Ctx, sort::sort},
id::Id,
Bundler, Load, ModuleId, Resolve,
};
use crate::bundler::modules::Modules;
use crate::{bundler::chunk::merge::Ctx, id::Id, Bundler, Load, ModuleId, Resolve};
use anyhow::{Context, Error};
use swc_common::DUMMY_SP;
use swc_ecma_ast::*;
use swc_ecma_utils::find_ids;

#[cfg(test)]
mod tests;

/// Circular imports are hard to handle.
///
/// We use some dedicated method to handle circular dependencies.
Expand All @@ -25,7 +19,7 @@ where
ctx: &Ctx,
plan: &CircularPlan,
entry_id: ModuleId,
) -> Result<Module, Error> {
) -> Result<Modules, Error> {
assert!(
plan.chunks.len() >= 1,
"# of circular modules should be 2 or greater than 2 including entry. Got {:?}",
Expand All @@ -34,11 +28,7 @@ where

if !ctx.merged.insert(entry_id) {
log::debug!("[circular] skip: {:?}", entry_id);
return Ok(Module {
span: DUMMY_SP,
body: Default::default(),
shebang: Default::default(),
});
return Ok(Modules::empty(self.injected_ctxt));
}

log::debug!("[circular] Stsrting with: {:?}", entry_id);
Expand All @@ -50,7 +40,7 @@ where
.context("failed to merge dependency of a cyclic module")?;

let mut exports = vec![];
for item in entry.body.iter_mut() {
for item in entry.iter_mut() {
match item {
ModuleItem::ModuleDecl(decl) => match decl {
ModuleDecl::ExportDecl(export) => match &export.decl {
Expand Down Expand Up @@ -125,16 +115,14 @@ where
entry = new_module;

if !exports.is_empty() {
entry
.body
.push(ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(
NamedExport {
span: DUMMY_SP.with_ctxt(self.synthesized_ctxt),
specifiers: exports,
src: None,
type_only: false,
},
)));
entry.inject(ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(
NamedExport {
span: DUMMY_SP.with_ctxt(self.synthesized_ctxt),
specifiers: exports,
src: None,
type_only: false,
},
)));
}

// print_hygiene("[circular] done", &self.cm, &entry);
Expand All @@ -146,10 +134,10 @@ where
pub(super) fn merge_circular_modules(
&self,
ctx: &Ctx,
mut entry: Module,
mut entry: Modules,
entry_id: ModuleId,
mut deps: Vec<ModuleId>,
) -> Result<Module, Error> {
) -> Result<Modules, Error> {
deps.retain(|&dep| {
if dep == entry_id {
return false;
Expand All @@ -167,40 +155,26 @@ where
deps.sort();

self.run(|| {
let mut dep_body = vec![];

for dep in deps {
let dep_info = self.scope.get_module(dep).unwrap();
let mut dep = self
.merge_modules(ctx, dep, false, false)
.context("failed to merge dependency of a cyclic module")?;

// print_hygiene("[circular] dep:init 1", &self.cm, &dep);
// print_hygiene("[circular] dep:init 1", &self.cm, &dep.clone().into());

self.handle_import_deps(ctx, &dep_info, &mut dep, true);

// print_hygiene("[circular] dep:init 2", &self.cm, &dep);

dep_body.extend(dep.body);
entry.prepend_all(dep);
}

// dep = dep.fold_with(&mut Unexporter);
// print_hygiene("before circular sort", &self.cm, &entry.clone().into());

// Merge code
entry.body = merge_respecting_order(dep_body, entry.body);
// entry.sort();

Ok(entry)
})
}
}

fn merge_respecting_order(dep: Vec<ModuleItem>, entry: Vec<ModuleItem>) -> Vec<ModuleItem> {
let mut new = Vec::with_capacity(dep.len() + entry.len());

new.extend(entry);
new.extend(dep);

sort(&mut new);

new
}
110 changes: 0 additions & 110 deletions bundler/src/bundler/chunk/circular/tests.rs

This file was deleted.

52 changes: 21 additions & 31 deletions bundler/src/bundler/chunk/cjs.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::merge::Unexporter;
use crate::bundler::modules::Modules;
use crate::{
bundler::{
chunk::{merge::Ctx, plan::Dependancy},
Expand All @@ -7,12 +8,12 @@ use crate::{
Bundler, Load, Resolve,
};
use anyhow::Error;
use std::{borrow::Cow, sync::atomic::Ordering};
use std::sync::atomic::Ordering;
use swc_atoms::js_word;
use swc_common::{SyntaxContext, DUMMY_SP};
use swc_ecma_ast::{ModuleItem, *};
use swc_ecma_utils::{prepend, quote_ident, undefined, ExprFactory};
use swc_ecma_visit::{noop_visit_mut_type, FoldWith, VisitMut, VisitMutWith};
use swc_ecma_utils::{quote_ident, undefined, ExprFactory};
use swc_ecma_visit::{noop_visit_mut_type, VisitMut, VisitMutWith};

impl<L, R> Bundler<'_, L, R>
where
Expand Down Expand Up @@ -44,9 +45,9 @@ where
&self,
ctx: &Ctx,
is_entry: bool,
entry: &mut Module,
entry: &mut Modules,
info: &TransformedModule,
dep: Cow<Module>,
dep: Modules,
dep_info: &TransformedModule,
targets: &mut Vec<Dependancy>,
) -> Result<(), Error> {
Expand All @@ -62,7 +63,7 @@ where
load_var: Ident::new("load".into(), DUMMY_SP.with_ctxt(dep_info.export_ctxt())),
replaced: false,
};
entry.body.visit_mut_with(&mut v);
entry.visit_mut_with(&mut v);

if v.replaced {
if let Some(idx) = targets.iter().position(|v| v.id == dep_info.id) {
Expand All @@ -74,21 +75,18 @@ where
{
info.helpers.require.store(true, Ordering::SeqCst);

let mut dep = dep.into_owned().fold_with(&mut Unexporter);
dep.visit_mut_with(&mut ImportDropper);
let mut dep = dep.fold_with(&mut Unexporter);
drop_module_decls(&mut dep);
dep.visit_mut_with(&mut DefaultHandler {
local_ctxt: dep_info.local_ctxt(),
});

prepend(
&mut entry.body,
ModuleItem::Stmt(wrap_module(
SyntaxContext::empty(),
dep_info.local_ctxt(),
load_var,
dep,
)),
);
entry.prepend(ModuleItem::Stmt(wrap_module(
SyntaxContext::empty(),
dep_info.local_ctxt(),
load_var,
dep.into(),
)));

log::warn!("Injecting load");
}
Expand All @@ -105,7 +103,7 @@ where
false,
entry,
info,
Cow::Borrowed(&dep_info.module),
Modules::from((*dep_info.module).clone(), self.injected_ctxt),
&dep_info,
targets,
)?;
Expand Down Expand Up @@ -338,19 +336,11 @@ impl VisitMut for RequireReplacer {
}
}

struct ImportDropper;

impl VisitMut for ImportDropper {
noop_visit_mut_type!();

fn visit_mut_module_item(&mut self, i: &mut ModuleItem) {
match i {
ModuleItem::ModuleDecl(..) => {
*i = ModuleItem::Stmt(Stmt::Empty(EmptyStmt { span: DUMMY_SP }))
}
ModuleItem::Stmt(_) => {}
}
}
fn drop_module_decls(modules: &mut Modules) {
modules.retain_mut(|i| match i {
ModuleItem::ModuleDecl(..) => false,
ModuleItem::Stmt(_) => true,
})
}

struct DefaultHandler {
Expand Down
Loading