diff --git a/lib/compress.js b/lib/compress.js index 60cabf3467d..1fa0cf86299 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -3632,7 +3632,8 @@ Compressor.prototype.compress = function(node) { var value = stat.body.value; var in_bool = stat.body.in_bool || next instanceof AST_Return && next.in_bool; // if (foo()) return x; return y; ---> return foo() ? x : y; - if (!stat.alternative && next instanceof AST_Return) { + if (!stat.alternative && next instanceof AST_Return + && (!value == !next.value || !in_async_generator(in_lambda))) { changed = true; stat = stat.clone(); stat.alternative = make_node(AST_BlockStatement, next, { @@ -9677,16 +9678,25 @@ Compressor.prototype.compress = function(node) { alternative: null, }); if (self.alternative instanceof AST_Exit && self.body.TYPE == self.alternative.TYPE) { - var exit = make_node(self.body.CTOR, self, { - value: make_node(AST_Conditional, self, { - condition: self.condition, - consequent: self.body.value || make_node(AST_Undefined, self.body).transform(compressor), - alternative: self.alternative.value - || make_node(AST_Undefined, self.alternative).transform(compressor), - }), - }); - if (exit instanceof AST_Return) exit.in_bool = self.body.in_bool || self.alternative.in_bool; - return exit; + var cons_value = self.body.value; + var alt_value = self.alternative.value; + if (!cons_value && !alt_value) return make_node(AST_BlockStatement, self, { + body: [ + make_node(AST_SimpleStatement, self, { body: self.condition }), + self.body, + ], + }).optimize(compressor); + if (cons_value && alt_value || !in_async_generator(compressor.find_parent(AST_Scope))) { + var exit = make_node(self.body.CTOR, self, { + value: make_node(AST_Conditional, self, { + condition: self.condition, + consequent: cons_value || make_node(AST_Undefined, self.body).transform(compressor), + alternative: alt_value || make_node(AST_Undefined, self.alternative).transform(compressor), + }), + }); + if (exit instanceof AST_Return) exit.in_bool = self.body.in_bool || self.alternative.in_bool; + return exit; + } } if (self.body instanceof AST_If && !self.body.alternative && !self.alternative) { self = make_node(AST_If, self, { diff --git a/test/compress/yields.js b/test/compress/yields.js index 989a9fa70e0..f2bb9b295f0 100644 --- a/test/compress/yields.js +++ b/test/compress/yields.js @@ -1769,3 +1769,223 @@ issue_5663: { ] node_version: ">=6" } + +issue_5679_1: { + options = { + conditionals: true, + } + input: { + var a = "FAIL"; + async function* f(b) { + try { + if (b) + return; + else + return; + } finally { + a = "PASS"; + } + } + f().next(); + console.log(a); + } + expect: { + var a = "FAIL"; + async function* f(b) { + try { + b; + return; + } finally { + a = "PASS"; + } + } + f().next(); + console.log(a); + } + expect_stdout: "PASS" + node_version: ">=10" +} + +issue_5679_2: { + options = { + conditionals: true, + } + input: { + var a = "FAIL"; + async function* f(b) { + try { + if (b) + return undefined; + else + return; + } finally { + a = "PASS"; + } + } + f().next(); + console.log(a); + } + expect: { + var a = "FAIL"; + async function* f(b) { + try { + if (b) + return void 0; + return; + } finally { + a = "PASS"; + } + } + f().next(); + console.log(a); + } + expect_stdout: "PASS" + node_version: ">=10" +} + +issue_5679_3: { + options = { + conditionals: true, + } + input: { + var a = "FAIL"; + async function* f(b) { + try { + if (b) + return; + else + return undefined; + } finally { + a = "PASS"; + } + } + f(42).next(); + console.log(a); + } + expect: { + var a = "FAIL"; + async function* f(b) { + try { + if (b) + return; + return void 0; + } finally { + a = "PASS"; + } + } + f(42).next(); + console.log(a); + } + expect_stdout: "PASS" + node_version: ">=10" +} + +issue_5679_4: { + options = { + conditionals: true, + } + input: { + var a = "PASS"; + async function* f(b) { + try { + if (b) + return undefined; + else + return undefined; + } finally { + a = "FAIL"; + } + } + f(null).next(); + console.log(a); + } + expect: { + var a = "PASS"; + async function* f(b) { + try { + return b, void 0; + } finally { + a = "FAIL"; + } + } + f(null).next(); + console.log(a); + } + expect_stdout: "PASS" + node_version: ">=10" +} + +issue_5679_5: { + options = { + conditionals: true, + if_return: true, + } + input: { + var a = "FAIL"; + async function* f(b) { + try { + if (b) + return console; + else + return; + } finally { + a = "PASS"; + } + } + f().next(); + console.log(a); + } + expect: { + var a = "FAIL"; + async function* f(b) { + try { + if (b) + return console; + return; + } finally { + a = "PASS"; + } + } + f().next(); + console.log(a); + } + expect_stdout: "PASS" + node_version: ">=10" +} + +issue_5679_6: { + options = { + conditionals: true, + if_return: true, + } + input: { + var a = "PASS"; + async function* f(b) { + try { + if (b) + return; + else + return console; + } finally { + a = "FAIL"; + } + } + f().next(); + console.log(a); + } + expect: { + var a = "PASS"; + async function* f(b) { + try { + if (!b) + return console; + } finally { + a = "FAIL"; + } + } + f().next(); + console.log(a); + } + expect_stdout: "PASS" + node_version: ">=10" +}