// 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_call_binding(parent, orig, val) {
+ function maintain_this_binding(parent, orig, val) {
if (parent instanceof AST_Call && parent.expression === orig) {
- if (val instanceof AST_PropAccess || (val instanceof AST_Symbol && val.name === "eval")) {
+ 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
if (is_lvalue(node, parent)) return node;
// Remove var definition and return its value to the TreeTransformer to replace.
- var value = maintain_call_binding(parent, node, var_decl.value);
+ var value = maintain_this_binding(parent, node, var_decl.value);
var_decl.value = null;
var_defs.splice(var_defs_index, 1);
if (!compressor.option("side_effects"))
return self;
if (!self.car.has_side_effects(compressor)) {
- return maintain_call_binding(compressor.parent(), self, self.cdr);
+ return maintain_this_binding(compressor.parent(), self, self.cdr);
}
if (compressor.option("cascade")) {
if (self.car instanceof AST_Assign
if (ll.length > 1) {
if (ll[1]) {
compressor.warn("Condition left of && always true [{file}:{line},{col}]", self.start);
- return maintain_call_binding(compressor.parent(), self, self.right.evaluate(compressor)[0]);
+ return maintain_this_binding(compressor.parent(), self, self.right.evaluate(compressor)[0]);
} else {
compressor.warn("Condition left of && always false [{file}:{line},{col}]", self.start);
- return maintain_call_binding(compressor.parent(), self, ll[0]);
+ return maintain_this_binding(compressor.parent(), self, ll[0]);
}
}
}
if (ll.length > 1) {
if (ll[1]) {
compressor.warn("Condition left of || always true [{file}:{line},{col}]", self.start);
- return maintain_call_binding(compressor.parent(), self, ll[0]);
+ return maintain_this_binding(compressor.parent(), self, ll[0]);
} else {
compressor.warn("Condition left of || always false [{file}:{line},{col}]", self.start);
- return maintain_call_binding(compressor.parent(), self, self.right.evaluate(compressor)[0]);
+ return maintain_this_binding(compressor.parent(), self, self.right.evaluate(compressor)[0]);
}
}
}
if (cond.length > 1) {
if (cond[1]) {
compressor.warn("Condition always true [{file}:{line},{col}]", self.start);
- return maintain_call_binding(compressor.parent(), self, self.consequent);
+ return maintain_this_binding(compressor.parent(), self, self.consequent);
} else {
compressor.warn("Condition always false [{file}:{line},{col}]", self.start);
- return maintain_call_binding(compressor.parent(), self, self.alternative);
+ return maintain_this_binding(compressor.parent(), self, self.alternative);
}
}
var negated = cond[0].negate(compressor);
}
if (node instanceof AST_SymbolRef) {
var name = node.name;
+ if (name == "eval" && tw.parent() instanceof AST_Call) {
+ for (var s = node.scope; s && !s.uses_eval; s = s.parent_scope) {
+ s.uses_eval = true;
+ }
+ }
var sym = node.scope.find_variable(name);
if (!sym) {
var g;
globals.set(name, g);
}
node.thedef = g;
- if (name == "eval" && tw.parent() instanceof AST_Call) {
- for (var s = node.scope; s && !s.uses_eval; s = s.parent_scope)
- s.uses_eval = true;
- }
if (func && name == "arguments") {
func.uses_arguments = true;
}
remove_redundant_sequence_items: {
options = { side_effects: true };
input: {
+ (0, 1, eval)();
(0, 1, logThis)();
(0, 1, _decorators.logThis)();
}
expect: {
+ (0, eval)();
logThis();
(0, _decorators.logThis)();
}
dont_remove_this_binding_sequence: {
options = { side_effects: true };
input: {
+ (0, eval)();
(0, logThis)();
(0, _decorators.logThis)();
}
expect: {
+ (0, eval)();
logThis();
(0, _decorators.logThis)();
}
(0 || a[b])();
(0 || 1 && a[b])();
(1 ? a[b] : 0)();
+
+ (1 && eval)();
+ (0 || eval)();
+ (0 || 1 && eval)();
+ (1 ? eval : 0)();
}
expect: {
a();
(0, a[b])();
(0, a[b])();
(0, a[b])();
+
+ (0, eval)();
+ (0, eval)();
+ (0, eval)();
+ (0, eval)();
}
}
input: {
var c = a; c();
var d = a.b; d();
+ var e = eval; e();
}
expect: {
a();
(0, a.b)();
+ (0, eval)();
}
}
-eval_direct_calls: {
+this_binding_side_effects: {
options = {
- side_effects: true,
- collapse_vars: true
- }
+ side_effects : true
+ };
input: {
- (0, eval)('');
-
- var fn = eval;
- fn('');
+ (function (foo) {
+ (0, foo)();
+ (0, foo.bar)();
+ (0, eval)('console.log(foo);');
+ }());
+ (function (foo) {
+ var eval = console;
+ (0, foo)();
+ (0, foo.bar)();
+ (0, eval)('console.log(foo);');
+ }());
}
expect: {
- (0, eval)('');
- (0, eval)('');
+ (function (foo) {
+ foo();
+ (0, foo.bar)();
+ (0, eval)('console.log(foo);');
+ }());
+ (function (foo) {
+ var eval = console;
+ foo();
+ (0, foo.bar)();
+ (0, eval)('console.log(foo);');
+ }());
}
}
\ No newline at end of file
--- /dev/null
+eval_collapse_vars: {
+ options = {
+ collapse_vars:true, sequences:false, properties:true, dead_code:true, conditionals:true,
+ comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
+ keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
+ };
+ input: {
+ function f1() {
+ var e = 7;
+ var s = "abcdef";
+ var i = 2;
+ var eval = console.log.bind(console);
+ var x = s.charAt(i++);
+ var y = s.charAt(i++);
+ var z = s.charAt(i++);
+ eval(x, y, z, e);
+ }
+ function p1() { var a = foo(), b = bar(), eval = baz(); return a + b + eval; }
+ function p2() { var a = foo(), b = bar(), eval = baz; return a + b + eval(); }
+ (function f2(eval) {
+ var a = 2;
+ console.log(a - 5);
+ eval("console.log(a);");
+ })(eval);
+ }
+ expect: {
+ function f1() {
+ var e = 7,
+ s = "abcdef",
+ i = 2,
+ eval = console.log.bind(console),
+ x = s.charAt(i++),
+ y = s.charAt(i++),
+ z = s.charAt(i++);
+ eval(x, y, z, e);
+ }
+ function p1() { return foo() + bar() + baz(); }
+ function p2() { var a = foo(), b = bar(), eval = baz; return a + b + eval(); }
+ (function f2(eval) {
+ var a = 2;
+ console.log(a - 5);
+ eval("console.log(a);");
+ })(eval);
+ }
+}
+
+eval_unused: {
+ options = { unused: true, keep_fargs: false };
+ input: {
+ function f1(a, eval, c, d, e) {
+ return a('c') + eval;
+ }
+ function f2(a, b, c, d, e) {
+ return a + eval('c');
+ }
+ function f3(a, eval, c, d, e) {
+ return a + eval('c');
+ }
+ }
+ expect: {
+ function f1(a, eval) {
+ return a('c') + eval;
+ }
+ function f2(a, b, c, d, e) {
+ return a + eval('c');
+ }
+ function f3(a, eval, c, d, e) {
+ return a + eval('c');
+ }
+ }
+}
+
+eval_mangle: {
+ mangle = {
+ };
+ input: {
+ function f1(a, eval, c, d, e) {
+ return a('c') + eval;
+ }
+ function f2(a, b, c, d, e) {
+ return a + eval('c');
+ }
+ function f3(a, eval, c, d, e) {
+ return a + eval('c');
+ }
+ }
+ expect_exact: 'function f1(n,c,e,a,o){return n("c")+c}function f2(a,b,c,d,e){return a+eval("c")}function f3(a,eval,c,d,e){return a+eval("c")}'
+}