fix delete corner cases (#1799)

- assignment
- boolean
- conditional
- sequence
This commit is contained in:
Alex Lam S.L
2017-04-08 14:25:28 +08:00
committed by GitHub
parent a1532eb076
commit cf72fe552f
5 changed files with 369 additions and 24 deletions

View File

@@ -481,15 +481,15 @@ merge(Compressor.prototype, {
// func(something) because that changes the meaning of
// the func (becomes lexical instead of global).
function maintain_this_binding(parent, orig, val) {
if (parent instanceof AST_Call && parent.expression === orig) {
if (val instanceof AST_PropAccess || val instanceof AST_SymbolRef && val.name === "eval") {
return make_node(AST_Seq, orig, {
car: make_node(AST_Number, orig, {
value: 0
}),
cdr: val
});
}
if (parent instanceof AST_UnaryPrefix && parent.operator == "delete"
|| parent instanceof AST_Call && parent.expression === orig
&& (val instanceof AST_PropAccess || val instanceof AST_SymbolRef && val.name == "eval")) {
return make_node(AST_Seq, orig, {
car: make_node(AST_Number, orig, {
value: 0
}),
cdr: val
});
}
return val;
}
@@ -3103,11 +3103,27 @@ merge(Compressor.prototype, {
});
OPT(AST_UnaryPrefix, function(self, compressor){
var e = self.expression;
if (self.operator == "delete"
&& !(e instanceof AST_SymbolRef
|| e instanceof AST_PropAccess
|| e instanceof AST_NaN
|| e instanceof AST_Infinity
|| e instanceof AST_Undefined)) {
if (e instanceof AST_Seq) {
e = e.to_array();
e.push(make_node(AST_True, self));
return AST_Seq.from_array(e).optimize(compressor);
}
return make_node(AST_Seq, self, {
car: e,
cdr: make_node(AST_True, self)
}).optimize(compressor);
}
var seq = self.lift_sequences(compressor);
if (seq !== self) {
return seq;
}
var e = self.expression;
if (compressor.option("side_effects") && self.operator == "void") {
e = e.drop_side_effect_free(compressor);
if (e) {
@@ -3606,6 +3622,14 @@ merge(Compressor.prototype, {
return self;
});
function in_delete(parent) {
return parent instanceof AST_UnaryPrefix && parent.operator == "delete";
}
function is_atomic(parent, self) {
return parent.expression instanceof AST_SymbolRef || parent.expression.TYPE === self.TYPE;
}
OPT(AST_Undefined, function(self, compressor){
if (compressor.option("unsafe")) {
var undef = find_variable(compressor, "undefined");
@@ -3620,10 +3644,7 @@ merge(Compressor.prototype, {
}
}
var parent = compressor.parent();
if (parent instanceof AST_UnaryPrefix
&& parent.operator == "delete"
&& (parent.expression instanceof AST_SymbolRef
|| parent.expression.TYPE === self.TYPE)) return self;
if (in_delete(parent) && is_atomic(parent, self)) return self;
return make_node(AST_UnaryPrefix, self, {
operator: "void",
expression: make_node(AST_Number, self, {
@@ -3634,12 +3655,10 @@ merge(Compressor.prototype, {
OPT(AST_Infinity, function(self, compressor){
var parent = compressor.parent();
if (parent instanceof AST_UnaryPrefix
&& parent.operator == "delete"
&& (parent.expression instanceof AST_SymbolRef
|| parent.expression.TYPE === self.TYPE))
return self;
var del = in_delete(parent);
if (del && is_atomic(parent, self)) return self;
if (compressor.option("keep_infinity")
&& !(del && !is_atomic(parent, self))
&& !find_variable(compressor, "Infinity"))
return self;
return make_node(AST_Binary, self, {
@@ -3655,10 +3674,7 @@ merge(Compressor.prototype, {
OPT(AST_NaN, function(self, compressor){
var parent = compressor.parent();
if (parent instanceof AST_UnaryPrefix
&& parent.operator == "delete"
&& !(parent.expression instanceof AST_SymbolRef
|| parent.expression.TYPE === self.TYPE)
if (in_delete(parent) && !is_atomic(parent, self)
|| find_variable(compressor, "NaN")) {
return make_node(AST_Binary, self, {
operator: "/",