mirror of
https://github.com/swc-project/swc.git
synced 2024-12-24 14:16:12 +03:00
Fixes (#294)
swc_ecma_transforms: - block_scoped_fn: don't fold self-modifing functions. (#288). - fixer: fix assignment in conditional expression (#293) - make resolver work with self modifying function (#292)
This commit is contained in:
parent
f49fbea2af
commit
21f3f792d1
@ -1,3 +1,4 @@
|
||||
use crate::util::UsageFinder;
|
||||
use ast::*;
|
||||
use swc_common::{Fold, FoldWith, Spanned, DUMMY_SP};
|
||||
|
||||
@ -15,7 +16,12 @@ impl Fold<Vec<Stmt>> for BlockScopedFns {
|
||||
extra_stmts.push(stmt)
|
||||
} else {
|
||||
match stmt {
|
||||
Stmt::Decl(Decl::Fn(decl)) => stmts.push(Stmt::Decl(Decl::Var(VarDecl {
|
||||
Stmt::Decl(Decl::Fn(decl)) => {
|
||||
if UsageFinder::find(&decl.ident, &decl.function) {
|
||||
extra_stmts.push(Stmt::Decl(Decl::Fn(decl)));
|
||||
continue;
|
||||
}
|
||||
stmts.push(Stmt::Decl(Decl::Var(VarDecl {
|
||||
span: DUMMY_SP,
|
||||
kind: VarDeclKind::Let,
|
||||
decls: vec![VarDeclarator {
|
||||
@ -28,7 +34,8 @@ impl Fold<Vec<Stmt>> for BlockScopedFns {
|
||||
definite: false,
|
||||
}],
|
||||
declare: false,
|
||||
}))),
|
||||
})))
|
||||
}
|
||||
_ => extra_stmts.push(stmt.fold_children(self)),
|
||||
}
|
||||
}
|
||||
@ -109,6 +116,68 @@ function foo(scope) {
|
||||
};
|
||||
scope.startOperation = startOperation;
|
||||
}
|
||||
"
|
||||
);
|
||||
|
||||
test!(
|
||||
::swc_ecma_parser::Syntax::default(),
|
||||
|_| BlockScopedFns,
|
||||
issue_288_1,
|
||||
"function components_Link_extends() { components_Link_extends = Object.assign || function \
|
||||
(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for \
|
||||
(var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { \
|
||||
target[key] = source[key]; } } } return target; }; return \
|
||||
components_Link_extends.apply(this, arguments); }
|
||||
|
||||
",
|
||||
"function components_Link_extends() { components_Link_extends = Object.assign || function \
|
||||
(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for \
|
||||
(var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { \
|
||||
target[key] = source[key]; } } } return target; }; return \
|
||||
components_Link_extends.apply(this, arguments); }
|
||||
|
||||
"
|
||||
);
|
||||
|
||||
test!(
|
||||
::swc_ecma_parser::Syntax::default(),
|
||||
|_| BlockScopedFns,
|
||||
issue_288_2,
|
||||
"function _extends() {
|
||||
module.exports = _extends = Object.assign || function (target) {
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
var source = arguments[i];
|
||||
|
||||
for (var key in source) {
|
||||
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
||||
target[key] = source[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
};
|
||||
|
||||
return _extends.apply(this, arguments);
|
||||
}
|
||||
",
|
||||
"function _extends() {
|
||||
module.exports = _extends = Object.assign || function (target) {
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
var source = arguments[i];
|
||||
|
||||
for (var key in source) {
|
||||
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
||||
target[key] = source[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
};
|
||||
|
||||
return _extends.apply(this, arguments);
|
||||
}
|
||||
"
|
||||
);
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::util::UsageFinder;
|
||||
use ast::*;
|
||||
use swc_common::{Fold, FoldWith, Visit, VisitWith};
|
||||
use swc_common::{Fold, FoldWith};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
@ -74,33 +75,6 @@ impl Fold<AssignExpr> for FnName {
|
||||
}
|
||||
}
|
||||
|
||||
struct UsageFinder<'a> {
|
||||
ident: &'a Ident,
|
||||
found: bool,
|
||||
}
|
||||
|
||||
impl<'a> Visit<Ident> for UsageFinder<'a> {
|
||||
fn visit(&mut self, i: &Ident) {
|
||||
if i.span.ctxt() == self.ident.span.ctxt() && i.sym == self.ident.sym {
|
||||
self.found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> UsageFinder<'a> {
|
||||
fn find<N>(ident: &'a Ident, node: &N) -> bool
|
||||
where
|
||||
N: VisitWith<Self>,
|
||||
{
|
||||
let mut v = UsageFinder {
|
||||
ident,
|
||||
found: false,
|
||||
};
|
||||
node.visit_with(&mut v);
|
||||
v.found
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_for {
|
||||
($T:tt) => {
|
||||
impl Fold<$T> for Renamer {
|
||||
|
@ -227,31 +227,8 @@ impl<'a> Fold<VarDeclarator> for Resolver<'a> {
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let is_class_like = match decl.init {
|
||||
Some(box Expr::Fn(FnExpr { ref ident, .. }))
|
||||
if cur_name.is_some()
|
||||
&& ident.as_ref().map(|v| &v.sym) == cur_name.as_ref().map(|v| &v.0) =>
|
||||
{
|
||||
true
|
||||
}
|
||||
|
||||
Some(box Expr::Call(CallExpr {
|
||||
callee: ExprOrSuper::Expr(box Expr::Fn(FnExpr { ident: None, .. })),
|
||||
..
|
||||
}))
|
||||
| Some(box Expr::Call(CallExpr {
|
||||
callee:
|
||||
ExprOrSuper::Expr(box Expr::Paren(ParenExpr {
|
||||
expr: box Expr::Fn(FnExpr { ident: None, .. }),
|
||||
..
|
||||
})),
|
||||
..
|
||||
})) => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
let old_def = self.cur_defining.take();
|
||||
self.cur_defining = if is_class_like { cur_name } else { None }.into();
|
||||
self.cur_defining = cur_name;
|
||||
|
||||
let init = decl.init.fold_children(self);
|
||||
|
||||
|
@ -632,3 +632,35 @@ identical!(
|
||||
}
|
||||
}"
|
||||
);
|
||||
|
||||
identical!(
|
||||
issue_292_1,
|
||||
"var __assign = function () {
|
||||
__assign = Object.assign || function __assign(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
||||
}
|
||||
|
||||
return t;
|
||||
};
|
||||
|
||||
return __assign.apply(this, arguments);
|
||||
};"
|
||||
);
|
||||
|
||||
identical!(
|
||||
issue_292_2,
|
||||
"__assign = Object.assign || function __assign(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
||||
}
|
||||
|
||||
return t;
|
||||
};
|
||||
|
||||
__assign.apply(this, arguments);"
|
||||
);
|
||||
|
@ -346,7 +346,7 @@ impl Fold<Expr> for Fixer {
|
||||
|
||||
Expr::Cond(expr) => {
|
||||
let test = match *expr.test {
|
||||
e @ Expr::Seq(..) => box e.wrap_with_paren(),
|
||||
e @ Expr::Seq(..) | e @ Expr::Assign(..) => box e.wrap_with_paren(),
|
||||
_ => expr.test,
|
||||
};
|
||||
|
||||
@ -686,4 +686,16 @@ var store = global[SHARED] || (global[SHARED] = {});
|
||||
copyright: '© 2018 Denis Pushkarev (zloirock.ru)'
|
||||
});"
|
||||
);
|
||||
|
||||
identical!(
|
||||
issue_293_1,
|
||||
"for (var e in a) a.hasOwnProperty(e) && ((b = a[e]) ? this[e] = b(c) : 'target' === e ? \
|
||||
this.target = d : this[e] = c[e]);"
|
||||
);
|
||||
|
||||
identical!(
|
||||
issue_293_2,
|
||||
"(a = rb ? zb(a, c) : Ab(a, c)) ? (b = nb.getPooled(ub.beforeInput, b, c, d), b.data = a, \
|
||||
Ra(b)) : b = null;"
|
||||
);
|
||||
}
|
||||
|
@ -977,6 +977,44 @@ impl Fold<Span> for DropSpan {
|
||||
}
|
||||
}
|
||||
|
||||
/// Finds usage of `ident`
|
||||
pub(crate) struct UsageFinder<'a> {
|
||||
ident: &'a Ident,
|
||||
found: bool,
|
||||
}
|
||||
|
||||
impl<'a> Visit<MemberExpr> for UsageFinder<'a> {
|
||||
fn visit(&mut self, e: &MemberExpr) {
|
||||
e.obj.visit_with(self);
|
||||
|
||||
if e.computed {
|
||||
e.prop.visit_with(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Visit<Ident> for UsageFinder<'a> {
|
||||
fn visit(&mut self, i: &Ident) {
|
||||
if i.span.ctxt() == self.ident.span.ctxt() && i.sym == self.ident.sym {
|
||||
self.found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> UsageFinder<'a> {
|
||||
pub(crate) fn find<N>(ident: &'a Ident, node: &N) -> bool
|
||||
where
|
||||
N: VisitWith<Self>,
|
||||
{
|
||||
let mut v = UsageFinder {
|
||||
ident,
|
||||
found: false,
|
||||
};
|
||||
node.visit_with(&mut v);
|
||||
v.found
|
||||
}
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
pub(crate) static ref CM: Arc<SourceMap> =
|
||||
{ Arc::new(SourceMap::new(FilePathMapping::empty())) };
|
||||
|
Loading…
Reference in New Issue
Block a user