diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2017-04-08 14:25:28 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-04-08 14:25:28 +0800 |
commit | cf72fe552f5a51ccfe40c32e0fb86d549e0ca848 (patch) | |
tree | c8fae2eef25cb24475a37d06cbd502dbf5599671 /lib/compress.js | |
parent | a1532eb076d506fbf87a04c0ec4f26e1929aa902 (diff) | |
download | tracifyjs-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.js | 62 |
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: "/", |