swc_ecma_transforms:
 - don't convert typeof to _typeof if not necessary (#250)
 - fix imports of `@swc/helpers` (#248).
This commit is contained in:
강동윤 2019-02-20 20:02:22 +09:00 committed by GitHub
parent 601f0feb14
commit 162dee5518
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 107 additions and 19 deletions

View File

@ -24,21 +24,6 @@ pub struct TypeOfSymbol;
impl Fold<Expr> for TypeOfSymbol {
fn fold(&mut self, expr: Expr) -> Expr {
fn should_work(node: &Expr) -> bool {
struct Visitor {
found: bool,
}
impl Visit<UnaryExpr> for Visitor {
fn visit(&mut self, e: &UnaryExpr) {
if e.op == op!("typeof") {
self.found = true
}
}
}
let mut v = Visitor { found: false };
node.visit_with(&mut v);
v.found
}
// fast path
if !should_work(&expr) {
return expr;
@ -64,3 +49,102 @@ impl Fold<Expr> for TypeOfSymbol {
}
}
}
impl Fold<BinExpr> for TypeOfSymbol {
fn fold(&mut self, expr: BinExpr) -> BinExpr {
match expr.op {
op!("==") | op!("!=") | op!("===") | op!("!==") => {}
_ => return expr.fold_children(self),
}
match *expr.left {
Expr::Unary(UnaryExpr {
op: op!("typeof"), ..
}) => {
if is_non_symbol_literal(&expr.right) {
return expr;
}
}
_ => {}
}
match *expr.right {
Expr::Unary(UnaryExpr {
op: op!("typeof"), ..
}) => {
if is_non_symbol_literal(&expr.left) {
return expr;
}
}
_ => {}
}
expr.fold_children(self)
}
}
fn should_work(node: &Expr) -> bool {
struct Visitor {
found: bool,
}
impl Visit<UnaryExpr> for Visitor {
fn visit(&mut self, e: &UnaryExpr) {
if e.op == op!("typeof") {
self.found = true
}
}
}
let mut v = Visitor { found: false };
node.visit_with(&mut v);
v.found
}
fn is_non_symbol_literal(e: &Expr) -> bool {
match *e {
Expr::Lit(Lit::Str(Str {
value: js_word!("undefined"),
..
}))
| Expr::Lit(Lit::Str(Str {
value: js_word!("object"),
..
}))
| Expr::Lit(Lit::Str(Str {
value: js_word!("boolean"),
..
}))
| Expr::Lit(Lit::Str(Str {
value: js_word!("number"),
..
}))
| Expr::Lit(Lit::Str(Str {
value: js_word!("string"),
..
}))
| Expr::Lit(Lit::Str(Str {
value: js_word!("function"),
..
})) => true,
_ => false,
}
}
#[cfg(test)]
mod tests {
use super::*;
test!(
::swc_ecma_parser::Syntax::default(),
|_| TypeOfSymbol,
dont_touch_non_symbol_comparison,
"typeof window !== 'undefined'",
"typeof window !== 'undefined'"
);
test!(
::swc_ecma_parser::Syntax::default(),
|_| TypeOfSymbol,
dont_touch_non_symbol_comparison_02,
"'undefined' !== typeof window",
"'undefined' !== typeof window"
);
}

View File

@ -81,9 +81,11 @@ impl Visit<ImportDecl> for ImportAnalyzer {
_ => false,
}
{
self.scope
.import_types
.insert(import.src.value.clone(), true);
if &*import.src.value != "@swc/helpers" {
self.scope
.import_types
.insert(import.src.value.clone(), true);
}
} else {
for s in &import.specifiers {
match *s {

View File

@ -228,7 +228,9 @@ impl Scope {
})
.or_insert_with(|| Some((specifier.local.sym.clone(), specifier.local.span)));
self.import_types.insert(import.src.value, true);
if &*import.src.value != "@swc/helpers" {
self.import_types.insert(import.src.value, true);
}
} else {
self.imports
.entry(import.src.value.clone())