aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2019-12-02 15:25:38 +0800
committerGitHub <noreply@github.com>2019-12-02 15:25:38 +0800
commit500e31e03b69d3c6fa219a74f9131c2abc9c9730 (patch)
tree2523c58edce3d0abb8524bcb92b5218d1289825a
parentbef856addb7ac977b516a9bcd155c897a7d0dd99 (diff)
downloadtracifyjs-500e31e03b69d3c6fa219a74f9131c2abc9c9730.tar.gz
tracifyjs-500e31e03b69d3c6fa219a74f9131c2abc9c9730.zip
enhance `collapse_vars` (#3621)
-rw-r--r--lib/compress.js93
-rw-r--r--test/compress/collapse_vars.js17
2 files changed, 88 insertions, 22 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 2c60a9b6..e18fd575 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -1124,7 +1124,7 @@ merge(Compressor.prototype, {
hit_index++;
if (hit_index < hit_stack.length) return handle_custom_scan_order(node);
hit = true;
- stop_after = find_stop(node, 0);
+ stop_after = (value_def ? find_stop_value : find_stop)(node, 0);
if (stop_after === node) abort = true;
return node;
}
@@ -1540,46 +1540,95 @@ merge(Compressor.prototype, {
function find_stop(node, level) {
var parent = scanner.parent(level);
- if (parent instanceof AST_Array) return value_def ? find_stop(parent, level + 1) : node;
+ if (parent instanceof AST_Array) return node;
+ if (parent instanceof AST_Assign) return node;
+ if (parent instanceof AST_Binary) return node;
+ if (parent instanceof AST_Call) return node;
+ if (parent instanceof AST_Case) return node;
+ if (parent instanceof AST_Conditional) return node;
+ if (parent instanceof AST_Definitions) return find_stop_unused(parent, level + 1);
+ if (parent instanceof AST_Exit) return node;
+ if (parent instanceof AST_If) return node;
+ if (parent instanceof AST_IterationStatement) return node;
+ if (parent instanceof AST_ObjectKeyVal) return node;
+ if (parent instanceof AST_PropAccess) return node;
+ if (parent instanceof AST_Sequence) {
+ return (parent.tail_node() === node ? find_stop : find_stop_unused)(parent, level + 1);
+ }
+ if (parent instanceof AST_SimpleStatement) return find_stop_unused(parent, level + 1);
+ if (parent instanceof AST_Switch) return node;
+ if (parent instanceof AST_Unary) return node;
+ if (parent instanceof AST_VarDef) return node;
+ return null;
+ }
+
+ 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) {
- if (!value_def) return node;
- if (lhs.equivalent_to(parent.left)) return node;
- if (get_rvalue(candidate).equivalent_to(parent.left)) return node;
- return find_stop(parent, level + 1);
+ if (parent.left instanceof AST_SymbolRef) {
+ var name = parent.left.name;
+ if (lhs.name == name) return node;
+ if (value_def.name == name) return node;
+ }
+ return find_stop_value(parent, level + 1);
}
if (parent instanceof AST_Binary) {
- if (!value_def) return node;
if (lazy_op[parent.operator] && parent.left !== node) {
var grandparent = scanner.parent(level + 1);
if (!(grandparent instanceof AST_Binary)) return node;
if (grandparent.operator != parent.operator) return node;
}
- return find_stop(parent, level + 1);
+ return find_stop_value(parent, level + 1);
+ }
+ if (parent instanceof AST_Call) return parent;
+ if (parent instanceof AST_Case) {
+ if (parent.expression !== node) return node;
+ return find_stop_value(parent, level + 1);
}
- if (parent instanceof AST_Call) return value_def ? parent : node;
- if (parent instanceof AST_Case) return node;
if (parent instanceof AST_Conditional) {
- if (!value_def || parent.condition !== node) return node;
- return find_stop(parent, level + 1);
+ if (parent.condition !== node) return node;
+ return find_stop_value(parent, level + 1);
}
if (parent instanceof AST_Definitions) return find_stop_unused(parent, level + 1);
- if (parent instanceof AST_Exit) return node;
- if (parent instanceof AST_If) return node;
- if (parent instanceof AST_IterationStatement) return node;
- if (parent instanceof AST_ObjectKeyVal) {
- return value_def ? find_stop(scanner.parent(level + 1), level + 2) : node;
+ if (parent instanceof AST_Do) return node;
+ if (parent instanceof AST_Exit) return find_stop_unused(parent, level + 1);
+ if (parent instanceof AST_For) {
+ if (parent.init !== node && parent.condition !== node) return node;
+ return find_stop_value(parent, level + 1);
}
- if (parent instanceof AST_PropAccess) return node;
+ if (parent instanceof AST_ForIn) {
+ if (parent.init !== node) return node;
+ return find_stop_value(parent, level + 1);
+ }
+ if (parent instanceof AST_If) {
+ if (parent.condition !== node) return node;
+ return find_stop_value(parent, level + 1);
+ }
+ if (parent instanceof AST_ObjectKeyVal) return find_stop_value(scanner.parent(level + 1), level + 2);
+ if (parent instanceof AST_PropAccess) return find_stop_value(parent, level + 1);
if (parent instanceof AST_Sequence) {
- return (parent.tail_node() === node ? find_stop : find_stop_unused)(parent, level + 1);
+ return (parent.tail_node() === node ? find_stop_value : find_stop_unused)(parent, level + 1);
}
if (parent instanceof AST_SimpleStatement) return find_stop_unused(parent, level + 1);
- if (parent instanceof AST_Switch) return node;
+ if (parent instanceof AST_Switch) {
+ if (parent.expression !== node) return node;
+ return find_stop_value(parent, level + 1);
+ }
if (parent instanceof AST_Unary) {
if (parent.operator == "delete") return node;
- return value_def ? find_stop(parent, level + 1) : node;
+ return find_stop_value(parent, level + 1);
+ }
+ if (parent instanceof AST_VarDef) {
+ var name = parent.name.name;
+ if (lhs.name == name) return node;
+ if (value_def.name == name) return node;
+ return find_stop_value(parent, level + 1);
+ }
+ if (parent instanceof AST_While) {
+ if (parent.condition !== node) return node;
+ return find_stop_value(parent, level + 1);
}
- if (parent instanceof AST_VarDef) return node;
return null;
}
diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js
index 58325be1..cc6c5f9a 100644
--- a/test/compress/collapse_vars.js
+++ b/test/compress/collapse_vars.js
@@ -2578,6 +2578,23 @@ chained_3: {
expect_stdout: "2"
}
+chained_4: {
+ options = {
+ collapse_vars: true,
+ }
+ input: {
+ var a = "foo", b = 42;
+ var b = void (b = a);
+ console.log(a, b);
+ }
+ expect: {
+ var a = "foo", b = 42;
+ var b = void (b = a);
+ console.log(a, b);
+ }
+ expect_stdout: "foo undefined"
+}
+
boolean_binary_1: {
options = {
collapse_vars: true,