aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2021-03-27 19:44:45 +0000
committerGitHub <noreply@github.com>2021-03-28 03:44:45 +0800
commitdaa8319b8a66641e2d78dc0e68446a2e774495e4 (patch)
tree503eb38047c253ffb89cb1b577645c3d111f760f
parentd5599604e80ab8771af422ca2f43302949b2eb15 (diff)
downloadtracifyjs-daa8319b8a66641e2d78dc0e68446a2e774495e4.tar.gz
tracifyjs-daa8319b8a66641e2d78dc0e68446a2e774495e4.zip
fix corner cases with logical assignment operators (#4828)
fixes #4827
-rw-r--r--lib/compress.js48
-rw-r--r--test/compress/assignments.js69
2 files changed, 105 insertions, 12 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 6286741f..24446b25 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -2391,21 +2391,36 @@ merge(Compressor.prototype, {
return null;
}
+ function find_stop_logical(parent, op, level) {
+ var node;
+ do {
+ node = parent;
+ parent = scanner.parent(++level);
+ } while (parent instanceof AST_Assign && parent.operator.slice(0, -1) == op
+ || parent instanceof AST_Binary && parent.operator == op);
+ return node;
+ }
+
function find_stop_value(node, level) {
var parent = scanner.parent(level);
if (parent instanceof AST_Array) return find_stop_value(parent, level + 1);
- if (parent instanceof AST_Assign) return may_throw(parent) || parent.left.match_symbol(function(ref) {
- return ref instanceof AST_SymbolRef && (lhs.name == ref.name || value_def.name == ref.name);
- }) ? node : find_stop_value(parent, level + 1);
+ if (parent instanceof AST_Assign) {
+ if (may_throw(parent)) return node;
+ if (parent.left.match_symbol(function(ref) {
+ return ref instanceof AST_SymbolRef && (lhs.name == ref.name || value_def.name == ref.name);
+ })) return node;
+ var op;
+ if (parent.left === node || !lazy_op[op = parent.operator.slice(0, -1)]) {
+ return find_stop_value(parent, level + 1);
+ }
+ return find_stop_logical(parent, op, level);
+ }
if (parent instanceof AST_Binary) {
- if (lazy_op[parent.operator] && parent.left !== node) {
- do {
- node = parent;
- parent = scanner.parent(++level);
- } while (parent instanceof AST_Binary && parent.operator == node.operator);
- return node;
+ var op;
+ if (parent.left === node || !lazy_op[op = parent.operator]) {
+ return find_stop_value(parent, level + 1);
}
- return find_stop_value(parent, level + 1);
+ return find_stop_logical(parent, op, level);
}
if (parent instanceof AST_Call) return parent;
if (parent instanceof AST_Case) {
@@ -5325,8 +5340,9 @@ merge(Compressor.prototype, {
var tw = new TreeWalker(function(node, descend) {
if (node instanceof AST_Assign) {
var lhs = node.left;
+ var rhs = node.right;
if (lhs instanceof AST_Destructured) {
- node.right.walk(tw);
+ rhs.walk(tw);
var marker = new TreeWalker(function(node) {
if (node instanceof AST_Destructured) return;
if (node instanceof AST_DefaultValue) {
@@ -5354,9 +5370,17 @@ merge(Compressor.prototype, {
lhs.walk(marker);
return true;
}
+ if (lazy_op[node.operator.slice(0, -1)]) {
+ lhs.walk(tw);
+ push();
+ rhs.walk(tw);
+ if (lhs instanceof AST_SymbolRef) mark(lhs);
+ pop();
+ return true;
+ }
if (lhs instanceof AST_SymbolRef) {
if (node.operator != "=") mark(lhs, true);
- node.right.walk(tw);
+ rhs.walk(tw);
mark(lhs);
return true;
}
diff --git a/test/compress/assignments.js b/test/compress/assignments.js
index 80538bd8..3973e2f5 100644
--- a/test/compress/assignments.js
+++ b/test/compress/assignments.js
@@ -603,3 +603,72 @@ issue_4819: {
expect_stdout: "true"
node_version: ">=15"
}
+
+issue_4827_1: {
+ options = {
+ collapse_vars: true,
+ toplevel: true,
+ }
+ input: {
+ A = "FAIL";
+ var a = A, b = "PASS", c;
+ c &&= b = a, console.log(b);
+ }
+ expect: {
+ A = "FAIL";
+ var a = A, b = "PASS", c;
+ c &&= b = a, console.log(b);
+ }
+ expect_stdout: "PASS"
+ node_version: ">=15"
+}
+
+issue_4827_2: {
+ options = {
+ collapse_vars: true,
+ inline: true,
+ reduce_vars: true,
+ side_effects: true,
+ toplevel: true,
+ unused: true,
+ }
+ input: {
+ var a = 0, b = "PASS";
+ function f(c) {
+ a++,
+ c &&= b = a;
+ }
+ f();
+ console.log(b);
+ }
+ expect: {
+ var a = 0, b = "PASS";
+ a++,
+ c &&= b = a;
+ var c;
+ console.log(b);
+ }
+ expect_stdout: "PASS"
+ node_version: ">=15"
+}
+
+issue_4827_3: {
+ options = {
+ merge_vars: true,
+ toplevel: true,
+ }
+ input: {
+ var a = 0, b, c;
+ a++;
+ c &&= b = a;
+ console.log(b);
+ }
+ expect: {
+ var a = 0, b, c;
+ a++;
+ c &&= b = a;
+ console.log(b);
+ }
+ expect_stdout: "undefined"
+ node_version: ">=15"
+}