fix corner case in collapse_vars (#4061)

This commit is contained in:
Alex Lam S.L
2020-08-21 03:35:34 +01:00
committed by GitHub
parent aa83ecdb3b
commit fee677786e
2 changed files with 94 additions and 15 deletions

View File

@@ -1952,6 +1952,7 @@ merge(Compressor.prototype, {
function get_lvalues(expr) {
var lvalues = new Dictionary();
if (expr instanceof AST_VarDef) lvalues.add(expr.name.name, lhs);
var find_arguments = scope.uses_arguments && !compressor.has_directive("use strict");
var scan_toplevel = scope instanceof AST_Toplevel;
var tw = new TreeWalker(function(node) {
var value;
@@ -1960,21 +1961,27 @@ merge(Compressor.prototype, {
} else if (node instanceof AST_This) {
value = node;
}
if (value) {
lvalues.add(node.name, is_modified(compressor, tw, node, value, 0));
} else if (scan_toplevel) {
if (node.TYPE == "Call") {
if (modify_toplevel) return;
var exp = node.expression;
if (exp instanceof AST_PropAccess) return;
if (exp instanceof AST_Function && !exp.contains_this()) return;
modify_toplevel = true;
} else if (node instanceof AST_PropAccess && may_be_global(node.expression)) {
if (node === lhs && !(expr instanceof AST_Unary)) {
modify_toplevel = true;
} else {
read_toplevel = true;
if (value) lvalues.add(node.name, is_modified(compressor, tw, node, value, 0));
if (find_arguments && node instanceof AST_Sub) {
scope.argnames.forEach(function(argname) {
if (!compressor.option("reduce_vars") || argname.definition().assignments) {
lvalues.add(argname.name, true);
}
});
find_arguments = false;
}
if (!scan_toplevel) return;
if (node.TYPE == "Call") {
if (modify_toplevel) return;
var exp = node.expression;
if (exp instanceof AST_PropAccess) return;
if (exp instanceof AST_Function && !exp.contains_this()) return;
modify_toplevel = true;
} else if (node instanceof AST_PropAccess && may_be_global(node.expression)) {
if (node === lhs && !(expr instanceof AST_Unary)) {
modify_toplevel = true;
} else {
read_toplevel = true;
}
}
});

View File

@@ -1599,7 +1599,7 @@ collapse_vars_constants: {
}
}
collapse_vars_arguments: {
collapse_vars_arguments_1: {
options = {
booleans: true,
collapse_vars: true,
@@ -1636,6 +1636,78 @@ collapse_vars_arguments: {
expect_stdout: true
}
collapse_vars_arguments_2: {
options = {
collapse_vars: true,
}
input: {
function log(a, b) {
console.log(b);
}
function f(c) {
var d = arguments[0];
c = "FAIL";
log(c, d);
}
f();
f("PASS");
}
expect: {
function log(a, b) {
console.log(b);
}
function f(c) {
var d = arguments[0];
log(c = "FAIL", d);
}
f();
f("PASS");
}
expect_stdout: [
"undefined",
"PASS",
]
}
collapse_vars_arguments_3: {
options = {
collapse_vars: true,
}
input: {
function log(a, b) {
console.log(b);
}
function f(c) {
var args = arguments;
console.log(c);
var d = args[0];
c = "FAIL";
log(c, d);
}
f();
f("PASS");
}
expect: {
function log(a, b) {
console.log(b);
}
function f(c) {
var args = arguments;
console.log(c);
var d = args[0];
log(c = "FAIL", d);
}
f();
f("PASS");
}
expect_stdout: [
"undefined",
"undefined",
"PASS",
"PASS",
]
}
collapse_vars_short_circuit: {
options = {
booleans: true,