fix corner case in sequences (#4073)

This commit is contained in:
Alex Lam S.L
2020-08-25 18:26:49 +01:00
committed by GitHub
parent a7e15fe73c
commit 09525c7530
3 changed files with 65 additions and 13 deletions

View File

@@ -288,10 +288,13 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
var label = node.label; var label = node.label;
var def = this.label; var def = this.label;
node.walk(new TreeWalker(function(node) { 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; node.label.thedef = label;
label.references.push(node); label.references.push(node);
return true;
} }
if (node instanceof AST_Scope) return true;
})); }));
} }
return node; return node;

View File

@@ -554,13 +554,6 @@ merge(Compressor.prototype, {
if (is_arguments(def) && node.property instanceof AST_Number) def.reassigned = true; 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) { def(AST_Accessor, function(tw, descend, compressor) {
push(tw); push(tw);
reset_variables(tw, compressor, this); reset_variables(tw, compressor, this);
@@ -740,11 +733,19 @@ merge(Compressor.prototype, {
return true; return true;
}); });
def(AST_ForIn, function(tw) { def(AST_ForIn, function(tw) {
this.init.walk(suppressor);
this.object.walk(tw); this.object.walk(tw);
var saved_loop = tw.in_loop; var saved_loop = tw.in_loop;
tw.in_loop = this; tw.in_loop = this;
push(tw); 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); this.body.walk(tw);
pop(tw); pop(tw);
tw.in_loop = saved_loop; tw.in_loop = saved_loop;
@@ -8521,7 +8522,9 @@ merge(Compressor.prototype, {
} }
} }
if (is_lhs(compressor.self(), parent)) return self; 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); var seq = lift_sequence_in_expression(self, compressor);
if (seq !== self) return seq.optimize(compressor); if (seq !== self) return seq.optimize(compressor);
} }
@@ -8632,8 +8635,11 @@ merge(Compressor.prototype, {
col: self.start.col col: self.start.col
}); });
} }
if (is_lhs(compressor.self(), compressor.parent())) return self; var parent = compressor.parent();
if (compressor.option("sequences") && compressor.parent().TYPE != "Call") { 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); var seq = lift_sequence_in_expression(self, compressor);
if (seq !== self) return seq.optimize(compressor); if (seq !== self) return seq.optimize(compressor);
} }

View File

@@ -877,7 +877,7 @@ for_init_var: {
expect_stdout: "PASS" expect_stdout: "PASS"
} }
forin: { forin_1: {
options = { options = {
sequences: true, sequences: true,
} }
@@ -895,6 +895,49 @@ forin: {
expect_stdout: "PASS" 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: { call: {
options = { options = {
sequences: true, sequences: true,