enhance side_effects (#5304)
This commit is contained in:
@@ -5303,21 +5303,43 @@ Compressor.prototype.compress = function(node) {
|
|||||||
return map && map[prop];
|
return map && map[prop];
|
||||||
});
|
});
|
||||||
|
|
||||||
function spread_side_effects(exp) {
|
// determine if object spread syntax may cause runtime exception
|
||||||
while ((exp = exp.tail_node()) instanceof AST_SymbolRef) {
|
(function(def) {
|
||||||
exp = exp.fixed_value();
|
def(AST_Node, return_false);
|
||||||
if (!exp) return true;
|
def(AST_Array, return_true);
|
||||||
}
|
def(AST_Assign, function() {
|
||||||
return !(exp instanceof AST_Array
|
switch (this.operator) {
|
||||||
|| exp.TYPE == "Binary" && !lazy_op[exp.operator]
|
case "=":
|
||||||
|| exp instanceof AST_Constant
|
return this.right.safe_to_spread();
|
||||||
|| exp instanceof AST_Lambda
|
case "&&=":
|
||||||
|| exp instanceof AST_Object && all(exp.properties, function(prop) {
|
case "||=":
|
||||||
|
case "??=":
|
||||||
|
return this.left.safe_to_spread() && this.right.safe_to_spread();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
def(AST_Binary, function() {
|
||||||
|
return !lazy_op[this.operator] || this.left.safe_to_spread() && this.right.safe_to_spread();
|
||||||
|
});
|
||||||
|
def(AST_Constant, return_true);
|
||||||
|
def(AST_Lambda, return_true);
|
||||||
|
def(AST_Object, function() {
|
||||||
|
return all(this.properties, function(prop) {
|
||||||
return !(prop instanceof AST_ObjectGetter || prop instanceof AST_Spread);
|
return !(prop instanceof AST_ObjectGetter || prop instanceof AST_Spread);
|
||||||
})
|
});
|
||||||
|| exp instanceof AST_ObjectIdentity
|
});
|
||||||
|| exp instanceof AST_Unary);
|
def(AST_ObjectIdentity, return_true);
|
||||||
}
|
def(AST_Sequence, function() {
|
||||||
|
return this.tail_node().safe_to_spread();
|
||||||
|
});
|
||||||
|
def(AST_SymbolRef, function() {
|
||||||
|
var fixed = this.fixed_value();
|
||||||
|
return fixed && fixed.safe_to_spread();
|
||||||
|
});
|
||||||
|
def(AST_Unary, return_true);
|
||||||
|
})(function(node, func) {
|
||||||
|
node.DEFMETHOD("safe_to_spread", func);
|
||||||
|
});
|
||||||
|
|
||||||
// determine if expression has side effects
|
// determine if expression has side effects
|
||||||
(function(def) {
|
(function(def) {
|
||||||
@@ -5329,7 +5351,8 @@ Compressor.prototype.compress = function(node) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
function array_spread(node, compressor) {
|
function array_spread(node, compressor) {
|
||||||
return !node.expression.is_string(compressor) || node.expression.has_side_effects(compressor);
|
var exp = node.expression;
|
||||||
|
return !exp.is_string(compressor) || exp.has_side_effects(compressor);
|
||||||
}
|
}
|
||||||
def(AST_Node, return_true);
|
def(AST_Node, return_true);
|
||||||
def(AST_Array, function(compressor) {
|
def(AST_Array, function(compressor) {
|
||||||
@@ -5411,7 +5434,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
def(AST_Object, function(compressor) {
|
def(AST_Object, function(compressor) {
|
||||||
return any(this.properties, compressor, function(node, compressor) {
|
return any(this.properties, compressor, function(node, compressor) {
|
||||||
var exp = node.expression;
|
var exp = node.expression;
|
||||||
return spread_side_effects(exp) || exp.has_side_effects(compressor);
|
return !exp.safe_to_spread() || exp.has_side_effects(compressor);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
def(AST_ObjectIdentity, return_false);
|
def(AST_ObjectIdentity, return_false);
|
||||||
@@ -8387,7 +8410,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
});
|
});
|
||||||
var values = trim(exprs, compressor, first_in_statement, function(node, compressor, first_in_statement) {
|
var values = trim(exprs, compressor, first_in_statement, function(node, compressor, first_in_statement) {
|
||||||
var exp = node.expression;
|
var exp = node.expression;
|
||||||
return spread_side_effects(exp) ? node : exp.drop_side_effect_free(compressor, first_in_statement);
|
return exp.safe_to_spread() ? exp.drop_side_effect_free(compressor, first_in_statement) : node;
|
||||||
});
|
});
|
||||||
if (!values) return null;
|
if (!values) return null;
|
||||||
if (values === exprs && !all(values, function(node) {
|
if (values === exprs && !all(values, function(node) {
|
||||||
|
|||||||
@@ -241,7 +241,29 @@ drop_empty_call_2: {
|
|||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
convert_hole: {
|
convert_hole_array: {
|
||||||
|
options = {
|
||||||
|
spreads: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
[ ...[ "PASS", , 42 ] ].forEach(function(a) {
|
||||||
|
console.log(a);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
[ "PASS", void 0, 42 ].forEach(function(a) {
|
||||||
|
console.log(a);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS",
|
||||||
|
"undefined",
|
||||||
|
"42",
|
||||||
|
]
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
convert_hole_call: {
|
||||||
options = {
|
options = {
|
||||||
spreads: true,
|
spreads: true,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user