join object assignments (#2763)
This commit is contained in:
@@ -869,6 +869,7 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function tighten_body(statements, compressor) {
|
function tighten_body(statements, compressor) {
|
||||||
|
var scope = compressor.find_parent(AST_Scope);
|
||||||
var CHANGED, max_iter = 10;
|
var CHANGED, max_iter = 10;
|
||||||
do {
|
do {
|
||||||
CHANGED = false;
|
CHANGED = false;
|
||||||
@@ -900,7 +901,6 @@ merge(Compressor.prototype, {
|
|||||||
// Will not attempt to collapse assignments into or past code blocks
|
// Will not attempt to collapse assignments into or past code blocks
|
||||||
// which are not sequentially executed, e.g. loops and conditionals.
|
// which are not sequentially executed, e.g. loops and conditionals.
|
||||||
function collapse(statements, compressor) {
|
function collapse(statements, compressor) {
|
||||||
var scope = compressor.find_parent(AST_Scope);
|
|
||||||
if (scope.uses_eval || scope.uses_with) return statements;
|
if (scope.uses_eval || scope.uses_with) return statements;
|
||||||
var args;
|
var args;
|
||||||
var candidates = [];
|
var candidates = [];
|
||||||
@@ -1696,6 +1696,41 @@ merge(Compressor.prototype, {
|
|||||||
statements.length = n;
|
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) {
|
function join_consecutive_vars(statements, compressor) {
|
||||||
var defs;
|
var defs;
|
||||||
for (var i = 0, j = -1, len = statements.length; i < len; i++) {
|
for (var i = 0, j = -1, len = statements.length; i < len; i++) {
|
||||||
@@ -1728,6 +1763,17 @@ merge(Compressor.prototype, {
|
|||||||
} else {
|
} else {
|
||||||
statements[++j] = stat;
|
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 {
|
} else {
|
||||||
statements[++j] = stat;
|
statements[++j] = stat;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1100,3 +1100,65 @@ const_prop_assign_pure: {
|
|||||||
x();
|
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