Skip to content

Commit

Permalink
Fix bundler (#1242)
Browse files Browse the repository at this point in the history
swc_ecma_codegen:
 - Fix codegen of unicode escapes. (denoland/deno#8541)

swc_bundler:
 - Allow importing a module multiple time. (denoland/deno#8530)
  • Loading branch information
kdy1 committed Nov 30, 2020
1 parent 46b553e commit ea6beaa
Show file tree
Hide file tree
Showing 16 changed files with 121 additions and 46 deletions.
2 changes: 1 addition & 1 deletion bundler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ edition = "2018"
license = "Apache-2.0/MIT"
name = "swc_bundler"
repository = "https://github.com/swc-project/swc.git"
version = "0.17.2"
version = "0.17.3"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
Expand Down
62 changes: 39 additions & 23 deletions bundler/src/bundler/chunk/merge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use std::{borrow::Cow, collections::HashMap, mem::take};
use swc_atoms::js_word;
use swc_common::{sync::Lock, FileName, SyntaxContext, DUMMY_SP};
use swc_ecma_ast::*;
use swc_ecma_utils::{find_ids, prepend, private_ident};
use swc_ecma_utils::{find_ids, prepend, private_ident, ExprFactory};
use swc_ecma_visit::{noop_fold_type, noop_visit_mut_type, Fold, FoldWith, VisitMut, VisitMutWith};
use util::CHashSet;

Expand Down Expand Up @@ -102,6 +102,7 @@ where
&self,
ctx: &Ctx,
dep_id: ModuleId,
src: &Source,
specifiers: &[Specifier],
) -> Result<Module, Error> {
log::debug!("Merging {:?} directly", dep_id);
Expand All @@ -114,27 +115,25 @@ where
let mut module = self.get_module_for_merging(ctx, dep_id, false)?;
module = self.wrap_esm(ctx, dep_id, module)?;

{
// Inject local_name = wrapped_esm_module_name
// Inject local_name = wrapped_esm_module_name
let module_ident = specifiers
.iter()
.find_map(|specifier| match specifier {
Specifier::Namespace {
local, all: true, ..
} => Some(local.clone()),
_ => None,
})
.unwrap();

let module_ident = specifiers
.iter()
.find_map(|specifier| match specifier {
Specifier::Namespace {
local, all: true, ..
} => Some(local.clone()),
_ => None,
})
.unwrap();

module.body.push(
self.scope
.wrapped_esm_id(dep_id)
.unwrap()
.assign_to(module_ident)
.into_module_item("merge_direct_import"),
);
}
let esm_id = self.scope.wrapped_esm_id(dep_id).unwrap();

module.body.push(
esm_id
.clone()
.assign_to(module_ident.clone())
.into_module_item("merge_direct_import"),
);

let plan = ctx.plan.normal.get(&dep_id);
let default_plan;
Expand All @@ -158,6 +157,23 @@ where
.merge_deps(ctx, false, module, plan, &dep_info, false)
.context("failed to merge dependencies")?;

// Required to handle edge cases liek https://github.com/denoland/deno/issues/8530
for specifier in specifiers {
match specifier {
Specifier::Specific { local, alias } => {
let i = alias.clone().unwrap_or_else(|| local.clone());

let from = esm_id.clone().into_ident().make_member(i.clone());

module.body.push(
from.assign_to(i.with_ctxt(src.export_ctxt))
.into_module_item("namespace_with_normal"),
);
}
Specifier::Namespace { .. } => continue,
}
}

self.handle_import_deps(ctx, &dep_info, &mut module, false);

module
Expand Down Expand Up @@ -336,8 +352,8 @@ where
.iter()
.find(|(src, _)| src.module_id == dep.id);

if let Some((_, specifiers)) = res {
self.merge_direct_import(ctx, dep.id, &specifiers)?
if let Some((src, specifiers)) = res {
self.merge_direct_import(ctx, dep.id, &src, &specifiers)?
} else {
// Common js requires different planning strategy.
self.merge_transitive_import(ctx, dep.id)?
Expand Down
28 changes: 15 additions & 13 deletions bundler/src/bundler/import/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,19 @@ where
idents_to_deglob: HashSet<Id>,
}

impl RawImports {
fn insert(&mut self, import: &ImportDecl) {
for prev in self.imports.iter_mut() {
if prev.src.value == import.src.value {
prev.specifiers.extend(import.specifiers.clone());
return;
}
}

self.imports.push(import.clone());
}
}

impl<L, R> ImportHandler<'_, '_, L, R>
where
L: Load,
Expand Down Expand Up @@ -217,7 +230,7 @@ where
}
}

self.info.imports.push(import.clone());
self.info.insert(&import);
return import;
}

Expand Down Expand Up @@ -306,17 +319,6 @@ where

if use_ns {
wrapping_required.push(import.src.value.clone());

import.specifiers.retain(|s| match s {
ImportSpecifier::Namespace(_) => true,
_ => false,
});

debug_assert_ne!(
import.specifiers,
vec![],
"forced_ns should be modified only if a namespace import specifier exist"
);
} else {
// De-glob namespace imports
import.specifiers.retain(|s| match s {
Expand Down Expand Up @@ -506,7 +508,7 @@ where
};

if self.top_level {
self.info.imports.push(decl);
self.info.insert(&decl);
return Expr::Call(e);
}

Expand Down
11 changes: 11 additions & 0 deletions bundler/tests/deno.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,17 @@ fn deno_8481_1() {
)
}

#[test]
fn deno_8530() {
run("tests/deno/deno-8530/input/entry.ts", &[])
}

#[test]
#[ignore]
fn deno_8545() {
run("tests/deno/deno-8545/input/entry.ts", &[])
}

#[test]
fn merging_order_01() {
run(
Expand Down
9 changes: 9 additions & 0 deletions bundler/tests/deno/deno-8530/input/entry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Head from "https://deno.land/x/aleph/head.ts"
import * as Head2 from "https://deno.land/x/aleph/head.ts"
console.log(Head, Head2);
if (typeof Head !== 'function') {
throw new Error()
}
if (typeof Head2 !== 'object') {
throw new Error()
}
18 changes: 18 additions & 0 deletions bundler/tests/deno/deno-8545/input/entry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Application, Router } from "https://raw.githubusercontent.com/kdy1/oak-bundle-issue/master/deps.ts";

const app = new Application();
const router = new Router();

router.get("/", (ctx) => {
ctx.response.body = "Index Page";
});

router.get("/users", (ctx) => {
ctx.response.body = "Users Page";
});

app.use(router.routes());
app.use(router.allowedMethods());

console.log(`Now listening on http://0.0.0.0:3000`);
await app.listen("0.0.0.0:3000");
2 changes: 1 addition & 1 deletion ecmascript/codegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ include = ["Cargo.toml", "src/**/*.rs"]
license = "Apache-2.0/MIT"
name = "swc_ecma_codegen"
repository = "https://github.com/swc-project/swc.git"
version = "0.41.1"
version = "0.41.2"

[dependencies]
bitflags = "1"
Expand Down
5 changes: 4 additions & 1 deletion ecmascript/codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2463,8 +2463,11 @@ fn escape<'s>(cm: &SourceMap, span: Span, s: &'s str, single_quote: Option<bool>
}
'u' => match orig_iter.next() {
Some('{') => {
buf.push('{');
loop {
if orig_iter.next() == Some('}') {
let ch = orig_iter.next();
buf.extend(ch);
if ch == Some('}') {
break;
}
}
Expand Down
16 changes: 16 additions & 0 deletions ecmascript/codegen/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,22 @@ fn integration_01_reduced_01() {
);
}

#[test]
fn dneo_8541_1() {
test_from_to(
"React.createElement('span', null, '\\u{b7}');",
"React.createElement('span', null, '\\u{b7}');",
);
}

#[test]
fn dneo_8541_2() {
test_from_to(
"React.createElement('span', null, '\\u00b7');",
"React.createElement('span', null, '\\u00b7');",
);
}

#[derive(Debug, Clone)]
struct Buf(Arc<RwLock<Vec<u8>>>);
impl Write for Buf {
Expand Down
2 changes: 1 addition & 1 deletion ecmascript/codegen/tests/references/20aca21e32bf7772.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
('\u');
('\u{10FFFF}');
2 changes: 1 addition & 1 deletion ecmascript/codegen/tests/references/37c0f5275362d1c9.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
"\u";
"\u{00000000034}";
2 changes: 1 addition & 1 deletion ecmascript/codegen/tests/references/4a0d9236bc523b77.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
('\u');
('\u{0000000000F8}');
2 changes: 1 addition & 1 deletion ecmascript/codegen/tests/references/78e1b8a4f3318967.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
"\u\u";
"\u{714E}\u{8336}";
2 changes: 1 addition & 1 deletion ecmascript/codegen/tests/references/cf0eb6e6c4317c33.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
('\u');
('\u{00F8}');
2 changes: 1 addition & 1 deletion ecmascript/codegen/tests/references/d81d71f4121e3193.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
('\u');
('\u{0}');
2 changes: 1 addition & 1 deletion ecmascript/codegen/tests/references/e9682c37a1a959e1.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
"\u\u\u";
"\u{20BB7}\u{91CE}\u{5BB6}";

0 comments on commit ea6beaa

Please sign in to comment.