aboutsummaryrefslogtreecommitdiff
path: root/lib/compress.js
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2017-04-08 14:25:28 +0800
committerGitHub <noreply@github.com>2017-04-08 14:25:28 +0800
commitcf72fe552f5a51ccfe40c32e0fb86d549e0ca848 (patch)
treec8fae2eef25cb24475a37d06cbd502dbf5599671 /lib/compress.js
parenta1532eb076d506fbf87a04c0ec4f26e1929aa902 (diff)
downloadtracifyjs-cf72fe552f5a51ccfe40c32e0fb86d549e0ca848.tar.gz
tracifyjs-cf72fe552f5a51ccfe40c32e0fb86d549e0ca848.zip
fix `delete` corner cases (#1799)
- assignment - boolean - conditional - sequence
Diffstat (limited to 'lib/compress.js')
-rw-r--r--lib/compress.js62
1 files changed, 39 insertions, 23 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 03b1fefb..de0ff387 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -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: "/",