aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2021-02-10 20:59:25 +0000
committerGitHub <noreply@github.com>2021-02-11 04:59:25 +0800
commit952765be66e45a10f59ef900a1bd4d90e38e9cf5 (patch)
tree7c2ed7a7b9fdc47fde756cf703d5b18f2fbb0ed6
parent083679bcad5711a90e49272e8a695a0c7b189a47 (diff)
downloadtracifyjs-952765be66e45a10f59ef900a1bd4d90e38e9cf5.tar.gz
tracifyjs-952765be66e45a10f59ef900a1bd4d90e38e9cf5.zip
enhance `join_vars` (#4643)
-rw-r--r--lib/compress.js45
-rw-r--r--test/compress/join_vars.js72
2 files changed, 110 insertions, 7 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 3d857190..1eed09ba 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -3049,13 +3049,13 @@ merge(Compressor.prototype, {
statements.length = n;
}
+ function extract_exprs(body) {
+ if (body instanceof AST_Assign) return [ body ];
+ if (body instanceof AST_Sequence) return body.expressions.slice();
+ }
+
function join_assigns(defn, body, keep) {
- var exprs;
- if (body instanceof AST_Assign) {
- exprs = [ body ];
- } else if (body instanceof AST_Sequence) {
- exprs = body.expressions.slice();
- }
+ var exprs = extract_exprs(body);
if (!exprs) return;
var trimmed = false;
for (var i = exprs.length - 1; --i >= 0;) {
@@ -3082,6 +3082,17 @@ merge(Compressor.prototype, {
return trimmed && exprs;
}
+ function merge_assigns(prev, defn) {
+ if (!(prev instanceof AST_SimpleStatement)) return;
+ if (declarations_only(defn)) return;
+ var exprs = extract_exprs(prev.body);
+ if (!exprs) return;
+ var definitions = [];
+ if (!join_var_assign(definitions, exprs.reverse(), 0)) return;
+ defn.definitions = definitions.reverse().concat(defn.definitions);
+ return exprs.reverse();
+ }
+
function merge_conditional_assignments(var_def, exprs, keep) {
if (!compressor.option("conditionals")) return;
if (var_def.name instanceof AST_Destructured) return;
@@ -3173,9 +3184,20 @@ merge(Compressor.prototype, {
} else if (defs && defs.TYPE == stat.TYPE && declarations_only(stat)) {
defs.definitions = defs.definitions.concat(stat.definitions);
CHANGED = true;
+ } else if (stat instanceof AST_Var) {
+ var exprs = merge_assigns(prev, stat);
+ if (exprs) {
+ if (exprs.length) {
+ prev.body = make_sequence(prev, exprs);
+ j++;
+ }
+ CHANGED = true;
+ } else {
+ j++;
+ }
+ statements[j] = defs = stat;
} else {
statements[++j] = stat;
- if (stat instanceof AST_Var) defs = stat;
}
continue;
} else if (stat instanceof AST_Exit) {
@@ -3199,6 +3221,15 @@ merge(Compressor.prototype, {
CHANGED = true;
} else if (stat.init instanceof AST_Var) {
defs = stat.init;
+ exprs = merge_assigns(prev, stat.init);
+ if (exprs) {
+ CHANGED = true;
+ if (exprs.length == 0) {
+ statements[j] = merge_defns(stat);
+ continue;
+ }
+ prev.body = make_sequence(prev, exprs);
+ }
}
} else if (stat instanceof AST_ForEnumeration) {
if (defs && defs.TYPE == stat.init.TYPE) {
diff --git a/test/compress/join_vars.js b/test/compress/join_vars.js
index aec6a917..21b76aaa 100644
--- a/test/compress/join_vars.js
+++ b/test/compress/join_vars.js
@@ -1055,3 +1055,75 @@ issue_3916: {
}
expect_stdout: "object PASS true PASS"
}
+
+assign_var: {
+ options = {
+ join_vars: true,
+ }
+ input: {
+ b = "foo";
+ var a = [ , "bar" ];
+ console.log(b);
+ for (var b in a)
+ console.log(b, a[b]);
+ }
+ expect: {
+ var b = "foo", a = [ , "bar" ], b;
+ console.log(b);
+ for (b in a)
+ console.log(b, a[b]);
+ }
+ expect_stdout: [
+ "foo",
+ "1 bar",
+ ]
+}
+
+assign_for_var: {
+ options = {
+ join_vars: true,
+ }
+ input: {
+ i = "foo",
+ a = new Array(i, "bar");
+ for (var i = 2; --i >= 0;) {
+ console.log(a[i]);
+ for (var a in i);
+ }
+ }
+ expect: {
+ for (var i = "foo", a = new Array(i, "bar"), i = 2; --i >= 0;) {
+ console.log(a[i]);
+ for (var a in i);
+ }
+ }
+ expect_stdout: [
+ "bar",
+ "foo",
+ ]
+}
+
+assign_sequence_var: {
+ options = {
+ join_vars: true,
+ }
+ input: {
+ var a = 0, b = 1;
+ console.log(a),
+ a++,
+ b = 2;
+ var c = 3;
+ console.log(a, b, c);
+ }
+ expect: {
+ var a = 0, b = 1;
+ console.log(a),
+ a++;
+ var b = 2, c = 3;
+ console.log(a, b, c);
+ }
+ expect_stdout: [
+ "0",
+ "1 2 3",
+ ]
+}