enhance join_vars (#5162)
This commit is contained in:
@@ -3476,15 +3476,26 @@ merge(Compressor.prototype, {
|
|||||||
var exprs = extract_exprs(body);
|
var exprs = extract_exprs(body);
|
||||||
if (!exprs) return;
|
if (!exprs) return;
|
||||||
var trimmed = false;
|
var trimmed = false;
|
||||||
for (var i = exprs.length - 1; --i >= 0;) {
|
for (var i = exprs.length; --i >= 0;) {
|
||||||
var expr = exprs[i];
|
var expr = exprs[i];
|
||||||
if (!(expr instanceof AST_Assign)) continue;
|
if (!can_trim(expr)) continue;
|
||||||
if (expr.operator != "=") continue;
|
var tail;
|
||||||
if (!(expr.left instanceof AST_SymbolRef)) continue;
|
if (expr.left instanceof AST_SymbolRef) {
|
||||||
var tail = exprs.slice(i + 1);
|
tail = exprs.slice(i + 1);
|
||||||
|
} else if (expr.left instanceof AST_PropAccess && can_trim(expr.left.expression)) {
|
||||||
|
tail = exprs.slice(i + 1);
|
||||||
|
var flattened = expr.clone();
|
||||||
|
expr = expr.left.expression;
|
||||||
|
flattened.left = flattened.left.clone();
|
||||||
|
flattened.left.expression = expr.left.clone();
|
||||||
|
tail.unshift(flattened);
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (tail.length == 0) continue;
|
||||||
if (!trim_assigns(expr.left, expr.right, tail)) continue;
|
if (!trim_assigns(expr.left, expr.right, tail)) continue;
|
||||||
trimmed = true;
|
trimmed = true;
|
||||||
exprs = exprs.slice(0, i + 1).concat(tail);
|
exprs = exprs.slice(0, i).concat(expr, tail);
|
||||||
}
|
}
|
||||||
if (defn instanceof AST_Definitions) {
|
if (defn instanceof AST_Definitions) {
|
||||||
keep = keep || 0;
|
keep = keep || 0;
|
||||||
@@ -3498,6 +3509,10 @@ merge(Compressor.prototype, {
|
|||||||
if (defn instanceof AST_Var && join_var_assign(defn.definitions, exprs, keep)) trimmed = true;
|
if (defn instanceof AST_Var && join_var_assign(defn.definitions, exprs, keep)) trimmed = true;
|
||||||
}
|
}
|
||||||
return trimmed && exprs;
|
return trimmed && exprs;
|
||||||
|
|
||||||
|
function can_trim(node) {
|
||||||
|
return node instanceof AST_Assign && node.operator == "=";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function merge_assigns(prev, defn) {
|
function merge_assigns(prev, defn) {
|
||||||
@@ -3554,22 +3569,35 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function trim_assigns(name, value, exprs) {
|
function trim_assigns(name, value, exprs) {
|
||||||
|
var names = Object.create(null);
|
||||||
|
names[name.name] = true;
|
||||||
|
while (value instanceof AST_Assign && value.operator == "=") {
|
||||||
|
if (value.left instanceof AST_SymbolRef) names[value.left.name] = true;
|
||||||
|
value = value.right;
|
||||||
|
}
|
||||||
if (!(value instanceof AST_Object)) return;
|
if (!(value instanceof AST_Object)) return;
|
||||||
var trimmed = false;
|
var trimmed = false;
|
||||||
do {
|
do {
|
||||||
var node = exprs[0];
|
if (!try_join(exprs[0])) break;
|
||||||
if (!(node instanceof AST_Assign)) break;
|
exprs.shift();
|
||||||
if (node.operator != "=") break;
|
trimmed = true;
|
||||||
if (!(node.left instanceof AST_PropAccess)) break;
|
} while (exprs.length);
|
||||||
|
return trimmed;
|
||||||
|
|
||||||
|
function try_join(node) {
|
||||||
|
if (!(node instanceof AST_Assign)) return;
|
||||||
|
if (node.operator != "=") return;
|
||||||
|
if (!(node.left instanceof AST_PropAccess)) return;
|
||||||
var sym = node.left.expression;
|
var sym = node.left.expression;
|
||||||
if (!(sym instanceof AST_SymbolRef)) break;
|
if (!(sym instanceof AST_SymbolRef)) return;
|
||||||
if (name.name != sym.name) break;
|
if (!names[sym.name]) return;
|
||||||
if (!node.right.is_constant_expression(scope)) break;
|
if (!node.right.is_constant_expression(scope)) return;
|
||||||
var prop = node.left.property;
|
var prop = node.left.property;
|
||||||
if (prop instanceof AST_Node) {
|
if (prop instanceof AST_Node) {
|
||||||
|
if (try_join(prop)) prop = node.left.property = prop.right;
|
||||||
prop = prop.evaluate(compressor);
|
prop = prop.evaluate(compressor);
|
||||||
}
|
}
|
||||||
if (prop instanceof AST_Node) break;
|
if (prop instanceof AST_Node) return;
|
||||||
prop = "" + prop;
|
prop = "" + prop;
|
||||||
var diff = prop == "__proto__" || compressor.has_directive("use strict") ? function(node) {
|
var diff = prop == "__proto__" || compressor.has_directive("use strict") ? function(node) {
|
||||||
var key = node.key;
|
var key = node.key;
|
||||||
@@ -3581,15 +3609,13 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
return key !== "__proto__";
|
return key !== "__proto__";
|
||||||
};
|
};
|
||||||
if (!all(value.properties, diff)) break;
|
if (!all(value.properties, diff)) return;
|
||||||
value.properties.push(make_node(AST_ObjectKeyVal, node, {
|
value.properties.push(make_node(AST_ObjectKeyVal, node, {
|
||||||
key: prop,
|
key: prop,
|
||||||
value: node.right
|
value: node.right
|
||||||
}));
|
}));
|
||||||
exprs.shift();
|
return true;
|
||||||
trimmed = true;
|
}
|
||||||
} while (exprs.length);
|
|
||||||
return trimmed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function join_consecutive_vars(statements) {
|
function join_consecutive_vars(statements) {
|
||||||
|
|||||||
@@ -489,6 +489,91 @@ join_object_assignments_regex: {
|
|||||||
expect_stdout: "1"
|
expect_stdout: "1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chained_assignments: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a, b = a = {};
|
||||||
|
b.p = "PASS";
|
||||||
|
console.log(a.p);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a, b = a = {
|
||||||
|
p: "PASS",
|
||||||
|
};
|
||||||
|
console.log(a.p);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
folded_assignments: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = {};
|
||||||
|
a[a.PASS = 42] = "PASS";
|
||||||
|
console.log(a[42], a.PASS);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = {
|
||||||
|
PASS: 42,
|
||||||
|
42: "PASS",
|
||||||
|
};
|
||||||
|
console.log(a[42], a.PASS);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS 42"
|
||||||
|
}
|
||||||
|
|
||||||
|
inlined_assignments: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
(a = {}).p = "PASS";
|
||||||
|
console.log(a.p);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = {
|
||||||
|
p: "PASS",
|
||||||
|
};
|
||||||
|
console.log(a.p);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
typescript_enum: {
|
||||||
|
rename = true
|
||||||
|
options = {
|
||||||
|
assignments: true,
|
||||||
|
evaluate: true,
|
||||||
|
hoist_props: true,
|
||||||
|
inline: true,
|
||||||
|
join_vars: true,
|
||||||
|
passes: 4,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var Enum;
|
||||||
|
(function (Enum) {
|
||||||
|
Enum[Enum.PASS = 42] = "PASS";
|
||||||
|
})(Enum || (Enum = {}));
|
||||||
|
console.log(Enum[42], Enum.PASS);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("PASS", 42);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS 42"
|
||||||
|
}
|
||||||
|
|
||||||
issue_2816: {
|
issue_2816: {
|
||||||
options = {
|
options = {
|
||||||
join_vars: true,
|
join_vars: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user