diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2020-08-25 18:26:49 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-26 01:26:49 +0800 |
commit | 09525c7530fb305c7b60c470ee9bab3510beb8f0 (patch) | |
tree | b4f81bd4468597d1942fa028f45d932001fab448 | |
parent | a7e15fe73cb8d78e7590f2d11bf18bbfe41061ea (diff) | |
download | tracifyjs-09525c7530fb305c7b60c470ee9bab3510beb8f0.tar.gz tracifyjs-09525c7530fb305c7b60c470ee9bab3510beb8f0.zip |
fix corner case in `sequences` (#4073)
-rw-r--r-- | lib/ast.js | 5 | ||||
-rw-r--r-- | lib/compress.js | 28 | ||||
-rw-r--r-- | test/compress/sequences.js | 45 |
3 files changed, 65 insertions, 13 deletions
@@ -288,10 +288,13 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", { var label = node.label; var def = this.label; node.walk(new TreeWalker(function(node) { - if (node instanceof AST_LoopControl && node.label && node.label.thedef === def) { + if (node instanceof AST_LoopControl) { + if (!node.label || node.label.thedef !== def) return; node.label.thedef = label; label.references.push(node); + return true; } + if (node instanceof AST_Scope) return true; })); } return node; diff --git a/lib/compress.js b/lib/compress.js index 3f0ea219..47445665 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -554,13 +554,6 @@ merge(Compressor.prototype, { if (is_arguments(def) && node.property instanceof AST_Number) def.reassigned = true; } - var suppressor = new TreeWalker(function(node) { - if (!(node instanceof AST_Symbol)) return; - var d = node.definition(); - if (!d) return; - if (node instanceof AST_SymbolRef) push_ref(d, node); - d.fixed = false; - }); def(AST_Accessor, function(tw, descend, compressor) { push(tw); reset_variables(tw, compressor, this); @@ -740,11 +733,19 @@ merge(Compressor.prototype, { return true; }); def(AST_ForIn, function(tw) { - this.init.walk(suppressor); this.object.walk(tw); var saved_loop = tw.in_loop; tw.in_loop = this; push(tw); + var init = this.init; + init.walk(tw); + if (init instanceof AST_Var) { + init = init.definitions[0].name; + } else while (init instanceof AST_PropAccess) { + init = init.expression.tail_node(); + } + var def = init.definition(); + if (def) def.fixed = false; this.body.walk(tw); pop(tw); tw.in_loop = saved_loop; @@ -8521,7 +8522,9 @@ merge(Compressor.prototype, { } } if (is_lhs(compressor.self(), parent)) return self; - if (compressor.option("sequences") && compressor.parent().TYPE != "Call") { + if (compressor.option("sequences") + && parent.TYPE != "Call" + && !(parent instanceof AST_ForIn && parent.init === self)) { var seq = lift_sequence_in_expression(self, compressor); if (seq !== self) return seq.optimize(compressor); } @@ -8632,8 +8635,11 @@ merge(Compressor.prototype, { col: self.start.col }); } - if (is_lhs(compressor.self(), compressor.parent())) return self; - if (compressor.option("sequences") && compressor.parent().TYPE != "Call") { + var parent = compressor.parent(); + if (is_lhs(compressor.self(), parent)) return self; + if (compressor.option("sequences") + && parent.TYPE != "Call" + && !(parent instanceof AST_ForIn && parent.init === self)) { var seq = lift_sequence_in_expression(self, compressor); if (seq !== self) return seq.optimize(compressor); } diff --git a/test/compress/sequences.js b/test/compress/sequences.js index c0b77127..32db63d3 100644 --- a/test/compress/sequences.js +++ b/test/compress/sequences.js @@ -877,7 +877,7 @@ for_init_var: { expect_stdout: "PASS" } -forin: { +forin_1: { options = { sequences: true, } @@ -895,6 +895,49 @@ forin: { expect_stdout: "PASS" } +forin_2: { + options = { + evaluate: true, + inline: true, + reduce_vars: true, + sequences: true, + toplevel: true, + unused: true, + } + input: { + var o = { + p: 1, + q: 2, + }; + var k = "k"; + for ((console.log("exp"), o)[function() { + console.log("prop"); + return k; + }()] in function() { + console.log("obj"); + return o; + }()) + console.log(o.k, o[o.k]); + } + expect: { + var o = { + p: 1, + q: 2, + }; + for ((console.log("exp"), o)[console.log("prop"), "k"] in console.log("obj"), o) + console.log(o.k, o[o.k]); + } + expect_stdout: [ + "obj", + "exp", + "prop", + "p 1", + "exp", + "prop", + "q 2", + ] +} + call: { options = { sequences: true, |