aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2021-05-27 23:32:43 +0100
committerGitHub <noreply@github.com>2021-05-28 06:32:43 +0800
commit749a828fc5995836596f1d554f31479d533232fe (patch)
treec84aabd9f2200eb92713132e37d3e8d4d63b8f2f
parentab42a90edb0316d7c5ed1a74b4a7f9167789ce4d (diff)
downloadtracifyjs-749a828fc5995836596f1d554f31479d533232fe.tar.gz
tracifyjs-749a828fc5995836596f1d554f31479d533232fe.zip
fix corner case in `collapse_vars` (#4970)
-rw-r--r--lib/compress.js43
-rw-r--r--test/compress/destructured.js36
2 files changed, 69 insertions, 10 deletions
diff --git a/lib/compress.js b/lib/compress.js
index e04e0560..b07e85ad 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -5120,6 +5120,7 @@ merge(Compressor.prototype, {
def(AST_Node, return_true);
def(AST_Constant, return_false);
+ def(AST_Destructured, return_true);
def(AST_EmptyStatement, return_false);
def(AST_Lambda, return_false);
def(AST_ObjectIdentity, return_false);
@@ -5132,6 +5133,15 @@ merge(Compressor.prototype, {
return false;
}
+ function call_may_throw(exp, compressor) {
+ if (exp.may_throw(compressor)) return true;
+ if (exp instanceof AST_SymbolRef) exp = exp.fixed_value();
+ if (!(exp instanceof AST_Lambda)) return true;
+ if (any(exp.argnames, compressor)) return true;
+ if (any(exp.body, compressor)) return true;
+ return is_arrow(exp) && exp.value && exp.value.may_throw(compressor);
+ }
+
def(AST_Array, function(compressor) {
return any(this.elements, compressor);
});
@@ -5155,9 +5165,10 @@ merge(Compressor.prototype, {
def(AST_Call, function(compressor) {
if (any(this.args, compressor)) return true;
if (this.is_expr_pure(compressor)) return false;
- if (this.expression.may_throw(compressor)) return true;
- return !(this.expression instanceof AST_Lambda)
- || any(this.expression.body, compressor);
+ this.may_throw = return_true;
+ var ret = call_may_throw(this.expression, compressor);
+ delete this.may_throw;
+ return ret;
});
def(AST_Case, function(compressor) {
return this.expression.may_throw(compressor)
@@ -5168,6 +5179,10 @@ merge(Compressor.prototype, {
|| this.consequent.may_throw(compressor)
|| this.alternative.may_throw(compressor);
});
+ def(AST_DefaultValue, function(compressor) {
+ return this.name.may_throw(compressor)
+ || this.value && this.value.may_throw(compressor);
+ });
def(AST_Definitions, function(compressor) {
return any(this.definitions, compressor);
});
@@ -5187,8 +5202,8 @@ merge(Compressor.prototype, {
return any(this.properties, compressor);
});
def(AST_ObjectProperty, function(compressor) {
- return this.key instanceof AST_Node && this.key.may_throw(compressor)
- || this.value.may_throw(compressor);
+ return this.value.may_throw(compressor)
+ || this.key instanceof AST_Node && this.key.may_throw(compressor);
});
def(AST_Return, function(compressor) {
return this.value && this.value.may_throw(compressor);
@@ -5211,18 +5226,26 @@ merge(Compressor.prototype, {
def(AST_SymbolRef, function(compressor) {
return !this.is_declared(compressor);
});
+ def(AST_Template, function(compressor) {
+ if (any(this.expressions, compressor)) return true;
+ if (this.is_expr_pure(compressor)) return false;
+ if (!this.tag) return false;
+ this.may_throw = return_true;
+ var ret = call_may_throw(this.tag, compressor);
+ delete this.may_throw;
+ return ret;
+ });
def(AST_Try, function(compressor) {
return (this.bcatch ? this.bcatch.may_throw(compressor) : any(this.body, compressor))
|| this.bfinally && this.bfinally.may_throw(compressor);
});
def(AST_Unary, function(compressor) {
- if (this.operator == "typeof" && this.expression instanceof AST_SymbolRef)
- return false;
- return this.expression.may_throw(compressor);
+ return this.expression.may_throw(compressor)
+ && !(this.operator == "typeof" && this.expression instanceof AST_SymbolRef);
});
def(AST_VarDef, function(compressor) {
- if (!this.value) return false;
- return this.value.may_throw(compressor);
+ return this.name.may_throw(compressor)
+ || this.value && this.value.may_throw(compressor);
});
})(function(node, func) {
node.DEFMETHOD("may_throw", func);
diff --git a/test/compress/destructured.js b/test/compress/destructured.js
index dd2daca9..78cd6863 100644
--- a/test/compress/destructured.js
+++ b/test/compress/destructured.js
@@ -1010,6 +1010,42 @@ collapse_vars_8: {
node_version: ">=6"
}
+collapse_vars_9: {
+ options = {
+ collapse_vars: true,
+ }
+ input: {
+ console.log(function(a) {
+ try {
+ var b = function([ c ]) {
+ if (c)
+ return "FAIL 1";
+ }();
+ a = "FAIL 2";
+ return b;
+ } catch (e) {
+ return a;
+ }
+ }("PASS"));
+ }
+ expect: {
+ console.log(function(a) {
+ try {
+ var b = function([ c ]) {
+ if (c)
+ return "FAIL 1";
+ }();
+ a = "FAIL 2";
+ return b;
+ } catch (e) {
+ return a;
+ }
+ }("PASS"));
+ }
+ expect_stdout: "PASS"
+ node_version: ">=6"
+}
+
conditionals: {
options = {
conditionals: true,