diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2021-07-07 17:29:23 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-08 00:29:23 +0800 |
commit | 6577d641ac82419d462f11fee73a7b067e793003 (patch) | |
tree | 9e57daf56b31eb61a3a47d3b2fd8417a22d3fe1f | |
parent | 2340feff875eb4b32e95abfe7526dede72ba2253 (diff) | |
download | tracifyjs-6577d641ac82419d462f11fee73a7b067e793003.tar.gz tracifyjs-6577d641ac82419d462f11fee73a7b067e793003.zip |
enhance `evaluate` & `reduce_vars` (#5060)
-rw-r--r-- | lib/compress.js | 65 | ||||
-rw-r--r-- | test/compress/default-values.js | 55 | ||||
-rw-r--r-- | test/compress/hoist_vars.js | 4 | ||||
-rw-r--r-- | test/compress/reduce_vars.js | 1 |
4 files changed, 78 insertions, 47 deletions
diff --git a/lib/compress.js b/lib/compress.js index de74f56c..90261d0a 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -734,7 +734,12 @@ merge(Compressor.prototype, { var save = fixed; if (save) fixed = function() { var value = save(); - return is_undefined(value) ? make_sequence(node, [ value, node.value ]) : node; + var ev; + if (is_undefined(value, compressor) + || (ev = fuzzy_eval(compressor, value, true)) === undefined) { + return make_sequence(node, [ value, node.value ]); + } + return ev instanceof AST_Node ? node : value; }; node.name.walk(scanner); fixed = save; @@ -7293,7 +7298,7 @@ merge(Compressor.prototype, { node.in_bool = true; var value = node.value; if (value) { - var ev = value.is_truthy() || value.evaluate(compressor, true); + var ev = fuzzy_eval(compressor, value); if (!ev) { value = value.drop_side_effect_free(compressor); node.value = value ? make_sequence(node.value, [ @@ -8006,7 +8011,7 @@ merge(Compressor.prototype, { OPT(AST_Do, function(self, compressor) { if (!compressor.option("loops")) return self; - var cond = self.condition.is_truthy() || self.condition.evaluate(compressor, true); + var cond = fuzzy_eval(compressor, self.condition); if (!(cond instanceof AST_Node)) { if (cond && !has_loop_control(self, compressor.parent(), AST_Continue)) return make_node(AST_For, self, { body: make_node(AST_BlockStatement, self.body, { @@ -8174,36 +8179,25 @@ merge(Compressor.prototype, { if (self.step) self.step = self.step.drop_side_effect_free(compressor); } if (self.condition) { - var cond = self.condition.evaluate(compressor); - if (cond instanceof AST_Node) { - cond = self.condition.is_truthy() || self.condition.evaluate(compressor, true); - } else if (cond) { - self.condition = null; - } + var cond = fuzzy_eval(compressor, self.condition); if (!cond) { if (compressor.option("dead_code")) { var body = []; if (is_statement(self.init)) { body.push(self.init); } else if (self.init) { - body.push(make_node(AST_SimpleStatement, self.init, { - body: self.init - })); + body.push(make_node(AST_SimpleStatement, self.init, { body: self.init })); } - body.push(make_node(AST_SimpleStatement, self.condition, { - body: self.condition - })); + body.push(make_node(AST_SimpleStatement, self.condition, { body: self.condition })); extract_declarations_from_unreachable_code(compressor, self.body, body); return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor); } - } else if (self.condition && !(cond instanceof AST_Node)) { + } else if (!(cond instanceof AST_Node)) { self.body = make_node(AST_BlockStatement, self.body, { body: [ - make_node(AST_SimpleStatement, self.condition, { - body: self.condition - }), - self.body - ] + make_node(AST_SimpleStatement, self.condition, { body: self.condition }), + self.body, + ], }); self.condition = null; } @@ -8894,7 +8888,7 @@ merge(Compressor.prototype, { if (!compressor.option("optional_chains")) return; if (!self.optional) return; var expr = self.expression; - var ev = expr.evaluate(compressor, true); + var ev = fuzzy_eval(compressor, expr, true); if (ev == null) return make_node(AST_UnaryPrefix, self, { operator: "void", expression: expr, @@ -10492,7 +10486,7 @@ merge(Compressor.prototype, { } // (x || false) && y ---> x ? y : false if (self.left.operator == "||") { - var lr = self.left.right.evaluate(compressor, true); + var lr = fuzzy_eval(compressor, self.left.right); if (!lr) return make_node(AST_Conditional, self, { condition: self.left.left, consequent: self.right, @@ -10545,7 +10539,7 @@ merge(Compressor.prototype, { } // x && true || y ---> x ? true : y if (!nullish && self.left.operator == "&&") { - var lr = self.left.right.is_truthy() || self.left.right.evaluate(compressor, true); + var lr = fuzzy_eval(compressor, self.left.right); if (lr && !(lr instanceof AST_Node)) return make_node(AST_Conditional, self, { condition: self.left.left, consequent: self.left.right, @@ -11070,21 +11064,16 @@ merge(Compressor.prototype, { } var local = self.fixed !== def.fixed; if (fixed && (local || def.should_replace !== false)) { - var init; + var ev, init; if (fixed instanceof AST_This) { - if (!is_funarg(def) && same_scope(def)) { - init = fixed; - } - } else { - var ev = fixed.evaluate(compressor, true); - if (ev !== fixed - && typeof ev != "function" - && (typeof ev != "object" - || ev instanceof RegExp - && compressor.option("unsafe_regexp") - && !def.cross_loop && same_scope(def))) { - init = make_node_from_constant(ev, fixed); - } + if (!is_funarg(def) && same_scope(def)) init = fixed; + } else if ((ev = fixed.evaluate(compressor, true)) !== fixed + && typeof ev != "function" + && (ev === null + || typeof ev != "object" + || compressor.option("unsafe_regexp") + && ev instanceof RegExp && !def.cross_loop && same_scope(def))) { + init = make_node_from_constant(ev, fixed); } if (init) { if (!local && def.should_replace === undefined) { diff --git a/test/compress/default-values.js b/test/compress/default-values.js index b3662715..de5374fa 100644 --- a/test/compress/default-values.js +++ b/test/compress/default-values.js @@ -149,7 +149,7 @@ process_boolean_returns: { } expect: { console.log(function(a = console.log("FAIL 1")) { - return a() ? "PASS" : "FAIL 2"; + return 42 ? "PASS" : "FAIL 2"; }(function() { return 1; })); @@ -245,21 +245,64 @@ maintain_if: { node_version: ">=6" } -reduce_value: { +reduce_funarg: { options = { evaluate: true, + keep_fargs: false, reduce_vars: true, unused: true, } input: { - console.log(function(a = "PASS") { - return a; + console.log(...function(a = "foo", b = "bar", c = "baz") { + return [ a, b, c ]; + }(void 0, null)); + } + expect: { + console.log(...function() { + return [ "foo", null, "baz" ]; }()); } + expect_stdout: "foo null baz" + node_version: ">=6" +} + +reduce_array: { + options = { + evaluate: true, + reduce_vars: true, + toplevel: true, + unsafe: true, + unused: true, + } + input: { + var [ a = "foo", b = "bar", c = "baz" ] = [ void 0, null ]; + console.log(a, b, c); + } expect: { - console.log("PASS"); + var [ , , c = "baz" ] = [ void 0, null ]; + console.log("foo", null, c); } - expect_stdout: "PASS" + expect_stdout: "foo null baz" + node_version: ">=6" +} + +reduce_object: { + options = { + evaluate: true, + reduce_vars: true, + toplevel: true, + unsafe: true, + unused: true, + } + input: { + var { a = "foo", b = "bar", c = "baz" } = { a: void 0, b: null }; + console.log(a, b, c); + } + expect: { + var { c = "baz" } = { a: void 0, b: null }; + console.log("foo", null, c); + } + expect_stdout: "foo null baz" node_version: ">=6" } diff --git a/test/compress/hoist_vars.js b/test/compress/hoist_vars.js index 97987fd9..39a27275 100644 --- a/test/compress/hoist_vars.js +++ b/test/compress/hoist_vars.js @@ -323,9 +323,7 @@ issue_4893_1: { expect: { try{ (function f() { - var b; - b = null; - b.p += 42; + null.p += 42; f; })(); } catch (e) { diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js index 66c70d5a..ebb6229a 100644 --- a/test/compress/reduce_vars.js +++ b/test/compress/reduce_vars.js @@ -1292,6 +1292,7 @@ toplevel_on_loops_3: { loops: true, reduce_funcs: true, reduce_vars: true, + side_effects: true, toplevel: true, unused: true, } |