enhance collapse_vars (#3801)

This commit is contained in:
Alex Lam S.L
2020-04-18 22:04:21 +01:00
committed by GitHub
parent f110601fb4
commit eb6f32bfc3
2 changed files with 49 additions and 12 deletions

View File

@@ -1122,7 +1122,10 @@ merge(Compressor.prototype, {
function collapse(statements, compressor) { function collapse(statements, compressor) {
if (scope.pinned()) return statements; if (scope.pinned()) return statements;
var args; var args;
var assignments = Object.create(null);
var candidates = []; var candidates = [];
var declare_only = Object.create(null);
var force_single;
var stat_index = statements.length; var stat_index = statements.length;
var scanner = new TreeTransformer(function(node, descend) { var scanner = new TreeTransformer(function(node, descend) {
if (abort) return node; if (abort) return node;
@@ -1255,7 +1258,6 @@ merge(Compressor.prototype, {
// Skip (non-executed) functions and (leading) default case in switch statements // Skip (non-executed) functions and (leading) default case in switch statements
if (node instanceof AST_Default || node instanceof AST_Scope) return node; if (node instanceof AST_Default || node instanceof AST_Scope) return node;
}, patch_sequence); }, patch_sequence);
var force_single;
while (--stat_index >= 0) { while (--stat_index >= 0) {
// Treat parameters as collapsible in IIFE, i.e. // Treat parameters as collapsible in IIFE, i.e.
// function(a, b){ ... }(x()); // function(a, b){ ... }(x());
@@ -1264,7 +1266,6 @@ merge(Compressor.prototype, {
if (stat_index == 0 && compressor.option("unused")) extract_args(); if (stat_index == 0 && compressor.option("unused")) extract_args();
// Find collapsible assignments // Find collapsible assignments
var hit_stack = []; var hit_stack = [];
var declare_only = Object.create(null);
extract_candidates(statements[stat_index]); extract_candidates(statements[stat_index]);
while (candidates.length > 0) { while (candidates.length > 0) {
hit_stack = candidates.pop(); hit_stack = candidates.pop();
@@ -1501,6 +1502,9 @@ merge(Compressor.prototype, {
candidates.push(hit_stack.slice()); candidates.push(hit_stack.slice());
extract_candidates(expr.left); extract_candidates(expr.left);
extract_candidates(expr.right); extract_candidates(expr.right);
if (expr.left instanceof AST_SymbolRef) {
assignments[expr.left.name] = (assignments[expr.left.name] || 0) + 1;
}
} else if (expr instanceof AST_Binary) { } else if (expr instanceof AST_Binary) {
extract_candidates(expr.left); extract_candidates(expr.left);
extract_candidates(expr.right); extract_candidates(expr.right);
@@ -1740,14 +1744,13 @@ merge(Compressor.prototype, {
if (expr instanceof AST_VarDef) { if (expr instanceof AST_VarDef) {
var def = expr.name.definition(); var def = expr.name.definition();
if (!member(expr.name, def.orig)) return; if (!member(expr.name, def.orig)) return;
var referenced = def.references.length - def.replaced; var declared = def.orig.length - def.eliminated - (declare_only[def.name] || 0);
var declared = def.orig.length - def.eliminated; var referenced = def.references.length - def.replaced - (assignments[def.name] || 0);
declared -= declare_only[def.name] || 0;
if (declared > 1 && !(expr.name instanceof AST_SymbolFunarg)) { if (declared > 1 && !(expr.name instanceof AST_SymbolFunarg)) {
mangleable_var(expr.value); mangleable_var(expr.value);
return make_node(AST_SymbolRef, expr.name, expr.name); return make_node(AST_SymbolRef, expr.name, expr.name);
} }
if (referenced > 1 ? mangleable_var(expr.value) : !compressor.exposed(def)) { if (mangleable_var(expr.value) || referenced == 1 && !compressor.exposed(def)) {
return make_node(AST_SymbolRef, expr.name, expr.name); return make_node(AST_SymbolRef, expr.name, expr.name);
} }
} else if (expr instanceof AST_Assign) { } else if (expr instanceof AST_Assign) {
@@ -1871,6 +1874,7 @@ merge(Compressor.prototype, {
found = true; found = true;
if (node instanceof AST_VarDef) { if (node instanceof AST_VarDef) {
node.value = null; node.value = null;
declare_only[node.name.name] = (declare_only[node.name.name] || 0) + 1;
if (value_def) value_def.replaced++; if (value_def) value_def.replaced++;
return node; return node;
} }

View File

@@ -803,8 +803,7 @@ collapse_vars_assignment: {
expect: { expect: {
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; return 3 / c;
return a = a;
} }
function f1(c) { function f1(c) {
return 1 - 3 / c; return 1 - 3 / c;
@@ -2205,8 +2204,8 @@ var_defs: {
} }
expect: { expect: {
var f1 = function(x, y) { var f1 = function(x, y) {
var r = x + y, a = r * r - r, b = 7; var r = x + y, z = r * r - r, b = 7;
console.log(a + b); console.log(z + b);
}; };
f1("1", 0); f1("1", 0);
} }
@@ -2665,8 +2664,8 @@ double_def_1: {
a(); a();
} }
expect: { expect: {
var a; var a = x;
(a = (a = x) && y)(); (a = a && y)();
} }
} }
@@ -7921,3 +7920,37 @@ var_value_def: {
} }
expect_stdout: "PASS" expect_stdout: "PASS"
} }
mangleable_var: {
options = {
collapse_vars: true,
unused: true,
}
input: {
function f(a) {
var b = a(), c = a(), d = b;
return c.p(c, d);
}
console.log(f(function() {
return {
p: function() {
return "PASS"
},
};
}));
}
expect: {
function f(a) {
var b = a(), c = a();
return c.p(c, b);
}
console.log(f(function() {
return {
p: function() {
return "PASS";
}
};
}));
}
expect_stdout: "PASS"
}