join object assignments (#2763)
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1100,3 +1100,65 @@ const_prop_assign_pure: {
|
||||
x();
|
||||
}
|
||||
}
|
||||
|
||||
join_object_assignments_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
var x = {
|
||||
a: 1,
|
||||
c: (console.log("c"), "C"),
|
||||
};
|
||||
x.b = 2;
|
||||
x[3] = function() {
|
||||
console.log(x);
|
||||
},
|
||||
x["a"] = /foo/,
|
||||
x.bar = x;
|
||||
return x;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var x = {
|
||||
a: 1,
|
||||
c: (console.log("c"), "C"),
|
||||
b: 2,
|
||||
3: function() {
|
||||
console.log(x);
|
||||
},
|
||||
a: /foo/,
|
||||
};
|
||||
x.bar = x;
|
||||
return x;
|
||||
}());
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
join_object_assignments_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
join_vars: true,
|
||||
passes: 3,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
foo: 1,
|
||||
};
|
||||
o.bar = 2;
|
||||
o.baz = 3;
|
||||
console.log(o.foo, o.bar + o.bar, o.foo * o.bar * o.baz);
|
||||
}
|
||||
expect: {
|
||||
console.log(1, 4, 6);
|
||||
}
|
||||
expect_stdout: "1 4 6"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user