fix corner cases in join_vars (#3790)

fixes #3789
fixes #3791
This commit is contained in:
Alex Lam S.L
2020-04-17 19:53:26 +01:00
committed by GitHub
parent 15a3ebd467
commit da68ec6e19
4 changed files with 140 additions and 9 deletions

View File

@@ -2330,7 +2330,7 @@ merge(Compressor.prototype, {
statements.length = n; statements.length = n;
} }
function join_assigns(defn, body) { function join_assigns(defn, body, keep) {
var exprs; var exprs;
if (body instanceof AST_Assign) { if (body instanceof AST_Assign) {
exprs = [ body ]; exprs = [ body ];
@@ -2352,14 +2352,14 @@ merge(Compressor.prototype, {
if (defn instanceof AST_Definitions) { if (defn instanceof AST_Definitions) {
var def = defn.definitions[defn.definitions.length - 1]; var def = defn.definitions[defn.definitions.length - 1];
if (trim_assigns(def.name, def.value, exprs)) trimmed = true; if (trim_assigns(def.name, def.value, exprs)) trimmed = true;
if (join_var_assign(defn.definitions, exprs)) trimmed = true; if (join_var_assign(defn.definitions, exprs, keep || 0)) trimmed = true;
} }
return trimmed && exprs; return trimmed && exprs;
} }
function join_var_assign(definitions, exprs) { function join_var_assign(definitions, exprs, keep) {
var trimmed = false; var trimmed = false;
while (exprs.length) { while (exprs.length > keep) {
var expr = exprs[0]; var expr = exprs[0];
if (!(expr instanceof AST_Assign)) break; if (!(expr instanceof AST_Assign)) break;
if (expr.operator != "=") break; if (expr.operator != "=") break;
@@ -2367,7 +2367,9 @@ merge(Compressor.prototype, {
if (!(lhs instanceof AST_SymbolRef)) break; if (!(lhs instanceof AST_SymbolRef)) break;
if (is_undeclared_ref(lhs)) break; if (is_undeclared_ref(lhs)) break;
var def = lhs.definition(); var def = lhs.definition();
if (def.scope !== definitions[0].name.scope) break; if (def.scope !== lhs.scope) break;
if (def.orig.length > def.eliminated + 1) break;
if (def.orig[0].TYPE != "SymbolVar") break;
var name = make_node(AST_SymbolVar, lhs, lhs); var name = make_node(AST_SymbolVar, lhs, lhs);
definitions.push(make_node(AST_VarDef, expr, { definitions.push(make_node(AST_VarDef, expr, {
name: name, name: name,
@@ -2478,7 +2480,7 @@ merge(Compressor.prototype, {
function join_assigns_expr(value) { function join_assigns_expr(value) {
statements[++j] = stat; statements[++j] = stat;
var exprs = join_assigns(prev, value); var exprs = join_assigns(prev, value, 1);
if (!exprs) return value; if (!exprs) return value;
CHANGED = true; CHANGED = true;
var tail = value.tail_node(); var tail = value.tail_node();
@@ -6045,11 +6047,21 @@ merge(Compressor.prototype, {
function can_inject_symbols() { function can_inject_symbols() {
var catches = Object.create(null); var catches = Object.create(null);
var child;
scope = compressor.self();
do { do {
child = scope;
scope = compressor.parent(++level); scope = compressor.parent(++level);
if (scope instanceof AST_Catch) { if (scope instanceof AST_Catch) {
catches[scope.argname.name] = true; catches[scope.argname.name] = true;
} else if (scope instanceof AST_IterationStatement) { } else if (scope instanceof AST_DWLoop) {
in_loop = [];
} else if (scope instanceof AST_For) {
if (scope.init === child) continue;
in_loop = [];
} else if (scope instanceof AST_ForIn) {
if (scope.init === child) continue;
if (scope.object === child) continue;
in_loop = []; in_loop = [];
} else if (scope instanceof AST_SymbolRef) { } else if (scope instanceof AST_SymbolRef) {
if (scope.fixed_value() instanceof AST_Scope) return false; if (scope.fixed_value() instanceof AST_Scope) return false;

View File

@@ -804,7 +804,7 @@ collapse_vars_assignment: {
function log(x) { return console.log(x), x; } function log(x) { return console.log(x), x; }
function f0(c) { function f0(c) {
var a = 3 / c; var a = 3 / c;
return a; return a = a;
} }
function f1(c) { function f1(c) {
return 1 - 3 / c; return 1 - 3 / c;

View File

@@ -663,3 +663,122 @@ issue_3788: {
"PASS", "PASS",
] ]
} }
issue_3789_1: {
options = {
join_vars: true,
}
input: {
try {
c;
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
try {} catch (c) {
var a;
c = 0;
}
}
expect: {
try {
c;
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
try {} catch (c) {
var a;
c = 0;
}
}
expect_stdout: "PASS"
}
issue_3789_2: {
options = {
join_vars: true,
}
input: {
try {
c;
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
try {} catch (c) {
try {} catch (c) {
var a;
c = 0;
}
}
}
expect: {
try {
c;
console.log("FAIL");
} catch (e) {
console.log("PASS");
}
try {} catch (c) {
try {} catch (c) {
var a;
c = 0;
}
}
}
expect_stdout: "PASS"
}
issue_3791_1: {
options = {
collapse_vars: true,
join_vars: true,
toplevel: true,
}
input: {
var a = "PASS";
switch (a) {
case console:
}
var a = a;
console.log(a);
}
expect: {
var a;
switch (a = "PASS") {
case console:
}
var a = a;
console.log(a);
}
expect_stdout: "PASS"
}
issue_3791_2: {
options = {
collapse_vars: true,
join_vars: true,
}
input: {
function f(a) {
var b;
return b = a || g;
function g() {
return b;
}
}
console.log(typeof f()());
}
expect: {
function f(a) {
var b;
return b = a || g;
function g() {
return b;
}
}
console.log(typeof f()());
}
expect_stdout: "function"
}

View File

@@ -1156,7 +1156,7 @@ for (var round = 1; round <= num_iterations; round++) {
uglify_code = uglify_code.code; uglify_code = uglify_code.code;
uglify_result = sandbox.run_code(uglify_code, toplevel); uglify_result = sandbox.run_code(uglify_code, toplevel);
ok = sandbox.same_stdout(original_result, uglify_result); ok = sandbox.same_stdout(original_result, uglify_result);
if (!ok && typeof uglify_result == "string" && o.compress.unsafe_math) { if (!ok && typeof uglify_result == "string" && o.compress && o.compress.unsafe_math) {
ok = fuzzy_match(original_result, uglify_result); ok = fuzzy_match(original_result, uglify_result);
if (!ok) { if (!ok) {
var fuzzy_result = sandbox.run_code(original_code.replace(/( - 0\.1){3}/g, " - 0.3"), toplevel); var fuzzy_result = sandbox.run_code(original_code.replace(/( - 0\.1){3}/g, " - 0.3"), toplevel);