enhance unsafe_comps (#5510)
This commit is contained in:
@@ -818,8 +818,9 @@ to be `false` and all symbol names will be omitted.
|
|||||||
|
|
||||||
- `unsafe` (default: `false`) — apply "unsafe" transformations (discussion below)
|
- `unsafe` (default: `false`) — apply "unsafe" transformations (discussion below)
|
||||||
|
|
||||||
- `unsafe_comps` (default: `false`) — compress expressions like `a <= b` assuming
|
- `unsafe_comps` (default: `false`) — assume operands cannot be (coerced to) `NaN`
|
||||||
none of the operands can be (coerced to) `NaN`.
|
in numeric comparisons, e.g. `a <= b`. In addition, expressions involving `in`
|
||||||
|
or `instanceof` would never throw.
|
||||||
|
|
||||||
- `unsafe_Function` (default: `false`) — compress and mangle `Function(args, code)`
|
- `unsafe_Function` (default: `false`) — compress and mangle `Function(args, code)`
|
||||||
when both `args` and `code` are string literals.
|
when both `args` and `code` are string literals.
|
||||||
|
|||||||
@@ -2452,7 +2452,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
|
|
||||||
function is_last_node(node, parent) {
|
function is_last_node(node, parent) {
|
||||||
if (node instanceof AST_Await) return true;
|
if (node instanceof AST_Await) return true;
|
||||||
if (node.TYPE == "Binary") return !can_drop_op(node.operator, node.right);
|
if (node.TYPE == "Binary") return !can_drop_op(node.operator, node.right, compressor);
|
||||||
if (node instanceof AST_Call) {
|
if (node instanceof AST_Call) {
|
||||||
var def, fn = node.expression;
|
var def, fn = node.expression;
|
||||||
if (fn instanceof AST_SymbolRef) {
|
if (fn instanceof AST_SymbolRef) {
|
||||||
@@ -5551,7 +5551,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
def(AST_Binary, function(compressor) {
|
def(AST_Binary, function(compressor) {
|
||||||
return this.left.has_side_effects(compressor)
|
return this.left.has_side_effects(compressor)
|
||||||
|| this.right.has_side_effects(compressor)
|
|| this.right.has_side_effects(compressor)
|
||||||
|| !can_drop_op(this.operator, this.right);
|
|| !can_drop_op(this.operator, this.right, compressor);
|
||||||
});
|
});
|
||||||
def(AST_Block, function(compressor) {
|
def(AST_Block, function(compressor) {
|
||||||
return any(this.body, compressor);
|
return any(this.body, compressor);
|
||||||
@@ -5705,7 +5705,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
def(AST_Binary, function(compressor) {
|
def(AST_Binary, function(compressor) {
|
||||||
return this.left.may_throw(compressor)
|
return this.left.may_throw(compressor)
|
||||||
|| this.right.may_throw(compressor)
|
|| this.right.may_throw(compressor)
|
||||||
|| !can_drop_op(this.operator, this.right);
|
|| !can_drop_op(this.operator, this.right, compressor);
|
||||||
});
|
});
|
||||||
def(AST_Block, function(compressor) {
|
def(AST_Block, function(compressor) {
|
||||||
return any(this.body, compressor);
|
return any(this.body, compressor);
|
||||||
@@ -8533,7 +8533,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
var left = this.left;
|
var left = this.left;
|
||||||
var right = this.right;
|
var right = this.right;
|
||||||
var op = this.operator;
|
var op = this.operator;
|
||||||
if (!can_drop_op(op, right)) {
|
if (!can_drop_op(op, right, compressor)) {
|
||||||
var lhs = left.drop_side_effect_free(compressor, first_in_statement);
|
var lhs = left.drop_side_effect_free(compressor, first_in_statement);
|
||||||
if (lhs === left) return this;
|
if (lhs === left) return this;
|
||||||
var node = this.clone();
|
var node = this.clone();
|
||||||
@@ -11202,13 +11202,13 @@ Compressor.prototype.compress = function(node) {
|
|||||||
|| node instanceof AST_Object;
|
|| node instanceof AST_Object;
|
||||||
}
|
}
|
||||||
|
|
||||||
function can_drop_op(op, rhs) {
|
function can_drop_op(op, rhs, compressor) {
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case "in":
|
case "in":
|
||||||
return is_object(rhs);
|
return is_object(rhs) || compressor && compressor.option("unsafe_comps");
|
||||||
case "instanceof":
|
case "instanceof":
|
||||||
if (rhs instanceof AST_SymbolRef) rhs = rhs.fixed_value();
|
if (rhs instanceof AST_SymbolRef) rhs = rhs.fixed_value();
|
||||||
return is_lambda(rhs);
|
return is_lambda(rhs) || compressor && compressor.option("unsafe_comps");
|
||||||
default:
|
default:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,22 @@ unsafe_comps: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe_in_instanceof: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
unsafe_comps: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
42 in a;
|
||||||
|
f() instanceof "foo";
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dont_change_in_or_instanceof_expressions: {
|
dont_change_in_or_instanceof_expressions: {
|
||||||
input: {
|
input: {
|
||||||
1 in 1;
|
1 in 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user