enhance collapse_vars (#5555)
This commit is contained in:
@@ -1665,6 +1665,18 @@ Compressor.prototype.compress = function(node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function find_try(compressor, level, node, scope, may_throw, sync) {
|
||||||
|
for (var parent; parent = compressor.parent(level++); node = parent) {
|
||||||
|
if (parent === scope) return false;
|
||||||
|
if (sync && parent instanceof AST_Lambda) {
|
||||||
|
if (parent.name || is_async(parent) || is_generator(parent)) return true;
|
||||||
|
} else if (parent instanceof AST_Try) {
|
||||||
|
if (parent.bfinally && parent.bfinally !== node) return true;
|
||||||
|
if (may_throw && parent.bcatch && parent.bcatch !== node) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var identifier_atom = makePredicate("Infinity NaN undefined");
|
var identifier_atom = makePredicate("Infinity NaN undefined");
|
||||||
function is_lhs_read_only(lhs, compressor) {
|
function is_lhs_read_only(lhs, compressor) {
|
||||||
if (lhs instanceof AST_ObjectIdentity) return true;
|
if (lhs instanceof AST_ObjectIdentity) return true;
|
||||||
@@ -2585,7 +2597,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (node instanceof AST_DestructuredObject) {
|
if (node instanceof AST_DestructuredObject) {
|
||||||
if (!value.is_defined(compressor)) return true;
|
if (value.may_throw_on_access(compressor)) return true;
|
||||||
return !all(node.properties, function(prop) {
|
return !all(node.properties, function(prop) {
|
||||||
if (prop.key instanceof AST_Node && reject(prop.key)) return false;
|
if (prop.key instanceof AST_Node && reject(prop.key)) return false;
|
||||||
return !may_throw_arg(reject, prop.value);
|
return !may_throw_arg(reject, prop.value);
|
||||||
@@ -2608,11 +2620,18 @@ Compressor.prototype.compress = function(node) {
|
|||||||
})) {
|
})) {
|
||||||
var fn_strict = fn.in_strict_mode(compressor)
|
var fn_strict = fn.in_strict_mode(compressor)
|
||||||
&& !fn.parent_scope.resolve(true).in_strict_mode(compressor);
|
&& !fn.parent_scope.resolve(true).in_strict_mode(compressor);
|
||||||
var has_await = is_async(fn) ? function(node) {
|
var check_arg = false, has_await;
|
||||||
|
if (is_async(fn)) {
|
||||||
|
check_arg = true;
|
||||||
|
has_await = function(node) {
|
||||||
return node instanceof AST_Symbol && node.name == "await";
|
return node instanceof AST_Symbol && node.name == "await";
|
||||||
} : function(node) {
|
};
|
||||||
|
} else {
|
||||||
|
check_arg = find_try(compressor, 1, iife, null, true, true);
|
||||||
|
has_await = function(node) {
|
||||||
return node instanceof AST_Await && !tw.find_parent(AST_Scope);
|
return node instanceof AST_Await && !tw.find_parent(AST_Scope);
|
||||||
};
|
};
|
||||||
|
}
|
||||||
var arg_scope = null;
|
var arg_scope = null;
|
||||||
var tw = new TreeWalker(function(node, descend) {
|
var tw = new TreeWalker(function(node, descend) {
|
||||||
if (!arg) return true;
|
if (!arg) return true;
|
||||||
@@ -2645,19 +2664,22 @@ Compressor.prototype.compress = function(node) {
|
|||||||
for (var i = fn.argnames.length; --i >= 0;) {
|
for (var i = fn.argnames.length; --i >= 0;) {
|
||||||
var sym = fn.argnames[i];
|
var sym = fn.argnames[i];
|
||||||
var arg = args[i];
|
var arg = args[i];
|
||||||
var value;
|
var value = null;
|
||||||
if (sym instanceof AST_DefaultValue) {
|
if (sym instanceof AST_DefaultValue) {
|
||||||
value = sym.value;
|
value = sym.value;
|
||||||
sym = sym.name;
|
sym = sym.name;
|
||||||
args[len + i] = value;
|
args[len + i] = value;
|
||||||
}
|
}
|
||||||
if (sym instanceof AST_Destructured) {
|
if (sym instanceof AST_Destructured) {
|
||||||
if (!may_throw_arg(function(node) {
|
if (check_arg && may_throw_arg(function(node) {
|
||||||
return node.has_side_effects(compressor);
|
return node.has_side_effects(compressor);
|
||||||
}, sym, arg)) continue;
|
}, sym, arg)) {
|
||||||
candidates.length = 0;
|
candidates.length = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
args[len + i] = fn.argnames[i];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (names.has(sym.name)) continue;
|
if (names.has(sym.name)) continue;
|
||||||
names.set(sym.name, true);
|
names.set(sym.name, true);
|
||||||
if (value) arg = is_undefined(arg) ? value : null;
|
if (value) arg = is_undefined(arg) ? value : null;
|
||||||
@@ -12656,15 +12678,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
self.right = make_node(AST_Null, right);
|
self.right = make_node(AST_Null, right);
|
||||||
var may_throw = node.may_throw(compressor);
|
var may_throw = node.may_throw(compressor);
|
||||||
self.right = right;
|
self.right = right;
|
||||||
for (var parent; parent = compressor.parent(level++); node = parent) {
|
return find_try(compressor, level, node, scope, may_throw, sync);
|
||||||
if (parent === scope) return false;
|
|
||||||
if (sync && parent instanceof AST_Lambda) {
|
|
||||||
if (parent.name || is_async(parent) || is_generator(parent)) return true;
|
|
||||||
} else if (parent instanceof AST_Try) {
|
|
||||||
if (parent.bfinally && parent.bfinally !== node) return true;
|
|
||||||
if (may_throw && parent.bcatch && parent.bcatch !== node) return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function strip_assignment(def) {
|
function strip_assignment(def) {
|
||||||
|
|||||||
@@ -1046,6 +1046,60 @@ collapse_vars_3: {
|
|||||||
node_version: ">=8"
|
node_version: ">=8"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
collapse_funarg_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A = "FAIL";
|
||||||
|
var a = "PASS";
|
||||||
|
(async function({}, b) {
|
||||||
|
return b;
|
||||||
|
})(null, A = a);
|
||||||
|
console.log(A);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A = "FAIL";
|
||||||
|
var a = "PASS";
|
||||||
|
(async function({}, b) {
|
||||||
|
return b;
|
||||||
|
})(null, A = a);
|
||||||
|
console.log(A);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
collapse_funarg_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A = "FAIL";
|
||||||
|
B = "PASS";
|
||||||
|
(async function() {
|
||||||
|
console.log(function({}, a) {
|
||||||
|
return a;
|
||||||
|
}(null, A = B));
|
||||||
|
})();
|
||||||
|
console.log(A);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A = "FAIL";
|
||||||
|
B = "PASS";
|
||||||
|
(async function() {
|
||||||
|
console.log(function({}, a) {
|
||||||
|
return a;
|
||||||
|
}(null, A = B));
|
||||||
|
})();
|
||||||
|
console.log(A);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
collapse_property_lambda: {
|
collapse_property_lambda: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
|||||||
@@ -1170,6 +1170,49 @@ mangle_arrow_2_toplevel: {
|
|||||||
node_version: ">=6.9.3"
|
node_version: ">=6.9.3"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
collapse_preceding_simple_arg: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "foo";
|
||||||
|
console.log(function(b, c = "bar") {
|
||||||
|
return b + c;
|
||||||
|
}(a, a));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "foo";
|
||||||
|
console.log(function(b, c = "bar") {
|
||||||
|
return a + c;
|
||||||
|
}(0, a));
|
||||||
|
}
|
||||||
|
expect_stdout: "foofoo"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_preceding_simple_arg: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "foo";
|
||||||
|
console.log(function(b, c = "bar") {
|
||||||
|
return b + c;
|
||||||
|
}(a, a));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "foo";
|
||||||
|
console.log(function(c = "bar") {
|
||||||
|
return a + c;
|
||||||
|
}(a));
|
||||||
|
}
|
||||||
|
expect_stdout: "foofoo"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
issue_4444: {
|
issue_4444: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
|||||||
@@ -472,6 +472,93 @@ funarg_collapse_vars_3: {
|
|||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
funarg_collapse_vars_4: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
(function(b, { log: c }) {
|
||||||
|
c(b);
|
||||||
|
})(a, console);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
(function(b, { log: c }) {
|
||||||
|
c(a);
|
||||||
|
})(0, console);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
funarg_collapse_vars_5: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A = "FAIL";
|
||||||
|
B = "PASS";
|
||||||
|
try {
|
||||||
|
console.log(function({}, a) {
|
||||||
|
return a;
|
||||||
|
}(null, A = B));
|
||||||
|
} catch (e) {}
|
||||||
|
console.log(A);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A = "FAIL";
|
||||||
|
B = "PASS";
|
||||||
|
try {
|
||||||
|
console.log(function({}, a) {
|
||||||
|
return a;
|
||||||
|
}(null, A = B));
|
||||||
|
} catch (e) {}
|
||||||
|
console.log(A);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
funarg_collapse_vars_6: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A = "FAIL";
|
||||||
|
B = "PASS";
|
||||||
|
function f() {
|
||||||
|
console.log(function({}, a) {
|
||||||
|
return a;
|
||||||
|
}(null, A = B));
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
f();
|
||||||
|
} catch (e) {
|
||||||
|
console.log(A);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A = "FAIL";
|
||||||
|
B = "PASS";
|
||||||
|
function f() {
|
||||||
|
console.log(function({}, a) {
|
||||||
|
return a;
|
||||||
|
}(null, A = B));
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
f();
|
||||||
|
} catch (e) {
|
||||||
|
console.log(A);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
funarg_reduce_vars_1: {
|
funarg_reduce_vars_1: {
|
||||||
options = {
|
options = {
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user