enhance booleans (#3657)
This commit is contained in:
@@ -241,7 +241,7 @@ merge(Compressor.prototype, {
|
|||||||
return this.TYPE == node.TYPE && this.print_to_string() == node.print_to_string();
|
return this.TYPE == node.TYPE && this.print_to_string() == node.print_to_string();
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("process_expression", function(insert, compressor) {
|
AST_Scope.DEFMETHOD("process_expression", function(insert, transform) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var tt = new TreeTransformer(function(node) {
|
var tt = new TreeTransformer(function(node) {
|
||||||
if (insert && node instanceof AST_SimpleStatement) {
|
if (insert && node instanceof AST_SimpleStatement) {
|
||||||
@@ -250,13 +250,7 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (!insert && node instanceof AST_Return) {
|
if (!insert && node instanceof AST_Return) {
|
||||||
if (compressor) {
|
return transform ? transform(node) : make_node(AST_SimpleStatement, node, {
|
||||||
var value = node.value && node.value.drop_side_effect_free(compressor, true);
|
|
||||||
return value ? make_node(AST_SimpleStatement, node, {
|
|
||||||
body: value
|
|
||||||
}) : make_node(AST_EmptyStatement, node);
|
|
||||||
}
|
|
||||||
return make_node(AST_SimpleStatement, node, {
|
|
||||||
body: node.value || make_node(AST_UnaryPrefix, node, {
|
body: node.value || make_node(AST_UnaryPrefix, node, {
|
||||||
operator: "void",
|
operator: "void",
|
||||||
expression: make_node(AST_Number, node, {
|
expression: make_node(AST_Number, node, {
|
||||||
@@ -361,6 +355,7 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
function reset_def(tw, compressor, def) {
|
function reset_def(tw, compressor, def) {
|
||||||
def.assignments = 0;
|
def.assignments = 0;
|
||||||
|
def.bool_fn = 0;
|
||||||
def.chained = false;
|
def.chained = false;
|
||||||
def.cross_loop = false;
|
def.cross_loop = false;
|
||||||
def.direct_access = false;
|
def.direct_access = false;
|
||||||
@@ -598,6 +593,7 @@ merge(Compressor.prototype, {
|
|||||||
var exp = this.expression;
|
var exp = this.expression;
|
||||||
if (!(exp instanceof AST_SymbolRef)) return;
|
if (!(exp instanceof AST_SymbolRef)) return;
|
||||||
var def = exp.definition();
|
var def = exp.definition();
|
||||||
|
if (tw.in_boolean_context()) def.bool_fn++;
|
||||||
if (!(def.fixed instanceof AST_Defun)) return;
|
if (!(def.fixed instanceof AST_Defun)) return;
|
||||||
var defun = mark_defun(tw, def);
|
var defun = mark_defun(tw, def);
|
||||||
if (!defun) return;
|
if (!defun) return;
|
||||||
@@ -4560,7 +4556,12 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
if (exp instanceof AST_Function && (!exp.name || !exp.name.definition().references.length)) {
|
if (exp instanceof AST_Function && (!exp.name || !exp.name.definition().references.length)) {
|
||||||
var node = this.clone();
|
var node = this.clone();
|
||||||
exp.process_expression(false, compressor);
|
exp.process_expression(false, function(node) {
|
||||||
|
var value = node.value && node.value.drop_side_effect_free(compressor, true);
|
||||||
|
return value ? make_node(AST_SimpleStatement, node, {
|
||||||
|
body: value
|
||||||
|
}) : make_node(AST_EmptyStatement, node);
|
||||||
|
});
|
||||||
exp.walk(new TreeWalker(function(node) {
|
exp.walk(new TreeWalker(function(node) {
|
||||||
if (node instanceof AST_Return && node.value) {
|
if (node instanceof AST_Return && node.value) {
|
||||||
node.value = node.value.drop_side_effect_free(compressor);
|
node.value = node.value.drop_side_effect_free(compressor);
|
||||||
@@ -6685,6 +6686,32 @@ merge(Compressor.prototype, {
|
|||||||
if (compressor.option("reduce_vars") && is_lhs(compressor.self(), parent) !== compressor.self()) {
|
if (compressor.option("reduce_vars") && is_lhs(compressor.self(), parent) !== compressor.self()) {
|
||||||
var def = self.definition();
|
var def = self.definition();
|
||||||
var fixed = self.fixed_value();
|
var fixed = self.fixed_value();
|
||||||
|
if (compressor.option("booleans") && def.bool_fn === def.references.length && fixed instanceof AST_Lambda) {
|
||||||
|
def.bool_fn = null;
|
||||||
|
fixed.process_expression(false, function(node) {
|
||||||
|
if (!node.value) return node;
|
||||||
|
var value = node.value.is_truthy() || node.value.tail_node().evaluate(compressor);
|
||||||
|
if (!value) {
|
||||||
|
value = node.value.drop_side_effect_free(compressor);
|
||||||
|
node.value = value ? make_sequence(node.value, [
|
||||||
|
value,
|
||||||
|
make_node(AST_Number, node.value, {
|
||||||
|
value: 0
|
||||||
|
})
|
||||||
|
]) : null;
|
||||||
|
} else if (value && !(value instanceof AST_Node)) {
|
||||||
|
var num = make_node(AST_Number, node.value, {
|
||||||
|
value: 1
|
||||||
|
});
|
||||||
|
value = node.value.drop_side_effect_free(compressor);
|
||||||
|
node.value = value ? make_sequence(node.value, [
|
||||||
|
value,
|
||||||
|
num
|
||||||
|
]) : num;
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
});
|
||||||
|
}
|
||||||
var single_use = def.single_use && !(parent instanceof AST_Call && parent.is_expr_pure(compressor));
|
var single_use = def.single_use && !(parent instanceof AST_Call && parent.is_expr_pure(compressor));
|
||||||
if (single_use && fixed instanceof AST_Lambda) {
|
if (single_use && fixed instanceof AST_Lambda) {
|
||||||
if (def.scope !== self.scope
|
if (def.scope !== self.scope
|
||||||
|
|||||||
@@ -86,3 +86,27 @@ issue_3465_3: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2737_2: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(bar) {
|
||||||
|
for (;bar();) break;
|
||||||
|
})(function qux() {
|
||||||
|
return console.log("PASS"), qux;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(bar) {
|
||||||
|
for (;bar();) break;
|
||||||
|
})(function() {
|
||||||
|
return console.log("PASS"), 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1911,14 +1911,14 @@ issue_2737_2: {
|
|||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
(function(bar) {
|
(function(bar) {
|
||||||
for (;bar(); ) break;
|
for (;bar();) break;
|
||||||
})(function qux() {
|
})(function qux() {
|
||||||
return console.log("PASS"), qux;
|
return console.log("PASS"), qux;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
(function(bar) {
|
(function(bar) {
|
||||||
for (;bar(); ) break;
|
for (;bar();) break;
|
||||||
})(function qux() {
|
})(function qux() {
|
||||||
return console.log("PASS"), qux;
|
return console.log("PASS"), qux;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ while_becomes_for: {
|
|||||||
while (foo()) bar();
|
while (foo()) bar();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
for (; foo(); ) bar();
|
for (;foo();) bar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ drop_if_break_1: {
|
|||||||
if (foo()) break;
|
if (foo()) break;
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
for (; !foo(););
|
for (;!foo(););
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ drop_if_break_2: {
|
|||||||
if (foo()) break;
|
if (foo()) break;
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
for (; bar() && !foo(););
|
for (;bar() && !foo(););
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ drop_if_break_4: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
for (; bar() && (x(), y(), !foo());) z(), k();
|
for (;bar() && (x(), y(), !foo());) z(), k();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ drop_if_else_break_1: {
|
|||||||
for (;;) if (foo()) bar(); else break;
|
for (;;) if (foo()) bar(); else break;
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
for (; foo(); ) bar();
|
for (;foo();) bar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ drop_if_else_break_2: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
for (; bar() && foo();) baz();
|
for (;bar() && foo();) baz();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ drop_if_else_break_3: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
for (; bar() && foo();) {
|
for (;bar() && foo();) {
|
||||||
baz();
|
baz();
|
||||||
stuff1();
|
stuff1();
|
||||||
stuff2();
|
stuff2();
|
||||||
@@ -138,7 +138,7 @@ drop_if_else_break_4: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
for (; bar() && (x(), y(), foo());) baz(), z(), k();
|
for (;bar() && (x(), y(), foo());) baz(), z(), k();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -523,13 +523,13 @@ issue_2740_1: {
|
|||||||
loops: true,
|
loops: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
for (; ; ) break;
|
for (;;) break;
|
||||||
for (a(); ; ) break;
|
for (a();;) break;
|
||||||
for (; b(); ) break;
|
for (;b();) break;
|
||||||
for (c(); d(); ) break;
|
for (c(); d();) break;
|
||||||
for (; ; e()) break;
|
for (;;e()) break;
|
||||||
for (f(); ; g()) break;
|
for (f();; g()) break;
|
||||||
for (; h(); i()) break;
|
for (;h(); i()) break;
|
||||||
for (j(); k(); l()) break;
|
for (j(); k(); l()) break;
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
@@ -670,7 +670,7 @@ issue_3371: {
|
|||||||
function a() {
|
function a() {
|
||||||
console.log("PASS");
|
console.log("PASS");
|
||||||
}
|
}
|
||||||
for (; a(); );
|
for (;a(););
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
|
|||||||
Reference in New Issue
Block a user