@@ -530,11 +530,16 @@ merge(Compressor.prototype, {
|
|||||||
tw.safe_ids = save_ids;
|
tw.safe_ids = save_ids;
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
def(AST_DWLoop, function(tw, descend) {
|
def(AST_Do, function(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);
|
||||||
descend();
|
this.body.walk(tw);
|
||||||
|
if (has_break_or_continue(this)) {
|
||||||
|
pop(tw);
|
||||||
|
push(tw);
|
||||||
|
}
|
||||||
|
this.condition.walk(tw);
|
||||||
pop(tw);
|
pop(tw);
|
||||||
tw.in_loop = saved_loop;
|
tw.in_loop = saved_loop;
|
||||||
return true;
|
return true;
|
||||||
@@ -543,19 +548,17 @@ merge(Compressor.prototype, {
|
|||||||
if (this.init) this.init.walk(tw);
|
if (this.init) this.init.walk(tw);
|
||||||
var saved_loop = tw.in_loop;
|
var saved_loop = tw.in_loop;
|
||||||
tw.in_loop = this;
|
tw.in_loop = this;
|
||||||
if (this.condition) {
|
|
||||||
push(tw);
|
|
||||||
this.condition.walk(tw);
|
|
||||||
pop(tw);
|
|
||||||
}
|
|
||||||
push(tw);
|
push(tw);
|
||||||
|
if (this.condition) this.condition.walk(tw);
|
||||||
this.body.walk(tw);
|
this.body.walk(tw);
|
||||||
pop(tw);
|
|
||||||
if (this.step) {
|
if (this.step) {
|
||||||
push(tw);
|
if (has_break_or_continue(this)) {
|
||||||
|
pop(tw);
|
||||||
|
push(tw);
|
||||||
|
}
|
||||||
this.step.walk(tw);
|
this.step.walk(tw);
|
||||||
pop(tw);
|
|
||||||
}
|
}
|
||||||
|
pop(tw);
|
||||||
tw.in_loop = saved_loop;
|
tw.in_loop = saved_loop;
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
@@ -713,6 +716,15 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
def(AST_While, function(tw, descend) {
|
||||||
|
var saved_loop = tw.in_loop;
|
||||||
|
tw.in_loop = this;
|
||||||
|
push(tw);
|
||||||
|
descend();
|
||||||
|
pop(tw);
|
||||||
|
tw.in_loop = saved_loop;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
})(function(node, func){
|
})(function(node, func){
|
||||||
node.DEFMETHOD("reduce_vars", func);
|
node.DEFMETHOD("reduce_vars", func);
|
||||||
});
|
});
|
||||||
@@ -3837,6 +3849,20 @@ merge(Compressor.prototype, {
|
|||||||
return compressor.option("loops") ? make_node(AST_For, self, self).optimize(compressor) : self;
|
return compressor.option("loops") ? make_node(AST_For, self, self).optimize(compressor) : self;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function has_break_or_continue(loop, parent) {
|
||||||
|
var found = false;
|
||||||
|
var tw = new TreeWalker(function(node) {
|
||||||
|
if (found || node instanceof AST_Scope) return true;
|
||||||
|
if (node instanceof AST_LoopControl && tw.loopcontrol_target(node) === loop) {
|
||||||
|
return found = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (parent instanceof AST_LabeledStatement) tw.push(parent);
|
||||||
|
tw.push(loop);
|
||||||
|
loop.body.walk(tw);
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
OPT(AST_Do, function(self, compressor){
|
OPT(AST_Do, function(self, compressor){
|
||||||
if (!compressor.option("loops")) return self;
|
if (!compressor.option("loops")) return self;
|
||||||
var cond = self.condition.is_truthy() || self.condition.tail_node().evaluate(compressor);
|
var cond = self.condition.is_truthy() || self.condition.tail_node().evaluate(compressor);
|
||||||
@@ -3851,22 +3877,16 @@ merge(Compressor.prototype, {
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
}).optimize(compressor);
|
}).optimize(compressor);
|
||||||
var has_loop_control = false;
|
if (!has_break_or_continue(self, compressor.parent())) {
|
||||||
var tw = new TreeWalker(function(node) {
|
return make_node(AST_BlockStatement, self.body, {
|
||||||
if (node instanceof AST_Scope || has_loop_control) return true;
|
body: [
|
||||||
if (node instanceof AST_LoopControl && tw.loopcontrol_target(node) === self)
|
self.body,
|
||||||
return has_loop_control = true;
|
make_node(AST_SimpleStatement, self.condition, {
|
||||||
});
|
body: self.condition
|
||||||
var parent = compressor.parent();
|
})
|
||||||
(parent instanceof AST_LabeledStatement ? parent : self).walk(tw);
|
]
|
||||||
if (!has_loop_control) return make_node(AST_BlockStatement, self.body, {
|
}).optimize(compressor);
|
||||||
body: [
|
}
|
||||||
self.body,
|
|
||||||
make_node(AST_SimpleStatement, self.condition, {
|
|
||||||
body: self.condition
|
|
||||||
})
|
|
||||||
]
|
|
||||||
}).optimize(compressor);
|
|
||||||
}
|
}
|
||||||
if (self.body instanceof AST_SimpleStatement) return make_node(AST_For, self, {
|
if (self.body instanceof AST_SimpleStatement) return make_node(AST_For, self, {
|
||||||
condition: make_sequence(self.condition, [
|
condition: make_sequence(self.condition, [
|
||||||
|
|||||||
@@ -5654,3 +5654,59 @@ issue_3042_2: {
|
|||||||
"true",
|
"true",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3068_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
do {
|
||||||
|
continue;
|
||||||
|
var b = "defined";
|
||||||
|
} while (b && b.c);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
do {
|
||||||
|
continue;
|
||||||
|
var b = "defined";
|
||||||
|
} while (b && b.c);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3068_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
do {
|
||||||
|
try {
|
||||||
|
while ("" == typeof a);
|
||||||
|
} finally {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var b = "defined";
|
||||||
|
} while (b && b.c);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
do {
|
||||||
|
try {
|
||||||
|
while ("" == typeof a);
|
||||||
|
} finally {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var b = "defined";
|
||||||
|
} while (b && b.c);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user