aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2018-05-10 06:16:35 +0800
committerGitHub <noreply@github.com>2018-05-10 06:16:35 +0800
commit14e712ee802da2a6199653268f8519187ece2c51 (patch)
tree0a0381a2de77ccc31bac130441ad6233da84d868 /lib
parentf83adcc9958ad0fc98c175a4d19ad3d37d228f24 (diff)
downloadtracifyjs-14e712ee802da2a6199653268f8519187ece2c51.tar.gz
tracifyjs-14e712ee802da2a6199653268f8519187ece2c51.zip
fix corner case in call binding (#3128)
fixes #3127
Diffstat (limited to 'lib')
-rw-r--r--lib/compress.js26
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) {