diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2018-05-10 06:16:35 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-10 06:16:35 +0800 |
commit | 14e712ee802da2a6199653268f8519187ece2c51 (patch) | |
tree | 0a0381a2de77ccc31bac130441ad6233da84d868 /lib | |
parent | f83adcc9958ad0fc98c175a4d19ad3d37d228f24 (diff) | |
download | tracifyjs-14e712ee802da2a6199653268f8519187ece2c51.tar.gz tracifyjs-14e712ee802da2a6199653268f8519187ece2c51.zip |
fix corner case in call binding (#3128)
fixes #3127
Diffstat (limited to 'lib')
-rw-r--r-- | lib/compress.js | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/lib/compress.js b/lib/compress.js index 8c565c21..d3c24529 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -919,15 +919,21 @@ merge(Compressor.prototype, { type: typeof val })); } - }; + } + + function needs_unbinding(compressor, val) { + return val instanceof AST_PropAccess + || compressor.has_directive("use strict") + && is_undeclared_ref(val) + && val.name == "eval"; + } // we shouldn't compress (1,func)(something) to // func(something) because that changes the meaning of // the func (becomes lexical instead of global). - function maintain_this_binding(parent, orig, val) { + function maintain_this_binding(compressor, parent, orig, val) { if (parent instanceof AST_UnaryPrefix && parent.operator == "delete" - || parent.TYPE == "Call" && parent.expression === orig - && (val instanceof AST_PropAccess || val instanceof AST_SymbolRef && val.name == "eval")) { + || parent.TYPE == "Call" && parent.expression === orig && needs_unbinding(compressor, val)) { return make_sequence(orig, [ make_node(AST_Number, orig, { value: 0 }), val ]); } return val; @@ -1098,7 +1104,7 @@ merge(Compressor.prototype, { var def = candidate.name.definition(); if (def.references.length - def.replaced == 1 && !compressor.exposed(def)) { def.replaced++; - return maintain_this_binding(parent, node, candidate.value); + return maintain_this_binding(compressor, parent, node, candidate.value); } return make_node(AST_Assign, candidate, { operator: "=", @@ -3346,7 +3352,7 @@ merge(Compressor.prototype, { } if (value) { props.push(value); - return maintain_this_binding(parent, node, make_sequence(node, props.map(function(prop) { + return maintain_this_binding(compressor, parent, node, make_sequence(node, props.map(function(prop) { return prop.transform(tt); }))); } @@ -4477,7 +4483,7 @@ merge(Compressor.prototype, { var exp = this.expression; if (!(exp instanceof AST_Sequence)) return this; var tail = exp.tail_node(); - if (tail instanceof AST_PropAccess && !(this instanceof AST_New)) return this; + if (needs_unbinding(compressor, tail) && !(this instanceof AST_New)) return this; var expressions = exp.expressions.slice(0, -1); var node = this.clone(); node.expression = tail; @@ -5028,7 +5034,7 @@ merge(Compressor.prototype, { var end = expressions.length - 1; trim_right_for_undefined(); if (end == 0) { - self = maintain_this_binding(compressor.parent(), compressor.self(), expressions[0]); + self = maintain_this_binding(compressor, compressor.parent(), compressor.self(), expressions[0]); if (!(self instanceof AST_Sequence)) self = self.optimize(compressor); return self; } @@ -5347,7 +5353,7 @@ merge(Compressor.prototype, { var ll = fuzzy_eval(self.left); if (!ll) { compressor.warn("Condition left of && always false [{file}:{line},{col}]", self.start); - return maintain_this_binding(compressor.parent(), compressor.self(), self.left).optimize(compressor); + return maintain_this_binding(compressor, compressor.parent(), compressor.self(), self.left).optimize(compressor); } else if (!(ll instanceof AST_Node)) { compressor.warn("Condition left of && always true [{file}:{line},{col}]", self.start); return make_sequence(self, [ self.left, self.right ]).optimize(compressor); @@ -5386,7 +5392,7 @@ merge(Compressor.prototype, { return make_sequence(self, [ self.left, self.right ]).optimize(compressor); } else if (!(ll instanceof AST_Node)) { compressor.warn("Condition left of || always true [{file}:{line},{col}]", self.start); - return maintain_this_binding(compressor.parent(), compressor.self(), self.left).optimize(compressor); + return maintain_this_binding(compressor, compressor.parent(), compressor.self(), self.left).optimize(compressor); } var rr = self.right.evaluate(compressor); if (!rr) { |