From 763b20dd9c549d42871f6d0d1e7e4608ed9e0bf1 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Sun, 12 Dec 2021 02:08:27 +0100 Subject: [PATCH] Fix wrong `does not export` error because of missing symbols (#7432) --- .../es6/re-export-renamed2/a.js | 3 + .../es6/re-export-renamed2/b.js | 4 ++ .../es6/re-export-renamed2/c.js | 1 + .../integration-tests/test/scope-hoisting.js | 12 ++++ packages/transformers/js/core/src/hoist.rs | 58 ++++++++++++++++--- 5 files changed, 70 insertions(+), 8 deletions(-) create mode 100644 packages/core/integration-tests/test/integration/scope-hoisting/es6/re-export-renamed2/a.js create mode 100644 packages/core/integration-tests/test/integration/scope-hoisting/es6/re-export-renamed2/b.js create mode 100644 packages/core/integration-tests/test/integration/scope-hoisting/es6/re-export-renamed2/c.js diff --git a/packages/core/integration-tests/test/integration/scope-hoisting/es6/re-export-renamed2/a.js b/packages/core/integration-tests/test/integration/scope-hoisting/es6/re-export-renamed2/a.js new file mode 100644 index 00000000000..1077b636aca --- /dev/null +++ b/packages/core/integration-tests/test/integration/scope-hoisting/es6/re-export-renamed2/a.js @@ -0,0 +1,3 @@ +import { x } from './b.js'; + +output = x; diff --git a/packages/core/integration-tests/test/integration/scope-hoisting/es6/re-export-renamed2/b.js b/packages/core/integration-tests/test/integration/scope-hoisting/es6/re-export-renamed2/b.js new file mode 100644 index 00000000000..f2cfbdb2bf0 --- /dev/null +++ b/packages/core/integration-tests/test/integration/scope-hoisting/es6/re-export-renamed2/b.js @@ -0,0 +1,4 @@ +export { x as y } from './c.js' + +export const x = 'foobar'; + diff --git a/packages/core/integration-tests/test/integration/scope-hoisting/es6/re-export-renamed2/c.js b/packages/core/integration-tests/test/integration/scope-hoisting/es6/re-export-renamed2/c.js new file mode 100644 index 00000000000..0190dbd267f --- /dev/null +++ b/packages/core/integration-tests/test/integration/scope-hoisting/es6/re-export-renamed2/c.js @@ -0,0 +1 @@ +export const x = 'xyz'; diff --git a/packages/core/integration-tests/test/scope-hoisting.js b/packages/core/integration-tests/test/scope-hoisting.js index ec6ef80f641..b1632bfc83e 100644 --- a/packages/core/integration-tests/test/scope-hoisting.js +++ b/packages/core/integration-tests/test/scope-hoisting.js @@ -1039,6 +1039,18 @@ describe('scope hoisting', function () { assert.deepEqual(output, 'foobar'); }); + it('supports requiring a re-exported and renamed ES6 import (reversed order)', async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/re-export-renamed2/a.js', + ), + ); + + let output = await run(b); + assert.deepEqual(output, 'foobar'); + }); + it('supports requiring a re-exported and renamed ES6 namespace import', async function () { let b = await bundle( path.join( diff --git a/packages/transformers/js/core/src/hoist.rs b/packages/transformers/js/core/src/hoist.rs index bd755f1a56b..3bec6b11c87 100644 --- a/packages/transformers/js/core/src/hoist.rs +++ b/packages/transformers/js/core/src/hoist.rs @@ -1406,10 +1406,12 @@ impl Visit for Collect { source, }, ); - self - .exports_locals - .entry(named.orig.sym.clone()) - .or_insert_with(|| exported.sym.clone()); + if node.src.is_none() { + self + .exports_locals + .entry(named.orig.sym.clone()) + .or_insert_with(|| exported.sym.clone()); + } } ExportSpecifier::Default(default) => { self.exports.insert( @@ -1420,10 +1422,12 @@ impl Visit for Collect { source, }, ); - self - .exports_locals - .entry(default.exported.sym.clone()) - .or_insert_with(|| js_word!("default")); + if node.src.is_none() { + self + .exports_locals + .entry(default.exported.sym.clone()) + .or_insert_with(|| js_word!("default")); + } } ExportSpecifier::Namespace(namespace) => { self.exports.insert( @@ -2267,6 +2271,16 @@ mod tests { }}; } + macro_rules! assert_eq_exported_symbols { + ($m: expr, $match: expr) => {{ + let mut map = HashMap::new(); + for sym in $m { + map.insert(sym.exported, sym.local); + } + assert_eq!(map, $match); + }}; + } + macro_rules! assert_eq_set { ($m: expr, $match: expr) => {{ let mut map = HashSet::new(); @@ -3383,6 +3397,34 @@ mod tests { import "abc:bar"; "#} ); + + let (_collect, code, hoist) = parse( + r#" + export { settings as siteSettings } from "./settings"; + export const settings = "hi"; + "#, + ); + + assert_eq!( + code, + indoc! {r#" + import "abc:./settings"; + const $abc$export$a5a6e0b888b2c992 = "hi"; + "#} + ); + + assert_eq_exported_symbols!( + hoist.exported_symbols, + map! { + w!("settings") => w!("$abc$export$a5a6e0b888b2c992") + } + ); + assert_eq_imported_symbols!( + hoist.re_exports, + map! { + w!("siteSettings") => (w!("./settings"), w!("settings")) + } + ); } #[test]