});
OPT(AST_Seq, function(self, compressor){
+ if (!compressor.option("side_effects"))
+ return self;
+ if (!self.car.has_side_effects())
+ return self.cdr;
if (compressor.option("cascade")) {
if (self.car instanceof AST_Assign
&& !self.car.left.has_side_effects()
return self;
});
+ AST_Unary.DEFMETHOD("lift_sequences", function(compressor){
+ if (compressor.option("sequences")) {
+ if (this.expression instanceof AST_Seq) {
+ var seq = this.expression;
+ var x = seq.to_array();
+ this.expression = x.pop();
+ x.push(this);
+ seq = AST_Seq.from_array(x).transform(compressor);
+ return seq;
+ }
+ }
+ return this;
+ });
+
+ OPT(AST_UnaryPostfix, function(self, compressor){
+ return self.lift_sequences(compressor);
+ });
+
OPT(AST_UnaryPrefix, function(self, compressor){
+ self = self.lift_sequences(compressor);
var e = self.expression;
if (compressor.option("booleans") && compressor.in_boolean_context()) {
switch (self.operator) {
return self.evaluate(compressor)[0];
});
+ AST_Binary.DEFMETHOD("lift_sequences", function(compressor){
+ if (compressor.option("sequences")) {
+ if (this.left instanceof AST_Seq) {
+ var seq = this.left;
+ var x = seq.to_array();
+ this.left = x.pop();
+ x.push(this);
+ seq = AST_Seq.from_array(x).transform(compressor);
+ return seq;
+ }
+ if (this.right instanceof AST_Seq
+ && !(this.operator == "||" || this.operator == "&&")
+ && !this.left.has_side_effects()) {
+ var seq = this.right;
+ var x = seq.to_array();
+ this.right = x.pop();
+ x.push(this);
+ seq = AST_Seq.from_array(x).transform(compressor);
+ return seq;
+ }
+ }
+ return this;
+ });
+
OPT(AST_Binary, function(self, compressor){
+ self = self.lift_sequences(compressor);
if (compressor.option("comparisons")) switch (self.operator) {
case "===":
case "!==":
var ASSIGN_OPS = [ '+', '-', '/', '*', '%', '>>', '<<', '>>>', '|', '^', '&' ];
OPT(AST_Assign, function(self, compressor){
+ self = self.lift_sequences(compressor);
if (self.operator == "="
&& self.left instanceof AST_SymbolRef
&& self.right instanceof AST_Binary
var p = output.parent();
return p instanceof AST_Call // (foo, bar)() or foo(1, (2, 3), 4)
|| p instanceof AST_Unary // !(foo, bar, baz)
- || p instanceof AST_Binary // 1 + (2, 3) + 4 ==> 7
+ || p instanceof AST_Binary // 1 + (2, 3) + 4 ==> 8
|| p instanceof AST_VarDef // var a = (1, 2), b = a + a; ==> b == 4
|| p instanceof AST_Dot // (1, {foo:2}).foo ==> 2
|| p instanceof AST_Array // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ]
with (x = 5, obj);
}
}
+
+lift_sequences_1: {
+ options = { sequences: true };
+ input: {
+ foo = !(x(), y(), bar());
+ }
+ expect: {
+ x(), y(), foo = !bar();
+ }
+}
+
+lift_sequences_2: {
+ options = { sequences: true, evaluate: true };
+ input: {
+ q = 1 + (foo(), bar(), 5) + 7 * (5 / (3 - (a(), (QW=ER), c(), 2))) - (x(), y(), 5);
+ }
+ expect: {
+ foo(), bar(), a(), QW = ER, c(), x(), y(), q = 36
+ }
+}
+
+lift_sequences_3: {
+ options = { sequences: true, conditionals: true };
+ input: {
+ x = (foo(), bar(), baz()) ? 10 : 20;
+ }
+ expect: {
+ foo(), bar(), x = baz() ? 10 : 20;
+ }
+}
+
+lift_sequences_4: {
+ options = { side_effects: true };
+ input: {
+ x = (foo, bar, baz);
+ }
+ expect: {
+ x = baz;
+ }
+}