fix AST_Binary.lift_sequences() (#1621)

Commit eab99a1c fails to account for side effects from compound assignments.
This commit is contained in:
Alex Lam S.L
2017-03-19 03:04:22 +08:00
committed by GitHub
parent 274331d0ea
commit cd58635dcc
2 changed files with 39 additions and 22 deletions

View File

@@ -2999,14 +2999,6 @@ merge(Compressor.prototype, {
return self; return self;
}); });
function has_side_effects_or_prop_access(node, compressor) {
var save_pure_getters = compressor.option("pure_getters");
compressor.options.pure_getters = false;
var ret = node.has_side_effects(compressor);
compressor.options.pure_getters = save_pure_getters;
return ret;
}
AST_Binary.DEFMETHOD("lift_sequences", function(compressor){ AST_Binary.DEFMETHOD("lift_sequences", function(compressor){
if (compressor.option("sequences")) { if (compressor.option("sequences")) {
if (this.left instanceof AST_Seq) { if (this.left instanceof AST_Seq) {
@@ -3014,18 +3006,23 @@ merge(Compressor.prototype, {
var x = seq.to_array(); var x = seq.to_array();
this.left = x.pop(); this.left = x.pop();
x.push(this); x.push(this);
seq = AST_Seq.from_array(x).transform(compressor); return AST_Seq.from_array(x).optimize(compressor);
return seq;
} }
if (this.right instanceof AST_Seq if (this.right instanceof AST_Seq && !this.left.has_side_effects(compressor)) {
&& this instanceof AST_Assign var assign = this.operator == "=" && this.left instanceof AST_SymbolRef;
&& !has_side_effects_or_prop_access(this.left, compressor)) { var root = this.right;
var seq = this.right; var cursor, seq = root;
var x = seq.to_array(); while (assign || !seq.car.has_side_effects(compressor)) {
this.right = x.pop(); cursor = seq;
x.push(this); if (seq.cdr instanceof AST_Seq) {
seq = AST_Seq.from_array(x).transform(compressor); seq = seq.cdr;
return seq; } else break;
}
if (cursor) {
this.right = cursor.cdr;
cursor.cdr = this;
return root.optimize(compressor);
}
} }
} }
return this; return this;

View File

@@ -103,15 +103,18 @@ lift_sequences_1: {
lift_sequences_2: { lift_sequences_2: {
options = { sequences: true, evaluate: true }; options = { sequences: true, evaluate: true };
input: { input: {
var foo, bar; var foo = 1, bar;
foo.x = (foo = {}, 10); foo.x = (foo = {}, 10);
bar = (bar = {}, 10); bar = (bar = {}, 10);
console.log(foo, bar);
} }
expect: { expect: {
var foo, bar; var foo = 1, bar;
foo.x = (foo = {}, 10), foo.x = (foo = {}, 10),
bar = {}, bar = 10; bar = {}, bar = 10,
console.log(foo, bar);
} }
expect_stdout: true
} }
lift_sequences_3: { lift_sequences_3: {
@@ -138,6 +141,23 @@ lift_sequences_4: {
} }
} }
lift_sequences_5: {
options = {
sequences: true,
}
input: {
var a = 2, b;
a *= (b, a = 4, 3);
console.log(a);
}
expect: {
var a = 2, b;
b, a *= (a = 4, 3),
console.log(a);
}
expect_stdout: "6"
}
for_sequences: { for_sequences: {
options = { sequences: true }; options = { sequences: true };
input: { input: {