@@ -2477,24 +2477,24 @@ Compressor.prototype.compress = function(node) {
|
|||||||
can_replace = false;
|
can_replace = false;
|
||||||
var after = stop_after;
|
var after = stop_after;
|
||||||
var if_hit = stop_if_hit;
|
var if_hit = stop_if_hit;
|
||||||
if (!all(fn.argnames, function(argname) {
|
for (var i = 0; !abort && i < fn.argnames.length; i++) {
|
||||||
if (argname instanceof AST_DefaultValue) {
|
if (may_throw_arg(reject, fn.argnames[i], node.args[i])) abort = true;
|
||||||
argname.value.transform(scanner);
|
}
|
||||||
if (abort) return false;
|
if (!abort) {
|
||||||
argname = argname.name;
|
if (fn.rest && may_throw_arg(reject, fn.rest, make_node(AST_Array, node, {
|
||||||
|
elements: node.args.slice(i),
|
||||||
|
}))) {
|
||||||
|
abort = true;
|
||||||
|
} else if (is_arrow(fn) && fn.value) {
|
||||||
|
fn.value.transform(scanner);
|
||||||
|
} else for (var i = 0; !abort && i < fn.body.length; i++) {
|
||||||
|
var stat = fn.body[i];
|
||||||
|
if (stat instanceof AST_Return) {
|
||||||
|
if (stat.value) stat.value.transform(scanner);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
stat.transform(scanner);
|
||||||
}
|
}
|
||||||
return !(argname instanceof AST_Destructured);
|
|
||||||
})) {
|
|
||||||
abort = true;
|
|
||||||
} else if (is_arrow(fn) && fn.value) {
|
|
||||||
fn.value.transform(scanner);
|
|
||||||
} else for (var i = 0; !abort && i < fn.body.length; i++) {
|
|
||||||
var stat = fn.body[i];
|
|
||||||
if (stat instanceof AST_Return) {
|
|
||||||
if (stat.value) stat.value.transform(scanner);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
stat.transform(scanner);
|
|
||||||
}
|
}
|
||||||
stop_if_hit = if_hit;
|
stop_if_hit = if_hit;
|
||||||
stop_after = after;
|
stop_after = after;
|
||||||
@@ -2560,28 +2560,35 @@ Compressor.prototype.compress = function(node) {
|
|||||||
return node instanceof AST_SymbolRef
|
return node instanceof AST_SymbolRef
|
||||||
&& (lvalues.has(node.name) || read_toplevel && compressor.exposed(node.definition()));
|
&& (lvalues.has(node.name) || read_toplevel && compressor.exposed(node.definition()));
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
|
function reject(node) {
|
||||||
|
node.transform(scanner);
|
||||||
|
return abort;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function may_throw_destructured(node, value) {
|
function may_throw_arg(reject, node, value) {
|
||||||
if (!value) return !(node instanceof AST_Symbol);
|
|
||||||
if (node instanceof AST_DefaultValue) {
|
if (node instanceof AST_DefaultValue) {
|
||||||
return value.has_side_effects(compressor)
|
return reject(node.value)
|
||||||
|| node.value.has_side_effects(compressor)
|
|| may_throw_arg(reject, node.name, node.value)
|
||||||
|| may_throw_destructured(node.name, is_undefined(value) && node.value);
|
|| !is_undefined(value) && may_throw_arg(reject, node.name, value);
|
||||||
}
|
}
|
||||||
|
if (!value) return !(node instanceof AST_Symbol);
|
||||||
if (node instanceof AST_Destructured) {
|
if (node instanceof AST_Destructured) {
|
||||||
if (node.rest && may_throw_destructured(node.rest)) return true;
|
if (node.rest && may_throw_arg(reject, node.rest)) return true;
|
||||||
if (node instanceof AST_DestructuredArray) {
|
if (node instanceof AST_DestructuredArray) {
|
||||||
if (!(value instanceof AST_Array || value.is_string(compressor))) return true;
|
if (value instanceof AST_Array) return !all(node.elements, function(element, index) {
|
||||||
return !all(node.elements, function(element) {
|
return !may_throw_arg(reject, element, value[index]);
|
||||||
return !may_throw_destructured(element);
|
});
|
||||||
|
return value.is_string(compressor) && !all(node.elements, function(element) {
|
||||||
|
return !may_throw_arg(reject, element);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (node instanceof AST_DestructuredObject) {
|
if (node instanceof AST_DestructuredObject) {
|
||||||
if (!value.is_defined(compressor)) return true;
|
if (!value.is_defined(compressor)) return true;
|
||||||
return !all(node.properties, function(prop) {
|
return !all(node.properties, function(prop) {
|
||||||
if (prop instanceof AST_Node && prop.has_side_effects(compressor)) return false;
|
if (prop.key instanceof AST_Node && reject(prop.key)) return false;
|
||||||
return !may_throw_destructured(prop.value);
|
return !may_throw_arg(reject, prop.value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2645,7 +2652,9 @@ Compressor.prototype.compress = function(node) {
|
|||||||
args[len + i] = value;
|
args[len + i] = value;
|
||||||
}
|
}
|
||||||
if (sym instanceof AST_Destructured) {
|
if (sym instanceof AST_Destructured) {
|
||||||
if (!may_throw_destructured(sym, arg)) continue;
|
if (!may_throw_arg(function(node) {
|
||||||
|
return node.has_side_effects(compressor);
|
||||||
|
}, sym, arg)) continue;
|
||||||
candidates.length = 0;
|
candidates.length = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2668,6 +2677,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
candidate.arg_index = value ? len + i : i;
|
candidate.arg_index = value ? len + i : i;
|
||||||
candidates.unshift([ candidate ]);
|
candidates.unshift([ candidate ]);
|
||||||
}
|
}
|
||||||
|
if (fn.rest) args.push(fn.rest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1531,3 +1531,96 @@ issue_5533_2_drop_fargs: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5552_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var log = console.log;
|
||||||
|
var a = f, b = log();
|
||||||
|
function f(...[ c = a = "PASS" ]) {}
|
||||||
|
f((a = "FAIL", b));
|
||||||
|
log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var log = console.log;
|
||||||
|
var a = f, b = log();
|
||||||
|
function f(...[ c = a = "PASS" ]) {}
|
||||||
|
f((a = "FAIL", b));
|
||||||
|
log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"",
|
||||||
|
"PASS",
|
||||||
|
]
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5552_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var log = console.log;
|
||||||
|
var a = f;
|
||||||
|
function f(...{ [a = "PASS"]: b }) {}
|
||||||
|
f((a = "FAIL", 42));
|
||||||
|
log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var log = console.log;
|
||||||
|
var a = f;
|
||||||
|
function f(...{ [a = "PASS"]: b }) {}
|
||||||
|
f((a = "FAIL", 42));
|
||||||
|
log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5552_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = [ "FAIL", "PASS" ];
|
||||||
|
console.log(function(b, ...[ c = a.pop() ]) {
|
||||||
|
return b;
|
||||||
|
}(a.pop()));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = [ "FAIL", "PASS" ];
|
||||||
|
console.log(function(b, ...[ c = a.pop() ]) {
|
||||||
|
return b;
|
||||||
|
}(a.pop()));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5552_4: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = [ "FAIL", "PASS" ];
|
||||||
|
console.log(function(b, ...{ [a.pop()]: c }) {
|
||||||
|
return b;
|
||||||
|
}(a.pop()));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = [ "FAIL", "PASS" ];
|
||||||
|
console.log(function(b, ...{ [a.pop()]: c }) {
|
||||||
|
return b;
|
||||||
|
}(a.pop()));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user