From 48c46fa9a72e480ddae721548fc2de929a7e925a Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Thu, 18 Mar 2021 00:31:55 +0000 Subject: [PATCH] fix corner case in `sequences` (#4798) --- lib/compress.js | 18 ++++++++---- test/compress/sequences.js | 57 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 6 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index c655803060..2224e144be 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -9443,14 +9443,9 @@ merge(Compressor.prototype, { && !(exp instanceof AST_SymbolRef || exp instanceof AST_PropAccess || is_identifier_atom(exp))) { - if (exp instanceof AST_Sequence) { - exp = exp.expressions.slice(); - exp.push(make_node(AST_True, self)); - return make_sequence(self, exp).optimize(compressor); - } return make_sequence(self, [ exp, make_node(AST_True, self) ]).optimize(compressor); } - if (compressor.option("sequences") && !(op == "typeof" && is_undeclared_ref(exp.tail_node()))) { + if (compressor.option("sequences") && can_lift()) { var seq = lift_sequence_in_expression(self, compressor); if (seq !== self) return seq.optimize(compressor); } @@ -9500,6 +9495,17 @@ merge(Compressor.prototype, { // avoids infinite recursion of numerals return op == "-" && (exp instanceof AST_Number || exp instanceof AST_Infinity) ? self : try_evaluate(compressor, self); + + function can_lift() { + switch (op) { + case "delete": + return !is_identifier_atom(exp.tail_node()); + case "typeof": + return !is_undeclared_ref(exp.tail_node()); + default: + return true; + } + } }); OPT(AST_Await, function(self, compressor) { diff --git a/test/compress/sequences.js b/test/compress/sequences.js index 90de1974c4..cc05fd7b84 100644 --- a/test/compress/sequences.js +++ b/test/compress/sequences.js @@ -564,6 +564,34 @@ delete_seq_3: { } delete_seq_4: { + options = { + booleans: true, + evaluate: false, + sequences: true, + side_effects: true, + } + input: { + function f() {} + console.log(delete (f(), undefined)); + console.log(delete (f(), void 0)); + console.log(delete (f(), Infinity)); + console.log(delete (f(), 1 / 0)); + console.log(delete (f(), NaN)); + console.log(delete (f(), 0 / 0)); + } + expect: { + function f() {} + console.log(delete void f()), + console.log(delete void f()), + console.log((f(), delete (1 / 0))), + console.log((f(), delete (1 / 0))), + console.log(delete (f(), NaN)), + console.log((f(), delete(0 / 0))); + } + expect_stdout: true +} + +delete_seq_4_evaluate: { options = { booleans: true, evaluate: true, @@ -592,6 +620,35 @@ delete_seq_4: { } delete_seq_5: { + options = { + booleans: true, + evaluate: false, + keep_infinity: true, + sequences: true, + side_effects: true, + } + input: { + function f() {} + console.log(delete (f(), undefined)); + console.log(delete (f(), void 0)); + console.log(delete (f(), Infinity)); + console.log(delete (f(), 1 / 0)); + console.log(delete (f(), NaN)); + console.log(delete (f(), 0 / 0)); + } + expect: { + function f() {} + console.log(delete void f()), + console.log(delete void f()), + console.log(delete (f(), Infinity)), + console.log((f(), delete (1 / 0))), + console.log(delete (f(), NaN)), + console.log((f(), delete (0 / 0))); + } + expect_stdout: true +} + +delete_seq_5_evaluate: { options = { booleans: true, evaluate: true,