Skip to content

Commit

Permalink
fix mangle syntax edge case with "==" and "!="
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Sep 22, 2021
1 parent 61155d5 commit 7ecdc28
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 9 deletions.
36 changes: 36 additions & 0 deletions internal/bundler/bundler_dce_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1687,3 +1687,39 @@ func TestDCETypeOf(t *testing.T) {
},
})
}

func TestDCETypeOfEqualsString(t *testing.T) {
dce_suite.expectBundled(t, bundled{
files: map[string]string{
"/entry.js": `
var hasBar = typeof bar !== 'undefined'
if (false) console.log(hasBar)
`,
},
entryPaths: []string{"/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
OutputFormat: config.FormatIIFE,
AbsOutputFile: "/out.js",
},
})
}

func TestDCETypeOfEqualsStringMangle(t *testing.T) {
dce_suite.expectBundled(t, bundled{
files: map[string]string{
"/entry.js": `
// Everything here should be removed as dead code due to tree shaking
var hasBar = typeof bar !== 'undefined'
if (false) console.log(hasBar)
`,
},
entryPaths: []string{"/entry.js"},
options: config.Options{
Mode: config.ModeBundle,
OutputFormat: config.FormatIIFE,
MangleSyntax: true,
AbsOutputFile: "/out.js",
},
})
}
15 changes: 15 additions & 0 deletions internal/bundler/snapshots/snapshots_dce.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ console.log("unused import");
TestDCETypeOf
---------- /out.js ----------

================================================================================
TestDCETypeOfEqualsString
---------- /out.js ----------
(() => {
// entry.js
if (false)
console.log(hasBar);
})();

================================================================================
TestDCETypeOfEqualsStringMangle
---------- /out.js ----------
(() => {
})();

================================================================================
TestDataURLLoaderRemoveUnused
---------- /out.js ----------
Expand Down
9 changes: 0 additions & 9 deletions internal/bundler/snapshots/snapshots_default.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3371,15 +3371,6 @@ var import_return_asi = __toModule(require_return_asi());
var import_return_asi2 = __toModule(require_return_asi2());
var import_return_asi3 = __toModule(require_return_asi3());

// bad-typeof.js
typeof x == "null";

// node_modules/bad-typeof.js
typeof x == "null";

// plugin-dir/node_modules/bad-typeof.js
typeof x == "null";

// equals-neg-zero.js
x === -0;

Expand Down
9 changes: 9 additions & 0 deletions internal/js_parser/js_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -13417,6 +13417,15 @@ func (p *parser) exprCanBeRemovedIfUnused(expr js_ast.Expr) bool {
case js_ast.BinOpStrictEq, js_ast.BinOpStrictNe, js_ast.BinOpComma,
js_ast.BinOpLogicalOr, js_ast.BinOpLogicalAnd, js_ast.BinOpNullishCoalescing:
return p.exprCanBeRemovedIfUnused(e.Left) && p.exprCanBeRemovedIfUnused(e.Right)

// For "==" and "!=", pretend the operator was actually "===" or "!==". If
// we know that we can convert it to "==" or "!=", then we can consider the
// operator itself to have no side effects. This matters because our mangle
// logic will convert "typeof x === 'object'" into "typeof x == 'object'"
// and since "typeof x === 'object'" is considered to be side-effect free,
// we must also consider "typeof x == 'object'" to be side-effect free.
case js_ast.BinOpLooseEq, js_ast.BinOpLooseNe:
return canChangeStrictToLoose(e.Left, e.Right) && p.exprCanBeRemovedIfUnused(e.Left) && p.exprCanBeRemovedIfUnused(e.Right)
}
}

Expand Down

0 comments on commit 7ecdc28

Please sign in to comment.