@@ -931,19 +931,25 @@ merge(Compressor.prototype, {
|
||||
tw.in_loop = this;
|
||||
push(tw);
|
||||
var init = this.init;
|
||||
init.walk(tw);
|
||||
if (init instanceof AST_Definitions) {
|
||||
init.definitions[0].name.match_symbol(function(node) {
|
||||
init.definitions[0].name.mark_symbol(function(node) {
|
||||
if (node instanceof AST_SymbolDeclaration) {
|
||||
var def = node.definition();
|
||||
def.assignments++;
|
||||
def.fixed = false;
|
||||
}
|
||||
}, true);
|
||||
} else if (init instanceof AST_SymbolRef) {
|
||||
var def = init.definition();
|
||||
def.assignments++;
|
||||
if (!init.is_immutable()) def.fixed = false;
|
||||
}, tw);
|
||||
} else if (init instanceof AST_Destructured || init instanceof AST_SymbolRef) {
|
||||
init.mark_symbol(function(node) {
|
||||
if (node instanceof AST_SymbolRef) {
|
||||
var def = node.definition();
|
||||
push_ref(def, node);
|
||||
def.assignments++;
|
||||
if (!node.is_immutable()) def.fixed = false;
|
||||
}
|
||||
}, tw);
|
||||
} else {
|
||||
init.walk(tw);
|
||||
}
|
||||
this.body.walk(tw);
|
||||
pop(tw);
|
||||
@@ -1259,16 +1265,17 @@ merge(Compressor.prototype, {
|
||||
AST_Node.DEFMETHOD("match_symbol", function(predicate) {
|
||||
return predicate(this);
|
||||
});
|
||||
AST_Destructured.DEFMETHOD("match_symbol", function(predicate, allow_computed_keys) {
|
||||
AST_Destructured.DEFMETHOD("match_symbol", function(predicate, ignore_side_effects) {
|
||||
var found = false;
|
||||
var tw = new TreeWalker(function(node) {
|
||||
if (found) return true;
|
||||
if (node instanceof AST_DefaultValue) {
|
||||
if (!ignore_side_effects) return found = true;
|
||||
node.name.walk(tw);
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_DestructuredKeyVal) {
|
||||
if (!allow_computed_keys && node.key instanceof AST_Node) return found = true;
|
||||
if (!ignore_side_effects && node.key instanceof AST_Node) return found = true;
|
||||
node.value.walk(tw);
|
||||
return true;
|
||||
}
|
||||
@@ -1605,13 +1612,12 @@ merge(Compressor.prototype, {
|
||||
can_replace = replace;
|
||||
return signal_abort(node);
|
||||
}
|
||||
// Scan but don't replace inside destructuring LHS
|
||||
if (node instanceof AST_Assign && node.left instanceof AST_Destructured) {
|
||||
// Scan but don't replace inside destructuring expression
|
||||
if (node instanceof AST_Destructured) {
|
||||
var replace = can_replace;
|
||||
can_replace = false;
|
||||
node.left = node.left.transform(scanner);
|
||||
descend(node, scanner);
|
||||
can_replace = replace;
|
||||
node.right = node.right.transform(scanner);
|
||||
return signal_abort(node);
|
||||
}
|
||||
// Scan but don't replace inside default value
|
||||
@@ -1710,8 +1716,8 @@ merge(Compressor.prototype, {
|
||||
var assign_used = false;
|
||||
var can_replace = !args || !hit;
|
||||
if (!can_replace) {
|
||||
for (var j = candidate.index + 1; !abort && j < args.length; j++) {
|
||||
args[j].transform(scanner);
|
||||
for (var j = candidate.arg_index + 1; !abort && j < args.length; j++) {
|
||||
if (args[j]) args[j].transform(scanner);
|
||||
}
|
||||
can_replace = true;
|
||||
}
|
||||
@@ -1911,7 +1917,7 @@ merge(Compressor.prototype, {
|
||||
return (node.value || parent instanceof AST_Let) && node.name.match_symbol(function(node) {
|
||||
return node instanceof AST_SymbolDeclaration
|
||||
&& (lvalues.has(node.name) || side_effects && may_modify(node));
|
||||
});
|
||||
}, true);
|
||||
}
|
||||
var sym = is_lhs(node.left, node);
|
||||
if (!sym) return false;
|
||||
@@ -1920,7 +1926,7 @@ merge(Compressor.prototype, {
|
||||
return sym.match_symbol(function(node) {
|
||||
return node instanceof AST_SymbolRef
|
||||
&& (lvalues.has(node.name) || read_toplevel && compressor.exposed(node.definition()));
|
||||
});
|
||||
}, true);
|
||||
}
|
||||
|
||||
function extract_args() {
|
||||
@@ -1959,21 +1965,17 @@ merge(Compressor.prototype, {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
var len = fn.argnames.length;
|
||||
args = iife.args.slice(len);
|
||||
args = iife.args.slice();
|
||||
var names = Object.create(null);
|
||||
for (var i = len; --i >= 0;) {
|
||||
for (var i = fn.argnames.length; --i >= 0;) {
|
||||
var sym = fn.argnames[i];
|
||||
var arg = iife.args[i];
|
||||
var value;
|
||||
if (sym instanceof AST_DefaultValue) {
|
||||
value = sym.value;
|
||||
sym = sym.name;
|
||||
args[iife.args.length + i] = value;
|
||||
}
|
||||
args.unshift(make_node(AST_VarDef, sym, {
|
||||
name: sym,
|
||||
value: value ? arg ? make_sequence(iife, [ arg, value ]) : value : arg,
|
||||
}));
|
||||
if (sym instanceof AST_Destructured) {
|
||||
if (!sym.match_symbol(return_false)) continue;
|
||||
candidates.length = 0;
|
||||
@@ -1994,7 +1996,8 @@ merge(Compressor.prototype, {
|
||||
name: sym,
|
||||
value: arg
|
||||
});
|
||||
candidate.index = i;
|
||||
candidate.name_index = i;
|
||||
candidate.arg_index = value ? iife.args.length + i : i;
|
||||
candidates.unshift([ candidate ]);
|
||||
}
|
||||
}
|
||||
@@ -2198,9 +2201,7 @@ merge(Compressor.prototype, {
|
||||
if (is_last_node(node, parent)) return node;
|
||||
if (in_conditional(node, parent)) return node;
|
||||
if (parent instanceof AST_Array) return find_stop_unused(parent, level + 1);
|
||||
if (parent instanceof AST_Assign) {
|
||||
return may_throw(parent) ? node : find_stop_unused(parent, level + 1);
|
||||
}
|
||||
if (parent instanceof AST_Assign) return check_assignment(parent.left);
|
||||
if (parent instanceof AST_Await) return node;
|
||||
if (parent instanceof AST_Binary) return find_stop_unused(parent, level + 1);
|
||||
if (parent instanceof AST_Call) return find_stop_unused(parent, level + 1);
|
||||
@@ -2231,10 +2232,27 @@ merge(Compressor.prototype, {
|
||||
if (parent instanceof AST_Spread) return node;
|
||||
if (parent instanceof AST_Switch) return find_stop_unused(parent, level + 1);
|
||||
if (parent instanceof AST_Unary) return find_stop_unused(parent, level + 1);
|
||||
if (parent instanceof AST_VarDef) {
|
||||
return may_throw(parent) ? node : find_stop_unused(parent, level + 1);
|
||||
}
|
||||
if (parent instanceof AST_VarDef) return check_assignment(parent.name);
|
||||
return null;
|
||||
|
||||
function check_assignment(lhs) {
|
||||
if (may_throw(parent)) return node;
|
||||
if (lhs !== node && lhs instanceof AST_Destructured) {
|
||||
var replace = can_replace;
|
||||
can_replace = false;
|
||||
var after = stop_after;
|
||||
var if_hit = stop_if_hit;
|
||||
lhs.transform(scanner);
|
||||
stop_if_hit = if_hit;
|
||||
stop_after = after;
|
||||
can_replace = replace;
|
||||
if (abort) {
|
||||
abort = false;
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return find_stop_unused(parent, level + 1);
|
||||
}
|
||||
}
|
||||
|
||||
function mangleable_var(value) {
|
||||
@@ -2389,7 +2407,7 @@ merge(Compressor.prototype, {
|
||||
}
|
||||
|
||||
function remove_candidate(expr) {
|
||||
var index = expr.index;
|
||||
var index = expr.name_index;
|
||||
if (index >= 0) {
|
||||
var argname = scope.argnames[index];
|
||||
if (argname instanceof AST_DefaultValue) {
|
||||
@@ -7018,7 +7036,7 @@ merge(Compressor.prototype, {
|
||||
if ((name instanceof AST_Destructured || name instanceof AST_SymbolLet)
|
||||
&& !name.match_symbol(function(node) {
|
||||
if (node instanceof AST_SymbolDeclaration) return may_overlap(compressor, node.definition());
|
||||
})) {
|
||||
}, true)) {
|
||||
self.init = to_var(self.init);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1100,3 +1100,63 @@ issue_4458: {
|
||||
expect_stdout: "PASS 42"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_4460: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var log = console.log, a = "FAIL";
|
||||
var [ b = a ] = (a = "PASS", []);
|
||||
log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var log = console.log, a = "FAIL";
|
||||
var [ b = a ] = (a = "PASS", []);
|
||||
log(a, b);
|
||||
}
|
||||
expect_stdout: "PASS PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_4461_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0;
|
||||
(function(b = a && console.log("PASS"), c) {
|
||||
return c;
|
||||
})(void 0, a++);
|
||||
}
|
||||
expect: {
|
||||
var a = 0;
|
||||
(function(b = a && console.log("PASS"), c) {
|
||||
return c;
|
||||
})(void 0, a++);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_4461_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0;
|
||||
(function([ b = a && console.log("PASS") ], c) {
|
||||
return c;
|
||||
})([], a++);
|
||||
}
|
||||
expect: {
|
||||
var a = 0;
|
||||
(function([ b = a && console.log("PASS") ], c) {
|
||||
return c;
|
||||
})([], a++);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user