aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2017-11-28 13:08:40 +0800
committerGitHub <noreply@github.com>2017-11-28 13:08:40 +0800
commitecc9f6b77093758d78a693a5ac4b6bcaf75e9a3f (patch)
treed1da1a5309bd75053dae1fde43c1b086ae192e7e
parentb37a68c84f7b74de8ec7fc862792964c436fa2ec (diff)
downloadtracifyjs-ecc9f6b77093758d78a693a5ac4b6bcaf75e9a3f.tar.gz
tracifyjs-ecc9f6b77093758d78a693a5ac4b6bcaf75e9a3f.zip
drop assignment in `AST_VarDef.value` (#2522)
fixes #2516
-rw-r--r--lib/compress.js59
-rw-r--r--test/compress/collapse_vars.js16
-rw-r--r--test/compress/drop-unused.js80
3 files changed, 118 insertions, 37 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 22415f4d..b51fdfc7 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -1088,6 +1088,7 @@ merge(Compressor.prototype, {
function get_lhs(expr) {
if (expr instanceof AST_VarDef) {
var def = expr.name.definition();
+ if (!member(expr.name, def.orig)) return;
var declared = def.orig.length - def.eliminated;
var referenced = def.references.length - def.replaced;
if (declared > 1 && !(expr.name instanceof AST_SymbolFunarg)
@@ -2434,47 +2435,18 @@ merge(Compressor.prototype, {
});
return true;
}
- var sym;
- if (scope === self
- && (sym = assign_as_unused(node)) instanceof AST_SymbolRef
- && self.variables.get(sym.name) === sym.definition()) {
- if (node instanceof AST_Assign) node.right.walk(tw);
- return true;
- }
- if (node instanceof AST_SymbolRef) {
- var node_def = node.definition();
- if (!(node_def.id in in_use_ids)) {
- in_use_ids[node_def.id] = true;
- in_use.push(node_def);
- }
- return true;
- }
- if (node instanceof AST_Scope) {
- var save_scope = scope;
- scope = node;
- descend();
- scope = save_scope;
- return true;
- }
+ return scan_ref_scoped(node, descend);
});
self.walk(tw);
// pass 2: for every used symbol we need to walk its
// initialization code to figure out if it uses other
// symbols (that may not be in_use).
+ tw = new TreeWalker(scan_ref_scoped);
for (var i = 0; i < in_use.length; ++i) {
in_use[i].orig.forEach(function(decl){
// undeclared globals will be instanceof AST_SymbolRef
var init = initializations.get(decl.name);
if (init) init.forEach(function(init){
- var tw = new TreeWalker(function(node){
- if (node instanceof AST_SymbolRef) {
- var node_def = node.definition();
- if (!(node_def.id in in_use_ids)) {
- in_use_ids[node_def.id] = true;
- in_use.push(node_def);
- }
- }
- });
init.walk(tw);
});
});
@@ -2663,6 +2635,31 @@ merge(Compressor.prototype, {
}
);
self.transform(tt);
+
+ function scan_ref_scoped(node, descend) {
+ var sym;
+ if (scope === self
+ && (sym = assign_as_unused(node)) instanceof AST_SymbolRef
+ && self.variables.get(sym.name) === sym.definition()) {
+ if (node instanceof AST_Assign) node.right.walk(tw);
+ return true;
+ }
+ if (node instanceof AST_SymbolRef) {
+ var node_def = node.definition();
+ if (!(node_def.id in in_use_ids)) {
+ in_use_ids[node_def.id] = true;
+ in_use.push(node_def);
+ }
+ return true;
+ }
+ if (node instanceof AST_Scope) {
+ var save_scope = scope;
+ scope = node;
+ descend();
+ scope = save_scope;
+ return true;
+ }
+ }
});
AST_Scope.DEFMETHOD("hoist_declarations", function(compressor){
diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js
index 844d5b0f..f968ff20 100644
--- a/test/compress/collapse_vars.js
+++ b/test/compress/collapse_vars.js
@@ -705,7 +705,7 @@ collapse_vars_lvalues_drop_assign: {
function f2(x) { var z = x, a = ++z; return z += a; }
function f3(x) { var a = (x -= 3); return x + a; }
function f4(x) { var a = (x -= 3); return x + a; }
- function f5(x) { e1(); var v = e2(), c = v = --x; return x - c; }
+ function f5(x) { e1(), e2(); var c = --x; return x - c; }
function f6(x) { e1(), e2(); return --x - x; }
function f7(x) { e1(); return x - (e2() - x); }
function f8(x) { e1(); return x - (e2() - x); }
@@ -2386,6 +2386,7 @@ duplicate_argname: {
issue_2298: {
options = {
collapse_vars: true,
+ passes: 2,
reduce_funcs: true,
reduce_vars: true,
unused: true,
@@ -3087,13 +3088,14 @@ issue_2437: {
}
expect: {
!function() {
- if (xhrDesc)
- return result = !!(req = new XMLHttpRequest()).onreadystatechange,
- Object.defineProperty(XMLHttpRequest.prototype, "onreadystatechange", xhrDesc || {}),
+ if (xhrDesc) {
+ var result = !!(req = new XMLHttpRequest()).onreadystatechange;
+ return Object.defineProperty(XMLHttpRequest.prototype, "onreadystatechange", xhrDesc || {}),
result;
+ }
var req = new XMLHttpRequest(), detectFunc = function() {};
- req.onreadystatechange = detectFunc;
- var result = req[SYMBOL_FAKE_ONREADYSTATECHANGE_1] === detectFunc;
+ req.onreadystatechange = detectFunc,
+ result = req[SYMBOL_FAKE_ONREADYSTATECHANGE_1] === detectFunc,
req.onreadystatechange = null;
}();
}
@@ -3522,6 +3524,7 @@ issue_2436_12: {
issue_2436_13: {
options = {
collapse_vars: true,
+ passes: 2,
reduce_vars: true,
unused: true,
}
@@ -3622,6 +3625,7 @@ issue_2497: {
issue_2506: {
options = {
collapse_vars: true,
+ passes: 2,
reduce_vars: true,
unused: true,
}
diff --git a/test/compress/drop-unused.js b/test/compress/drop-unused.js
index 33241d67..eb6f9df4 100644
--- a/test/compress/drop-unused.js
+++ b/test/compress/drop-unused.js
@@ -1299,3 +1299,83 @@ issue_2288: {
}
}
}
+
+issue_2516_1: {
+ options = {
+ collapse_vars: true,
+ reduce_funcs: true,
+ reduce_vars: true,
+ unused: true,
+ }
+ input: {
+ function foo() {
+ function qux(x) {
+ bar.call(null, x);
+ }
+ function bar(x) {
+ var FOUR = 4;
+ var trouble = x || never_called();
+ var value = (FOUR - 1) * trouble;
+ console.log(value == 6 ? "PASS" : value);
+ }
+ Baz = qux;
+ }
+ var Baz;
+ foo();
+ Baz(2);
+ }
+ expect: {
+ function foo() {
+ Baz = function(x) {
+ (function(x) {
+ var trouble = x || never_called();
+ var value = (4 - 1) * trouble;
+ console.log(6 == value ? "PASS" : value);
+ }).call(null, x);
+ };
+ }
+ var Baz;
+ foo();
+ Baz(2);
+ }
+}
+
+issue_2516_2: {
+ options = {
+ collapse_vars: true,
+ reduce_funcs: true,
+ reduce_vars: true,
+ passes: 2,
+ unused: true,
+ }
+ input: {
+ function foo() {
+ function qux(x) {
+ bar.call(null, x);
+ }
+ function bar(x) {
+ var FOUR = 4;
+ var trouble = x || never_called();
+ var value = (FOUR - 1) * trouble;
+ console.log(value == 6 ? "PASS" : value);
+ }
+ Baz = qux;
+ }
+ var Baz;
+ foo();
+ Baz(2);
+ }
+ expect: {
+ function foo() {
+ Baz = function(x) {
+ (function(x) {
+ var value = (4 - 1) * (x || never_called());
+ console.log(6 == value ? "PASS" : value);
+ }).call(null, x);
+ };
+ }
+ var Baz;
+ foo();
+ Baz(2);
+ }
+}