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;
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);
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;
}
}
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);
}
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);
}
expect_stdout: "PASS"
}
-forin: {
+forin_1: {
options = {
sequences: true,
}
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,