join object assignments (#2763)

This commit is contained in:
Alex Lam S.L
2018-01-11 17:08:21 +08:00
committed by GitHub
parent 6a0af85c8b
commit f1e1bb419a
2 changed files with 109 additions and 1 deletions

View File

@@ -869,6 +869,7 @@ merge(Compressor.prototype, {
}
function tighten_body(statements, compressor) {
var scope = compressor.find_parent(AST_Scope);
var CHANGED, max_iter = 10;
do {
CHANGED = false;
@@ -900,7 +901,6 @@ merge(Compressor.prototype, {
// Will not attempt to collapse assignments into or past code blocks
// which are not sequentially executed, e.g. loops and conditionals.
function collapse(statements, compressor) {
var scope = compressor.find_parent(AST_Scope);
if (scope.uses_eval || scope.uses_with) return statements;
var args;
var candidates = [];
@@ -1696,6 +1696,41 @@ merge(Compressor.prototype, {
statements.length = n;
}
function join_object_assignments(defn, body) {
if (!(defn instanceof AST_Definitions)) return;
var exprs;
if (body instanceof AST_Assign) {
exprs = [ body ];
} else if (body instanceof AST_Sequence) {
exprs = body.expressions.slice();
}
if (!exprs) return;
do {
var node = exprs[0];
if (!(node instanceof AST_Assign)) break;
if (!(node.left instanceof AST_PropAccess)) break;
var sym = node.left.expression;
if (!(sym instanceof AST_SymbolRef)) break;
var def = find_if(function(def) {
return def.name.name == sym.name
&& def.value instanceof AST_Object;
}, defn.definitions);
if (!def) break;
if (!node.right.is_constant_expression(scope)) break;
var prop = node.left.property;
if (prop instanceof AST_Node) {
prop = prop.evaluate(compressor);
}
if (prop instanceof AST_Node) break;
def.value.properties.push(make_node(AST_ObjectKeyVal, node, {
key: prop,
value: node.right
}));
exprs.shift();
} while (exprs.length);
return exprs;
}
function join_consecutive_vars(statements, compressor) {
var defs;
for (var i = 0, j = -1, len = statements.length; i < len; i++) {
@@ -1728,6 +1763,17 @@ merge(Compressor.prototype, {
} else {
statements[++j] = stat;
}
} else if (stat instanceof AST_SimpleStatement) {
var exprs = join_object_assignments(prev, stat.body);
if (exprs) {
if (exprs.length > 0) {
stat.body = make_sequence(stat.body, exprs);
statements[++j] = stat;
}
CHANGED = true;
} else {
statements[++j] = stat;
}
} else {
statements[++j] = stat;
}