fix(es/modules): Handle module references in binding idents (#5055)

This commit is contained in:
magic-akari 2022-06-28 18:47:46 +08:00 committed by GitHub
parent c4fe6e2286
commit e13364f976
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 172 additions and 27 deletions

View File

@ -4,7 +4,7 @@ use swc_common::{
util::take::Take,
DUMMY_SP,
};
use swc_ecma_ast::{Id, Ident, *};
use swc_ecma_ast::*;
use swc_ecma_utils::{undefined, ExprFactory, IntoIndirectCall};
use swc_ecma_visit::{noop_visit_mut_type, VisitMut, VisitMutWith};
@ -41,32 +41,28 @@ pub(crate) struct ModuleRefRewriter {
impl VisitMut for ModuleRefRewriter {
noop_visit_mut_type!();
/// replace bar in binding pattern
/// const foo = { bar }
fn visit_mut_prop(&mut self, n: &mut Prop) {
match n {
Prop::Shorthand(shorthand) => {
if let Some(expr) = self.map_module_ref_ident(shorthand) {
*n = KeyValueProp {
key: shorthand.take().into(),
value: Box::new(expr),
}
.into()
}
}
_ => n.visit_mut_children_with(self),
}
}
fn visit_mut_expr(&mut self, n: &mut Expr) {
match n {
Expr::Ident(ref_ident) => {
if let Some((mod_ident, mod_prop)) = self.import_map.get(&ref_ident.to_id()) {
let mut mod_ident = mod_ident.clone();
let span = ref_ident.span.with_ctxt(mod_ident.span.ctxt);
mod_ident.span = span;
let mod_expr = if self.lazy_record.contains(&mod_ident.to_id()) {
mod_ident.as_call(span, Default::default())
} else {
mod_ident.into()
};
if let Some(imported_name) = mod_prop {
let prop = prop_name(imported_name, DUMMY_SP).into();
*n = MemberExpr {
obj: Box::new(mod_expr),
span,
prop,
}
.into();
} else {
*n = mod_expr;
}
if let Some(expr) = self.map_module_ref_ident(ref_ident) {
*n = expr;
}
}
@ -136,4 +132,33 @@ impl ModuleRefRewriter {
n.visit_mut_with(self);
self.top_level = top_level;
}
fn map_module_ref_ident(&mut self, ref_ident: &Ident) -> Option<Expr> {
self.import_map
.get(&ref_ident.to_id())
.map(|(mod_ident, mod_prop)| -> Expr {
let mut mod_ident = mod_ident.clone();
let span = ref_ident.span.with_ctxt(mod_ident.span.ctxt);
mod_ident.span = span;
let mod_expr = if self.lazy_record.contains(&mod_ident.to_id()) {
mod_ident.as_call(span, Default::default())
} else {
mod_ident.into()
};
if let Some(imported_name) = mod_prop {
let prop = prop_name(imported_name, DUMMY_SP).into();
MemberExpr {
obj: Box::new(mod_expr),
span,
prop,
}
.into()
} else {
mod_expr
}
})
}
}

View File

@ -13,6 +13,6 @@ define([
});
_foo = _interopRequireDefault(_foo);
const bar = {
foo
foo: _foo.default
};
});

View File

@ -8,5 +8,5 @@ Object.defineProperty(exports, "bar", {
});
const _foo = _interopRequireDefault(require("foo"));
const bar = {
foo
foo: _foo.default
};

View File

@ -16,6 +16,6 @@
});
_foo = _interopRequireDefault(_foo);
const bar = {
foo
foo: _foo.default
};
});

View File

@ -0,0 +1,7 @@
import foo from "foo";
import { bar } from "bar";
import * as baz from "baz";
export default { foo, baz, baz };
const x = { foo, bar, baz };
export const y = { foo, bar, baz };

View File

@ -0,0 +1,39 @@
define([
"require",
"exports",
"foo",
"bar",
"baz"
], function(require, exports, _foo, _bar, _baz) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
get: all[name],
enumerable: true
});
}
_export(exports, {
default: ()=>_default,
y: ()=>y
});
_foo = _interopRequireDefault(_foo);
_baz = _interopRequireWildcard(_baz);
var _default = {
foo: _foo.default,
baz: _baz,
baz: _baz
};
const x = {
foo: _foo.default,
bar: _bar.bar,
baz: _baz
};
const y = {
foo: _foo.default,
bar: _bar.bar,
baz: _baz
};
});

View File

@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
get: all[name],
enumerable: true
});
}
_export(exports, {
default: ()=>_default,
y: ()=>y
});
const _foo = _interopRequireDefault(require("foo"));
const _bar = require("bar");
const _baz = _interopRequireWildcard(require("baz"));
var _default = {
foo: _foo.default,
baz: _baz,
baz: _baz
};
const x = {
foo: _foo.default,
bar: _bar.bar,
baz: _baz
};
const y = {
foo: _foo.default,
bar: _bar.bar,
baz: _baz
};

View File

@ -0,0 +1,42 @@
(function(global, factory) {
if (typeof module === "object" && typeof module.exports === "object") factory(exports, require("foo"), require("bar"), require("baz"));
else if (typeof define === "function" && define.amd) define([
"exports",
"foo",
"bar",
"baz"
], factory);
else if (global = typeof globalThis !== "undefined" ? globalThis : global || self) factory(global.input = {}, global.foo, global.bar, global.baz);
})(this, function(exports, _foo, _bar, _baz) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
get: all[name],
enumerable: true
});
}
_export(exports, {
default: ()=>_default,
y: ()=>y
});
_foo = _interopRequireDefault(_foo);
_baz = _interopRequireWildcard(_baz);
var _default = {
foo: _foo.default,
baz: _baz,
baz: _baz
};
const x = {
foo: _foo.default,
bar: _bar.bar,
baz: _baz
};
const y = {
foo: _foo.default,
bar: _bar.bar,
baz: _baz
};
});