Skip to content

Commit

Permalink
fix corner case in collapse_vars (#4970)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexlamsl committed May 27, 2021
1 parent ab42a90 commit 749a828
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 10 deletions.
43 changes: 33 additions & 10 deletions lib/compress.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
});
Expand All @@ -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)
Expand All @@ -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);
});
Expand All @@ -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);
Expand All @@ -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);
Expand Down
36 changes: 36 additions & 0 deletions test/compress/destructured.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 749a828

Please sign in to comment.