diff --git a/lib/compress.js b/lib/compress.js index af462ba9..7729ffde 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -8055,8 +8055,16 @@ Compressor.prototype.compress = function(node) { if (!compressor.option("awaits")) return this; var exp = this.expression; if (!is_primitive(compressor, exp)) return this; + if (exp instanceof AST_UnaryPrefix && exp.operator == "!") exp = exp.expression; + var dropped = exp.drop_side_effect_free(compressor); + if (dropped === exp) return this; + if (!dropped) { + dropped = make_node(AST_Number, exp, { value: 0 }); + } else if (!is_primitive(compressor, dropped)) { + dropped = dropped.negate(compressor); + } var node = this.clone(); - node.expression = exp.drop_side_effect_free(compressor) || make_node(AST_Number, this, { value: 0 }); + node.expression = dropped; return node; }); def(AST_Binary, function(compressor, first_in_statement) { @@ -8400,7 +8408,8 @@ Compressor.prototype.compress = function(node) { if (compressor.option("awaits") && end > 0 && last instanceof AST_Await && last.expression.is_constant()) { expressions = expressions.slice(0, -1); end--; - last.expression = expressions[end]; + var expr = expressions[end]; + last.expression = is_primitive(compressor, expr) ? expr : expr.negate(compressor); expressions[end] = last; } var assign, cond, lhs; @@ -10728,13 +10737,7 @@ Compressor.prototype.compress = function(node) { if (compressor.option("side_effects")) { var exp = self.expression; if (exp instanceof AST_Await) return exp.optimize(compressor); - if (exp instanceof AST_UnaryPrefix) { - if (exp.expression instanceof AST_Await) return exp.optimize(compressor); - if (exp.operator == "void") return make_node(AST_UnaryPrefix, self, { - operator: "void", - expression: make_node(AST_Await, self, { expression: exp.expression }), - }).optimize(compressor); - } + if (exp instanceof AST_UnaryPrefix && exp.expression instanceof AST_Await) return exp.optimize(compressor); for (var level = 0, node = self, parent; parent = compressor.parent(level++); node = parent) { if (is_arrow(parent)) { if (parent.value === node) return exp.optimize(compressor); diff --git a/test/compress/awaits.js b/test/compress/awaits.js index 68459fab..91c5c3ef 100644 --- a/test/compress/awaits.js +++ b/test/compress/awaits.js @@ -693,7 +693,124 @@ inline_block_return_async: { node_version: ">=8" } -await_unary: { +await_then: { + options = { + awaits: true, + side_effects: true, + } + input: { + var a = "PASS"; + function f() { + return { + then: function(r) { + a = "FAIL"; + r(); + }, + }; + } + (async function() { + f(), await 42; + while (console.log(a)); + })(); + } + expect: { + var a = "PASS"; + function f() { + return { + then: function(r) { + a = "FAIL"; + r(); + }, + }; + } + (async function() { + await !f(); + while (console.log(a)); + })(); + } + expect_stdout: "PASS" + node_version: ">=8" +} + +await_unary_1: { + options = { + awaits: true, + side_effects: true, + } + input: { + var a = "PASS"; + function f() { + return { + then: function(r) { + a = "FAIL"; + r(); + }, + }; + } + (async function() { + await !f(); + while (console.log(a)); + })(); + } + expect: { + var a = "PASS"; + function f() { + return { + then: function(r) { + a = "FAIL"; + r(); + }, + }; + } + (async function() { + await !f(); + while (console.log(a)); + })(); + } + expect_stdout: "PASS" + node_version: ">=8" +} + +await_unary_2: { + options = { + awaits: true, + side_effects: true, + } + input: { + var a = "PASS"; + function f() { + return { + then: function(r) { + a = "FAIL"; + r(); + }, + }; + } + (async function() { + await ~f(); + while (console.log(a)); + })(); + } + expect: { + var a = "PASS"; + function f() { + return { + then: function(r) { + a = "FAIL"; + r(); + }, + }; + } + (async function() { + await !f(); + while (console.log(a)); + })(); + } + expect_stdout: "PASS" + node_version: ">=8" +} + +await_unary_3: { options = { awaits: true, side_effects: true, @@ -720,7 +837,46 @@ await_unary: { node_version: ">=8" } -await_void: { +await_void_1: { + options = { + awaits: true, + side_effects: true, + } + input: { + var a = "PASS"; + function f() { + return { + then: function(r) { + a = "FAIL"; + r(); + }, + }; + } + (async function() { + await void f(); + while (console.log(a)); + })(); + } + expect: { + var a = "PASS"; + function f() { + return { + then: function(r) { + a = "FAIL"; + r(); + }, + }; + } + (async function() { + await !f(); + while (console.log(a)); + })(); + } + expect_stdout: "PASS" + node_version: ">=8" +} + +await_void_2: { options = { awaits: true, if_return: true, @@ -735,7 +891,7 @@ await_void: { } expect: { (async function() { - await console.log("PASS"); + console.log("PASS"); })(); } expect_stdout: "PASS"