aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2019-12-30 22:41:11 +0800
committerGitHub <noreply@github.com>2019-12-30 22:41:11 +0800
commit4dbdac9c312320770f8a24a3eda6e09aa429e3c0 (patch)
treee6d40192da3c35d88ca9d05a322495532b270702
parent78c8efd851411a3605f667e78efaa342a1c65b53 (diff)
downloadtracifyjs-4dbdac9c312320770f8a24a3eda6e09aa429e3c0.tar.gz
tracifyjs-4dbdac9c312320770f8a24a3eda6e09aa429e3c0.zip
enhance `booleans` (#3657)
-rw-r--r--lib/compress.js45
-rw-r--r--test/compress/booleans.js24
-rw-r--r--test/compress/functions.js4
-rw-r--r--test/compress/loops.js32
4 files changed, 78 insertions, 27 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 9c60d0ae..4252c58e 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -241,7 +241,7 @@ merge(Compressor.prototype, {
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 tt = new TreeTransformer(function(node) {
if (insert && node instanceof AST_SimpleStatement) {
@@ -250,13 +250,7 @@ merge(Compressor.prototype, {
});
}
if (!insert && node instanceof AST_Return) {
- if (compressor) {
- 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, {
+ return transform ? transform(node) : make_node(AST_SimpleStatement, node, {
body: node.value || make_node(AST_UnaryPrefix, node, {
operator: "void",
expression: make_node(AST_Number, node, {
@@ -361,6 +355,7 @@ merge(Compressor.prototype, {
function reset_def(tw, compressor, def) {
def.assignments = 0;
+ def.bool_fn = 0;
def.chained = false;
def.cross_loop = false;
def.direct_access = false;
@@ -598,6 +593,7 @@ merge(Compressor.prototype, {
var exp = this.expression;
if (!(exp instanceof AST_SymbolRef)) return;
var def = exp.definition();
+ if (tw.in_boolean_context()) def.bool_fn++;
if (!(def.fixed instanceof AST_Defun)) return;
var defun = mark_defun(tw, def);
if (!defun) return;
@@ -4560,7 +4556,12 @@ merge(Compressor.prototype, {
}
if (exp instanceof AST_Function && (!exp.name || !exp.name.definition().references.length)) {
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) {
if (node instanceof AST_Return && node.value) {
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()) {
var def = self.definition();
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));
if (single_use && fixed instanceof AST_Lambda) {
if (def.scope !== self.scope
diff --git a/test/compress/booleans.js b/test/compress/booleans.js
index 9b8c1664..a036a1d0 100644
--- a/test/compress/booleans.js
+++ b/test/compress/booleans.js
@@ -86,3 +86,27 @@ issue_3465_3: {
}
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"
+}
diff --git a/test/compress/functions.js b/test/compress/functions.js
index 4fea42dc..30569847 100644
--- a/test/compress/functions.js
+++ b/test/compress/functions.js
@@ -1911,14 +1911,14 @@ issue_2737_2: {
}
input: {
(function(bar) {
- for (;bar(); ) break;
+ for (;bar();) break;
})(function qux() {
return console.log("PASS"), qux;
});
}
expect: {
(function(bar) {
- for (;bar(); ) break;
+ for (;bar();) break;
})(function qux() {
return console.log("PASS"), qux;
});
diff --git a/test/compress/loops.js b/test/compress/loops.js
index db0fbb9a..44874479 100644
--- a/test/compress/loops.js
+++ b/test/compress/loops.js
@@ -6,7 +6,7 @@ while_becomes_for: {
while (foo()) bar();
}
expect: {
- for (; foo(); ) bar();
+ for (;foo();) bar();
}
}
@@ -19,7 +19,7 @@ drop_if_break_1: {
if (foo()) break;
}
expect: {
- for (; !foo(););
+ for (;!foo(););
}
}
@@ -32,7 +32,7 @@ drop_if_break_2: {
if (foo()) break;
}
expect: {
- for (; bar() && !foo(););
+ for (;bar() && !foo(););
}
}
@@ -70,7 +70,7 @@ drop_if_break_4: {
}
}
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;
}
expect: {
- for (; foo(); ) bar();
+ for (;foo();) bar();
}
}
@@ -97,7 +97,7 @@ drop_if_else_break_2: {
}
}
expect: {
- for (; bar() && foo();) baz();
+ for (;bar() && foo();) baz();
}
}
@@ -114,7 +114,7 @@ drop_if_else_break_3: {
}
}
expect: {
- for (; bar() && foo();) {
+ for (;bar() && foo();) {
baz();
stuff1();
stuff2();
@@ -138,7 +138,7 @@ drop_if_else_break_4: {
}
}
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,
}
input: {
- for (; ; ) break;
- for (a(); ; ) break;
- for (; b(); ) break;
- for (c(); d(); ) break;
- for (; ; e()) break;
- for (f(); ; g()) break;
- for (; h(); i()) break;
+ for (;;) break;
+ for (a();;) break;
+ for (;b();) break;
+ for (c(); d();) break;
+ for (;;e()) break;
+ for (f();; g()) break;
+ for (;h(); i()) break;
for (j(); k(); l()) break;
}
expect: {
@@ -670,7 +670,7 @@ issue_3371: {
function a() {
console.log("PASS");
}
- for (; a(); );
+ for (;a(););
})();
}
expect_stdout: "PASS"