Skip to content

Commit

Permalink
Adapt for breaking swc AST change
Browse files Browse the repository at this point in the history
  • Loading branch information
mischnic committed Mar 16, 2024
1 parent 051299d commit d263ff5
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 136 deletions.
103 changes: 43 additions & 60 deletions packages/transformers/js/core/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::collections::{HashMap, HashSet};
use swc_core::common::{sync::Lrc, Mark, Span, DUMMY_SP};
use swc_core::ecma::ast::*;
use swc_core::ecma::atoms::{js_word, JsWord};
use swc_core::ecma::visit::{Visit, VisitWith};
use swc_core::ecma::visit::{noop_visit_type, Visit, VisitWith};

macro_rules! collect_visit_fn {
($name:ident, $type:ident) => {
Expand Down Expand Up @@ -822,29 +822,27 @@ impl Visit for Collect {
self.in_assign = false;
node.right.visit_with(self);

if let PatOrExpr::Pat(pat) = &node.left {
if has_binding_identifier(pat, &"exports".into(), self.unresolved_mark) {
// Must wrap for cases like
// ```
// function logExports() {
// console.log(exports);
// }
// exports.test = 2;
// logExports();
// exports = {test: 4};
// logExports();
// ```
self.static_cjs_exports = false;
self.has_cjs_exports = true;
self.should_wrap = true;
self.add_bailout(node.span, BailoutReason::ExportsReassignment);
} else if has_binding_identifier(pat, &"module".into(), self.unresolved_mark) {
// Same for `module`. If it is reassigned we can't correctly statically analyze.
self.static_cjs_exports = false;
self.has_cjs_exports = true;
self.should_wrap = true;
self.add_bailout(node.span, BailoutReason::ModuleReassignment);
}
if has_binding_identifier(&node.left, &"exports".into(), self.unresolved_mark) {
// Must wrap for cases like
// ```
// function logExports() {
// console.log(exports);
// }
// exports.test = 2;
// logExports();
// exports = {test: 4};
// logExports();
// ```
self.static_cjs_exports = false;
self.has_cjs_exports = true;
self.should_wrap = true;
self.add_bailout(node.span, BailoutReason::ExportsReassignment);
} else if has_binding_identifier(&node.left, &"module".into(), self.unresolved_mark) {
// Same for `module`. If it is reassigned we can't correctly statically analyze.
self.static_cjs_exports = false;
self.has_cjs_exports = true;
self.should_wrap = true;
self.add_bailout(node.span, BailoutReason::ModuleReassignment);
}
}

Expand Down Expand Up @@ -1096,7 +1094,7 @@ impl Collect {
}
ObjectPatProp::Assign(assign) => {
if self.non_const_bindings.contains_key(&id!(assign.key)) {
idents.push(assign.key.clone());
idents.push(assign.key.id.clone());
}
}
ObjectPatProp::Rest(rest) => {
Expand Down Expand Up @@ -1124,43 +1122,28 @@ impl Collect {
}
}

fn has_binding_identifier(node: &Pat, sym: &JsWord, unresolved_mark: Mark) -> bool {
match node {
Pat::Ident(ident) => {
if ident.id.sym == *sym && is_unresolved(&ident, unresolved_mark) {
return true;
}
}
Pat::Object(object) => {
for prop in &object.props {
match prop {
ObjectPatProp::KeyValue(kv) => {
if has_binding_identifier(&kv.value, sym, unresolved_mark) {
return true;
}
}
ObjectPatProp::Assign(assign) => {
if assign.key.sym == *sym && is_unresolved(&assign.key, unresolved_mark) {
return true;
}
}
ObjectPatProp::Rest(rest) => {
if has_binding_identifier(&rest.arg, sym, unresolved_mark) {
return true;
}
}
}
}
}
Pat::Array(array) => {
for el in array.elems.iter().flatten() {
if has_binding_identifier(el, sym, unresolved_mark) {
return true;
}
fn has_binding_identifier(node: &AssignTarget, sym: &JsWord, unresolved_mark: Mark) -> bool {
pub struct BindingIdentFinder<'a> {
sym: &'a JsWord,
unresolved_mark: Mark,
found: bool,
}

impl Visit for BindingIdentFinder<'_> {
noop_visit_type!();

fn visit_binding_ident(&mut self, ident: &BindingIdent) {
if ident.id.sym == *self.sym && is_unresolved(&ident, self.unresolved_mark) {
self.found = true;
}
}
_ => {}
}

false
let mut visitor = BindingIdentFinder {
sym,
unresolved_mark,
found: false,
};
node.visit_with(&mut visitor);
visitor.found
}
118 changes: 58 additions & 60 deletions packages/transformers/js/core/src/env_replacer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,16 @@ impl<'a> Fold for EnvReplacer<'a> {
// Replace assignments to process.browser with `true`
// TODO: this seems questionable but we did it in the JS version??
if let Expr::Assign(ref assign) = node {
if let PatOrExpr::Pat(ref pat) = assign.left {
if let Pat::Expr(ref expr) = &**pat {
if let Expr::Member(ref member) = &**expr {
if self.is_browser
&& match_member_expr(member, vec!["process", "browser"], self.unresolved_mark)
{
let mut res = assign.clone();
res.right = Box::new(Expr::Lit(Lit::Bool(Bool {
value: true,
span: DUMMY_SP,
})));
return Expr::Assign(res);
}
}
if let AssignTarget::Simple(SimpleAssignTarget::Member(member)) = &assign.left {
if self.is_browser
&& match_member_expr(member, vec!["process", "browser"], self.unresolved_mark)
{
let mut res = assign.clone();
res.right = Box::new(Expr::Lit(Lit::Bool(Bool {
value: true,
span: DUMMY_SP,
})));
return Expr::Assign(res);
}
}
}
Expand Down Expand Up @@ -87,56 +83,58 @@ impl<'a> Fold for EnvReplacer<'a> {
return node.fold_children_with(self);
}

let expr = match &assign.left {
PatOrExpr::Pat(pat) => {
if let Pat::Expr(expr) = &**pat {
Some(&**expr)
} else if let Expr::Member(member) = &*assign.right {
if assign.op == AssignOp::Assign
&& match_member_expr(member, vec!["process", "env"], self.unresolved_mark)
{
let mut decls = vec![];
self.collect_pat_bindings(pat, &mut decls);
// process.env.FOO = ...;
if let AssignTarget::Simple(SimpleAssignTarget::Member(member)) = &assign.left {
if let Expr::Member(obj) = &*member.obj {
if match_member_expr(obj, vec!["process", "env"], self.unresolved_mark) {
self.emit_mutating_error(assign.span);
return *assign.right.clone().fold_with(self);
}
}
}

let mut exprs: Vec<Box<Expr>> = decls
.iter()
.map(|decl| {
Box::new(Expr::Assign(AssignExpr {
span: DUMMY_SP,
op: AssignOp::Assign,
left: PatOrExpr::Pat(Box::new(decl.name.clone())),
right: Box::new(if let Some(init) = &decl.init {
*init.clone()
} else {
Expr::Ident(get_undefined_ident(self.unresolved_mark))
}),
}))
})
.collect();
if let Expr::Member(member) = &*assign.right {
if assign.op == AssignOp::Assign
&& match_member_expr(member, vec!["process", "env"], self.unresolved_mark)
{
let pat = match &assign.left {
// ({x, y, z, ...} = process.env);
AssignTarget::Simple(SimpleAssignTarget::Ident(ident)) => {
Some(Pat::Ident(ident.clone()))
}
// foo = process.env;
AssignTarget::Pat(AssignTargetPat::Object(obj)) => Some(obj.clone().into()),
_ => None,
};
if let Some(pat) = pat {
let mut decls = vec![];
self.collect_pat_bindings(&pat, &mut decls);

exprs.push(Box::new(Expr::Object(ObjectLit {
span: DUMMY_SP,
props: vec![],
})));
let mut exprs: Vec<Box<Expr>> = decls
.iter()
.map(|decl| {
Box::new(Expr::Assign(AssignExpr {
span: DUMMY_SP,
op: AssignOp::Assign,
left: decl.name.clone().try_into().unwrap(),
right: Box::new(if let Some(init) = &decl.init {
*init.clone()
} else {
Expr::Ident(get_undefined_ident(self.unresolved_mark))
}),
}))
})
.collect();

return Expr::Seq(SeqExpr {
span: assign.span,
exprs,
});
}
None
} else {
None
}
}
PatOrExpr::Expr(expr) => Some(&**expr),
};
exprs.push(Box::new(Expr::Object(ObjectLit {
span: DUMMY_SP,
props: vec![],
})));

if let Some(Expr::Member(MemberExpr { obj, .. })) = &expr {
if let Expr::Member(member) = &**obj {
if match_member_expr(member, vec!["process", "env"], self.unresolved_mark) {
self.emit_mutating_error(assign.span);
return *assign.right.clone().fold_with(self);
return Expr::Seq(SeqExpr {
span: assign.span,
exprs,
});
}
}
}
Expand Down
18 changes: 5 additions & 13 deletions packages/transformers/js/core/src/hoist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -874,21 +874,13 @@ impl<'a> Fold for Hoist<'a> {
return node.fold_children_with(self);
}

let expr = match &node.left {
PatOrExpr::Expr(expr) => expr,
PatOrExpr::Pat(pat) => match &**pat {
Pat::Expr(expr) => expr,
_ => return node.fold_children_with(self),
},
};

if let Expr::Member(member) = &**expr {
if let AssignTarget::Simple(SimpleAssignTarget::Member(member)) = &node.left {
if match_member_expr(member, vec!["module", "exports"], self.unresolved_mark) {
let ident = BindingIdent::from(self.get_export_ident(member.span, &"*".into()));
return AssignExpr {
span: node.span,
op: node.op,
left: PatOrExpr::Pat(Box::new(Pat::Ident(ident))),
left: AssignTarget::Simple(SimpleAssignTarget::Ident(ident.into())),
right: node.right.fold_with(self),
};
}
Expand Down Expand Up @@ -940,13 +932,13 @@ impl<'a> Fold for Hoist<'a> {
span: node.span,
op: node.op,
left: if self.collect.static_cjs_exports {
PatOrExpr::Pat(Box::new(Pat::Ident(ident)))
AssignTarget::Simple(SimpleAssignTarget::Ident(ident.into()))
} else {
PatOrExpr::Pat(Box::new(Pat::Expr(Box::new(Expr::Member(MemberExpr {
AssignTarget::Simple(SimpleAssignTarget::Member(MemberExpr {
span: member.span,
obj: Box::new(Expr::Ident(ident.id)),
prop: member.prop.clone().fold_with(self),
})))))
}))
},
right: node.right.fold_with(self),
};
Expand Down
6 changes: 3 additions & 3 deletions packages/transformers/js/core/src/modules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,11 +211,11 @@ impl ESMFold {
ModuleItem::Stmt(Stmt::Expr(ExprStmt {
expr: Box::new(Expr::Assign(AssignExpr {
op: AssignOp::Assign,
left: PatOrExpr::Expr(Box::new(Expr::Member(MemberExpr {
left: AssignTarget::Simple(SimpleAssignTarget::Member(MemberExpr {
obj: Box::new(Expr::Ident(Ident::new("exports".into(), DUMMY_SP))),
prop: MemberProp::Ident(Ident::new(name, DUMMY_SP)),
span: DUMMY_SP,
}))),
})),
right: Box::new(right),
span: DUMMY_SP,
})),
Expand Down Expand Up @@ -584,7 +584,7 @@ impl Fold for ESMFold {
if self.in_export_decl {
self.create_export(
node.key.sym.clone(),
Expr::Ident(node.key.clone()),
Expr::Ident(node.key.id.clone()),
DUMMY_SP,
);
}
Expand Down

0 comments on commit d263ff5

Please sign in to comment.