aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2021-02-02 17:39:30 +0000
committerGitHub <noreply@github.com>2021-02-02 17:39:30 +0000
commita2f27c7640fee2c981b49ee484a37e1721622bb3 (patch)
tree67ce8a676c7590f7857b3475cbaee59cd5ca28eb
parent3c556b8689346f8256781455c0e1b2f00975570f (diff)
downloadtracifyjs-a2f27c7640fee2c981b49ee484a37e1721622bb3.tar.gz
tracifyjs-a2f27c7640fee2c981b49ee484a37e1721622bb3.zip
fix corner cases in `templates` (#4610)
-rw-r--r--README.md3
-rw-r--r--lib/compress.js16
-rw-r--r--test/compress/templates.js48
3 files changed, 63 insertions, 4 deletions
diff --git a/README.md b/README.md
index 9a0be306..9f69ce00 100644
--- a/README.md
+++ b/README.md
@@ -769,6 +769,9 @@ to be `false` and all symbol names will be omitted.
- `switches` (default: `true`) -- de-duplicate and remove unreachable `switch` branches
+- `templates` (default: `true`) -- compact template literals by embedding expressions
+ and/or converting to string literals, e.g. `` `foo ${42}` → "foo 42"``
+
- `top_retain` (default: `null`) -- prevent specific toplevel functions and
variables from `unused` removal (can be array, comma-separated, RegExp or
function. Implies `toplevel`)
diff --git a/lib/compress.js b/lib/compress.js
index 7293f9df..dbd3dd35 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -4416,8 +4416,8 @@ merge(Compressor.prototype, {
}
var exprs = eval_all(this.expressions, compressor, ignore_side_effects, cached, depth);
if (!exprs) return this;
- var ret = decode(this.strings[0]);
var malformed = false;
+ var ret = decode(this.strings[0]);
for (var i = 0; i < exprs.length; i++) {
ret += exprs[i] + decode(this.strings[i + 1]);
}
@@ -4426,7 +4426,7 @@ merge(Compressor.prototype, {
return this;
function decode(str) {
- return str.replace(/\\(u[0-9a-fA-F]{4}|u\{[0-9a-fA-F]+\}|x[0-9a-fA-F]{2}|[0-9]+|[\s\S])/g, function(match, seq) {
+ return str.replace(/\\(u\{[^}]*\}?|u[\s\S]{0,4}|x[\s\S]{0,2}|[0-9]+|[\s\S])/g, function(match, seq) {
var s = decode_escape_sequence(seq);
if (typeof s != "string") malformed = true;
return s;
@@ -9952,8 +9952,18 @@ merge(Compressor.prototype, {
return "\\" + (s == "\r" ? "r" : s);
});
if (ev.length > node.print_to_string().length + 3) continue;
+ var combined = strs[i] + ev + strs[i + 1];
+ if (typeof make_node(AST_Template, self, {
+ expressions: [],
+ strings: [ combined ],
+ tag: self.tag,
+ }).evaluate(compressor) != typeof make_node(AST_Template, self, {
+ expressions: [ node ],
+ strings: strs.slice(i, i + 2),
+ tag: self.tag,
+ }).evaluate(compressor)) continue;
exprs.splice(i, 1);
- strs.splice(i, 2, strs[i] + ev + strs[i + 1]);
+ strs.splice(i, 2, combined);
}
}
return try_evaluate(compressor, self);
diff --git a/test/compress/templates.js b/test/compress/templates.js
index 3c7957f8..0be46df0 100644
--- a/test/compress/templates.js
+++ b/test/compress/templates.js
@@ -134,7 +134,7 @@ partial_evaluate: {
node_version: ">=4"
}
-malformed_evaluate: {
+malformed_evaluate_1: {
options = {
evaluate: true,
templates: true,
@@ -149,6 +149,52 @@ malformed_evaluate: {
node_version: ">=4"
}
+malformed_evaluate_2: {
+ options = {
+ evaluate: true,
+ templates: true,
+ }
+ input: {
+ console.log(`\u0${0}b${5}`);
+ }
+ expect: {
+ console.log(`\u0${0}b5`);
+ }
+ expect_stdout: true
+ node_version: ">=4"
+}
+
+malformed_evaluate_3: {
+ options = {
+ evaluate: true,
+ templates: true,
+ }
+ input: {
+ console.log(`\u${0}b${5}`);
+ }
+ expect: {
+ console.log(`\u0b5`);
+ }
+ expect_stdout: true
+ node_version: ">=4"
+}
+
+malformed_evaluate_4: {
+ options = {
+ evaluate: true,
+ templates: true,
+ unsafe: true,
+ }
+ input: {
+ console.log(String.raw`\u0${0}b${5}`);
+ }
+ expect: {
+ console.log("\\u00b5");
+ }
+ expect_stdout: "\\u00b5"
+ node_version: ">=8"
+}
+
unsafe_evaluate: {
options = {
evaluate: true,