Merge remote-tracking branch 'refs/remotes/mishoo/master'

This commit is contained in:
pborunda 2017-03-02 07:13:44 -07:00
commit fef2699de1
11 changed files with 458 additions and 62 deletions

View File

@ -624,7 +624,7 @@ function uglify(ast, options, mangle) {
// Compression // Compression
uAST.figure_out_scope(); uAST.figure_out_scope();
uAST = uAST.transform(UglifyJS.Compressor(options)); uAST = UglifyJS.Compressor(options).compress(uAST);
// Mangling (optional) // Mangling (optional)
if (mangle) { if (mangle) {
@ -868,7 +868,7 @@ toplevel.figure_out_scope()
Like this: Like this:
```javascript ```javascript
var compressor = UglifyJS.Compressor(options); var compressor = UglifyJS.Compressor(options);
var compressed_ast = toplevel.transform(compressor); var compressed_ast = compressor.compress(toplevel);
``` ```
The `options` can be missing. Available options are discussed above in The `options` can be missing. Available options are discussed above in

View File

@ -61,7 +61,7 @@ function Compressor(options, false_by_default) {
booleans : !false_by_default, booleans : !false_by_default,
loops : !false_by_default, loops : !false_by_default,
unused : !false_by_default, unused : !false_by_default,
toplevel : !!options["top_retain"], toplevel : !!(options && options["top_retain"]),
top_retain : null, top_retain : null,
hoist_funs : !false_by_default, hoist_funs : !false_by_default,
keep_fargs : true, keep_fargs : true,
@ -70,7 +70,7 @@ function Compressor(options, false_by_default) {
if_return : !false_by_default, if_return : !false_by_default,
join_vars : !false_by_default, join_vars : !false_by_default,
collapse_vars : !false_by_default, collapse_vars : !false_by_default,
reduce_vars : false, reduce_vars : !false_by_default,
cascade : !false_by_default, cascade : !false_by_default,
side_effects : !false_by_default, side_effects : !false_by_default,
pure_getters : false, pure_getters : false,
@ -180,38 +180,105 @@ merge(Compressor.prototype, {
AST_Node.DEFMETHOD("reset_opt_flags", function(compressor, rescan){ AST_Node.DEFMETHOD("reset_opt_flags", function(compressor, rescan){
var reduce_vars = rescan && compressor.option("reduce_vars"); var reduce_vars = rescan && compressor.option("reduce_vars");
var unsafe = compressor.option("unsafe"); var safe_ids = [];
push();
var tw = new TreeWalker(function(node){ var tw = new TreeWalker(function(node){
if (!(node instanceof AST_Directive || node instanceof AST_Constant)) {
node._squeezed = false;
node._optimized = false;
}
if (reduce_vars) { if (reduce_vars) {
if (node instanceof AST_Toplevel) node.globals.each(reset_def); if (node instanceof AST_Toplevel) node.globals.each(reset_def);
if (node instanceof AST_Scope) node.variables.each(reset_def); if (node instanceof AST_Scope) node.variables.each(reset_def);
if (node instanceof AST_SymbolRef) { if (node instanceof AST_SymbolRef) {
var d = node.definition(); var d = node.definition();
d.references.push(node); d.references.push(node);
if (!d.modified && (d.orig.length > 1 || isModified(node, 0))) { if (!d.fixed || isModified(node, 0) || !is_safe(d)) {
d.modified = true; d.fixed = false;
} }
} }
if (node instanceof AST_Call && node.expression instanceof AST_Function) { if (node instanceof AST_VarDef) {
node.expression.argnames.forEach(function(arg, i) { var d = node.name.definition();
arg.definition().init = node.args[i] || make_node(AST_Undefined, node); if (d.fixed === undefined) {
d.fixed = node.value || make_node(AST_Undefined, node);
mark_as_safe(d);
} else {
d.fixed = false;
}
}
var iife;
if (node instanceof AST_Function
&& (iife = tw.parent()) instanceof AST_Call
&& iife.expression === node) {
node.argnames.forEach(function(arg, i) {
var d = arg.definition();
d.fixed = iife.args[i] || make_node(AST_Undefined, iife);
mark_as_safe(d);
}); });
} }
} if (node instanceof AST_If || node instanceof AST_DWLoop) {
if (!(node instanceof AST_Directive || node instanceof AST_Constant)) { node.condition.walk(tw);
node._squeezed = false; push();
node._optimized = false; node.body.walk(tw);
pop();
if (node.alternative) {
push();
node.alternative.walk(tw);
pop();
}
return true;
}
if (node instanceof AST_LabeledStatement) {
push();
node.body.walk(tw);
pop();
return true;
}
if (node instanceof AST_For) {
if (node.init) node.init.walk(tw);
push();
if (node.condition) node.condition.walk(tw);
node.body.walk(tw);
if (node.step) node.step.walk(tw);
pop();
return true;
}
if (node instanceof AST_ForIn) {
if (node.init instanceof AST_SymbolRef) {
node.init.definition().fixed = false;
}
node.object.walk(tw);
push();
node.body.walk(tw);
pop();
return true;
}
} }
}); });
this.walk(tw); this.walk(tw);
function mark_as_safe(def) {
safe_ids[safe_ids.length - 1][def.id] = true;
}
function is_safe(def) {
for (var i = safe_ids.length, id = def.id; --i >= 0;) {
if (safe_ids[i][id]) return true;
}
}
function push() {
safe_ids.push(Object.create(null));
}
function pop() {
safe_ids.pop();
}
function reset_def(def) { function reset_def(def) {
def.modified = false; def.fixed = undefined;
def.references = []; def.references = [];
def.should_replace = undefined; def.should_replace = undefined;
if (unsafe && def.init) {
def.init._evaluated = undefined;
}
} }
function isModified(node, level) { function isModified(node, level) {
@ -988,12 +1055,6 @@ merge(Compressor.prototype, {
def(AST_Conditional, function(compressor){ def(AST_Conditional, function(compressor){
return this.consequent.is_string(compressor) && this.alternative.is_string(compressor); return this.consequent.is_string(compressor) && this.alternative.is_string(compressor);
}); });
def(AST_Call, function(compressor){
return compressor.option("unsafe")
&& this.expression instanceof AST_SymbolRef
&& this.expression.name == "String"
&& this.expression.undeclared();
});
})(function(node, func){ })(function(node, func){
node.DEFMETHOD("is_string", func); node.DEFMETHOD("is_string", func);
}); });
@ -1149,11 +1210,14 @@ merge(Compressor.prototype, {
def(AST_Statement, function(){ def(AST_Statement, function(){
throw new Error(string_template("Cannot evaluate a statement [{file}:{line},{col}]", this.start)); throw new Error(string_template("Cannot evaluate a statement [{file}:{line},{col}]", this.start));
}); });
// XXX: AST_Accessor and AST_Function both inherit from AST_Scope,
// which itself inherits from AST_Statement; however, they aren't
// really statements. This could bite in other places too. :-(
// Wish JS had multiple inheritance.
def(AST_Accessor, function(){
throw def;
});
def(AST_Function, function(){ def(AST_Function, function(){
// XXX: AST_Function inherits from AST_Scope, which itself
// inherits from AST_Statement; however, an AST_Function
// isn't really a statement. This could byte in other
// places too. :-( Wish JS had multiple inheritance.
throw def; throw def;
}); });
function ev(node, compressor) { function ev(node, compressor) {
@ -1181,7 +1245,9 @@ merge(Compressor.prototype, {
for (var i = 0, len = this.properties.length; i < len; i++) { for (var i = 0, len = this.properties.length; i < len; i++) {
var prop = this.properties[i]; var prop = this.properties[i];
var key = prop.key; var key = prop.key;
if (key instanceof AST_Node) { if (key instanceof AST_Symbol) {
key = key.name;
} else if (key instanceof AST_Node) {
key = ev(key, compressor); key = ev(key, compressor);
} }
if (typeof Object.prototype[key] === 'function') { if (typeof Object.prototype[key] === 'function') {
@ -1259,14 +1325,14 @@ merge(Compressor.prototype, {
this._evaluating = true; this._evaluating = true;
try { try {
var d = this.definition(); var d = this.definition();
if (compressor.option("reduce_vars") && !d.modified && d.init) { if (compressor.option("reduce_vars") && d.fixed) {
if (compressor.option("unsafe")) { if (compressor.option("unsafe")) {
if (d.init._evaluated === undefined) { if (!HOP(d.fixed, "_evaluated")) {
d.init._evaluated = ev(d.init, compressor); d.fixed._evaluated = ev(d.fixed, compressor);
} }
return d.init._evaluated; return d.fixed._evaluated;
} }
return ev(d.init, compressor); return ev(d.fixed, compressor);
} }
} finally { } finally {
this._evaluating = false; this._evaluating = false;
@ -2190,7 +2256,7 @@ merge(Compressor.prototype, {
// here because they are only used in an equality comparison later on. // here because they are only used in an equality comparison later on.
self.condition = negated; self.condition = negated;
var tmp = self.body; var tmp = self.body;
self.body = self.alternative || make_node(AST_EmptyStatement); self.body = self.alternative || make_node(AST_EmptyStatement, self);
self.alternative = tmp; self.alternative = tmp;
} }
if (is_empty(self.body) && is_empty(self.alternative)) { if (is_empty(self.body) && is_empty(self.alternative)) {
@ -2416,6 +2482,20 @@ merge(Compressor.prototype, {
}); });
OPT(AST_Call, function(self, compressor){ OPT(AST_Call, function(self, compressor){
if (compressor.option("unused")
&& self.expression instanceof AST_Function
&& !self.expression.uses_arguments
&& !self.expression.uses_eval
&& self.args.length > self.expression.argnames.length) {
var end = self.expression.argnames.length;
for (var i = end, len = self.args.length; i < len; i++) {
var node = self.args[i].drop_side_effect_free(compressor);
if (node) {
self.args[end++] = node;
}
}
self.args.length = end;
}
if (compressor.option("unsafe")) { if (compressor.option("unsafe")) {
var exp = self.expression; var exp = self.expression;
if (exp instanceof AST_SymbolRef && exp.undeclared()) { if (exp instanceof AST_SymbolRef && exp.undeclared()) {
@ -2455,7 +2535,7 @@ merge(Compressor.prototype, {
case "Boolean": case "Boolean":
if (self.args.length == 0) return make_node(AST_False, self); if (self.args.length == 0) return make_node(AST_False, self);
if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, { if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, {
expression: make_node(AST_UnaryPrefix, null, { expression: make_node(AST_UnaryPrefix, self, {
expression: self.args[0], expression: self.args[0],
operator: "!" operator: "!"
}), }),
@ -2627,6 +2707,12 @@ merge(Compressor.prototype, {
} }
} }
} }
if (self.args.length == 0
&& self.expression instanceof AST_Function
&& self.expression.body[0] instanceof AST_Return
&& self.expression.body[0].value.is_constant()) {
return self.expression.body[0].value;
}
if (compressor.option("negate_iife") if (compressor.option("negate_iife")
&& compressor.parent() instanceof AST_SimpleStatement && compressor.parent() instanceof AST_SimpleStatement
&& is_iife_call(self)) { && is_iife_call(self)) {
@ -2890,7 +2976,7 @@ merge(Compressor.prototype, {
compressor.warn("Boolean && always false [{file}:{line},{col}]", self.start); compressor.warn("Boolean && always false [{file}:{line},{col}]", self.start);
return make_node(AST_Seq, self, { return make_node(AST_Seq, self, {
car: self.left, car: self.left,
cdr: make_node(AST_False) cdr: make_node(AST_False, self)
}).optimize(compressor); }).optimize(compressor);
} }
if (ll.length > 1 && ll[1]) { if (ll.length > 1 && ll[1]) {
@ -2953,10 +3039,25 @@ merge(Compressor.prototype, {
} }
} }
} }
if (self.operator == "+" && self.right instanceof AST_String if (self.operator == "+") {
&& self.right.getValue() === "" && self.left instanceof AST_Binary if (self.right instanceof AST_String
&& self.left.operator == "+" && self.left.is_string(compressor)) { && self.right.getValue() == ""
return self.left; && self.left.is_string(compressor)) {
return self.left;
}
if (self.left instanceof AST_String
&& self.left.getValue() == ""
&& self.right.is_string(compressor)) {
return self.right;
}
if (self.left instanceof AST_Binary
&& self.left.operator == "+"
&& self.left.left instanceof AST_String
&& self.left.left.getValue() == ""
&& self.right.is_string(compressor)) {
self.left = self.left.right;
return self.transform(compressor);
}
} }
if (compressor.option("evaluate")) { if (compressor.option("evaluate")) {
switch (self.operator) { switch (self.operator) {
@ -3081,9 +3182,9 @@ merge(Compressor.prototype, {
} }
if (compressor.option("evaluate") && compressor.option("reduce_vars")) { if (compressor.option("evaluate") && compressor.option("reduce_vars")) {
var d = self.definition(); var d = self.definition();
if (!d.modified && d.init) { if (d.fixed) {
if (d.should_replace === undefined) { if (d.should_replace === undefined) {
var init = d.init.evaluate(compressor); var init = d.fixed.evaluate(compressor);
if (init.length > 1) { if (init.length > 1) {
var value = init[0].print_to_string().length; var value = init[0].print_to_string().length;
var name = d.name.length; var name = d.name.length;

View File

@ -185,7 +185,7 @@ function push_uniq(array, el) {
function string_template(text, props) { function string_template(text, props) {
return text.replace(/\{(.+?)\}/g, function(str, p){ return text.replace(/\{(.+?)\}/g, function(str, p){
return props[p]; return props && props[p];
}); });
}; };

View File

@ -4,7 +4,7 @@
"homepage": "http://lisperator.net/uglifyjs", "homepage": "http://lisperator.net/uglifyjs",
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)", "author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"version": "2.8.1", "version": "2.8.4",
"engines": { "engines": {
"node": ">=0.8.0" "node": ">=0.8.0"
}, },

View File

@ -1141,7 +1141,7 @@ collapse_vars_constants: {
function f3(x) { function f3(x) {
var b = x.prop; var b = x.prop;
sideeffect1(); sideeffect1();
return b + (function() { return -9; })(); return b + -9;
} }
} }
} }

View File

@ -164,3 +164,53 @@ concat_6: {
); );
} }
} }
concat_7: {
input: {
console.log(
"" + 1,
"" + "1",
"" + 1 + 2,
"" + 1 + "2",
"" + "1" + 2,
"" + "1" + "2",
"" + (x += "foo")
);
}
expect: {
console.log(
"" + 1,
"1",
"" + 1 + 2,
1 + "2",
"1" + 2,
"1" + "2",
x += "foo"
);
}
}
concat_8: {
input: {
console.log(
1 + "",
"1" + "",
1 + 2 + "",
1 + "2" + "",
"1" + 2 + "",
"1" + "2" + "",
(x += "foo") + ""
);
}
expect: {
console.log(
1 + "",
"1",
1 + 2 + "",
1 + "2",
"1" + 2,
"1" + "2",
x += "foo"
);
}
}

View File

@ -337,6 +337,32 @@ unsafe_object_repeated: {
} }
} }
unsafe_object_accessor: {
options = {
evaluate: true,
reduce_vars: true,
unsafe: true,
}
input: {
function f() {
var a = {
get b() {},
set b() {}
};
return {a:a};
}
}
expect: {
function f() {
var a = {
get b() {},
set b() {}
};
return {a:a};
}
}
}
unsafe_function: { unsafe_function: {
options = { options = {
evaluate : true, evaluate : true,
@ -620,6 +646,29 @@ call_args: {
} }
} }
call_args_drop_param: {
options = {
evaluate: true,
keep_fargs: false,
reduce_vars: true,
unused: true,
}
input: {
const a = 1;
console.log(a);
+function(a) {
return a;
}(a, b);
}
expect: {
const a = 1;
console.log(1);
+function() {
return 1;
}(b);
}
}
in_boolean_context: { in_boolean_context: {
options = { options = {
booleans: true, booleans: true,

View File

@ -6,3 +6,71 @@ non_ascii_function_identifier_name: {
} }
expect_exact: "function fooλ(δλ){}function λ(δλ){}(function λ(δλ){})();" expect_exact: "function fooλ(δλ){}function λ(δλ){}(function λ(δλ){})();"
} }
iifes_returning_constants_keep_fargs_true: {
options = {
keep_fargs : true,
side_effects : true,
evaluate : true,
unused : true,
dead_code : true,
conditionals : true,
comparisons : true,
booleans : true,
if_return : true,
join_vars : true,
reduce_vars : true,
cascade : true,
}
input: {
(function(){ return -1.23; }());
console.log( function foo(){ return "okay"; }() );
console.log( function foo(x, y, z){ return 123; }() );
console.log( function(x, y, z){ return z; }() );
console.log( function(x, y, z){ if (x) return y; return z; }(1, 2, 3) );
console.log( function(x, y){ return x * y; }(2, 3) );
console.log( function(x, y){ return x * y; }(2, 3, a(), b()) );
}
expect: {
console.log("okay");
console.log(123);
console.log(void 0);
console.log(function(x,y,z){return 2}(1,2,3));
console.log(function(x,y){return 6}(2,3));
console.log(function(x, y){return 6}(2,3,a(),b()));
}
}
iifes_returning_constants_keep_fargs_false: {
options = {
keep_fargs : false,
side_effects : true,
evaluate : true,
unused : true,
dead_code : true,
conditionals : true,
comparisons : true,
booleans : true,
if_return : true,
join_vars : true,
reduce_vars : true,
cascade : true,
}
input: {
(function(){ return -1.23; }());
console.log( function foo(){ return "okay"; }() );
console.log( function foo(x, y, z){ return 123; }() );
console.log( function(x, y, z){ return z; }() );
console.log( function(x, y, z){ if (x) return y; return z; }(1, 2, 3) );
console.log( function(x, y){ return x * y; }(2, 3) );
console.log( function(x, y){ return x * y; }(2, 3, a(), b()) );
}
expect: {
console.log("okay");
console.log(123);
console.log(void 0);
console.log(2);
console.log(6);
console.log(function(){return 6}(a(),b()));
}
}

View File

@ -38,10 +38,10 @@ negate_iife_3: {
conditionals: true conditionals: true
}; };
input: { input: {
(function(){ return true })() ? console.log(true) : console.log(false); (function(){ return t })() ? console.log(true) : console.log(false);
} }
expect: { expect: {
!function(){ return true }() ? console.log(false) : console.log(true); !function(){ return t }() ? console.log(false) : console.log(true);
} }
} }
@ -51,10 +51,10 @@ negate_iife_3_off: {
conditionals: true, conditionals: true,
}; };
input: { input: {
(function(){ return true })() ? console.log(true) : console.log(false); (function(){ return t })() ? console.log(true) : console.log(false);
} }
expect: { expect: {
!function(){ return true }() ? console.log(false) : console.log(true); !function(){ return t }() ? console.log(false) : console.log(true);
} }
} }
@ -65,13 +65,13 @@ negate_iife_4: {
sequences: true sequences: true
}; };
input: { input: {
(function(){ return true })() ? console.log(true) : console.log(false); (function(){ return t })() ? console.log(true) : console.log(false);
(function(){ (function(){
console.log("something"); console.log("something");
})(); })();
} }
expect: { expect: {
!function(){ return true }() ? console.log(false) : console.log(true), function(){ !function(){ return t }() ? console.log(false) : console.log(true), function(){
console.log("something"); console.log("something");
}(); }();
} }
@ -86,7 +86,7 @@ sequence_off: {
}; };
input: { input: {
function f() { function f() {
(function(){ return true })() ? console.log(true) : console.log(false); (function(){ return t })() ? console.log(true) : console.log(false);
(function(){ (function(){
console.log("something"); console.log("something");
})(); })();
@ -95,19 +95,19 @@ sequence_off: {
(function(){ (function(){
console.log("something"); console.log("something");
})(); })();
(function(){ return true })() ? console.log(true) : console.log(false); (function(){ return t })() ? console.log(true) : console.log(false);
} }
} }
expect: { expect: {
function f() { function f() {
!function(){ return true }() ? console.log(false) : console.log(true), function(){ !function(){ return t }() ? console.log(false) : console.log(true), function(){
console.log("something"); console.log("something");
}(); }();
} }
function g() { function g() {
(function(){ (function(){
console.log("something"); console.log("something");
})(), function(){ return true }() ? console.log(true) : console.log(false); })(), function(){ return t }() ? console.log(true) : console.log(false);
} }
} }
} }
@ -119,7 +119,7 @@ negate_iife_5: {
conditionals: true, conditionals: true,
}; };
input: { input: {
if ((function(){ return true })()) { if ((function(){ return t })()) {
foo(true); foo(true);
} else { } else {
bar(false); bar(false);
@ -129,7 +129,7 @@ negate_iife_5: {
})(); })();
} }
expect: { expect: {
!function(){ return true }() ? bar(false) : foo(true), function(){ !function(){ return t }() ? bar(false) : foo(true), function(){
console.log("something"); console.log("something");
}(); }();
} }
@ -142,7 +142,7 @@ negate_iife_5_off: {
conditionals: true, conditionals: true,
}; };
input: { input: {
if ((function(){ return true })()) { if ((function(){ return t })()) {
foo(true); foo(true);
} else { } else {
bar(false); bar(false);
@ -152,7 +152,7 @@ negate_iife_5_off: {
})(); })();
} }
expect: { expect: {
!function(){ return true }() ? bar(false) : foo(true), function(){ !function(){ return t }() ? bar(false) : foo(true), function(){
console.log("something"); console.log("something");
}(); }();
} }

View File

@ -470,3 +470,122 @@ multi_def_2: {
var repeatLength = this.getBits(bitsLength) + bitsOffset; var repeatLength = this.getBits(bitsLength) + bitsOffset;
} }
} }
use_before_var: {
options = {
evaluate: true,
reduce_vars: true,
}
input: {
console.log(t);
var t = 1;
}
expect: {
console.log(t);
var t = 1;
}
}
inner_var_if: {
options = {
evaluate: true,
reduce_vars: true,
}
input: {
function f(){
return 0;
}
if (f())
var t = 1;
if (!t)
console.log(t);
}
expect: {
function f(){
return 0;
}
if (f())
var t = 1;
if (!t)
console.log(t);
}
}
inner_var_label: {
options = {
evaluate: true,
reduce_vars: true,
}
input: {
function f(){
return 1;
}
l: {
if (f()) break l;
var t = 1;
}
console.log(t);
}
expect: {
function f(){
return 1;
}
l: {
if (f()) break l;
var t = 1;
}
console.log(t);
}
}
inner_var_for: {
options = {
evaluate: true,
reduce_vars: true,
}
input: {
var a = 1;
x(a, b, d);
for (var b = 2, c = 3; x(a, b, c, d); x(a, b, c, d)) {
var d = 4, e = 5;
x(a, b, c, d, e);
}
x(a, b, c, d, e)
}
expect: {
var a = 1;
x(1, b, d);
for (var b = 2, c = 3; x(1, b, 3, d); x(1, b, 3, d)) {
var d = 4, e = 5;
x(1, b, 3, d, e);
}
x(1, b, 3, d, e);
}
}
inner_var_for_in: {
options = {
evaluate: true,
reduce_vars: true,
}
input: {
var a = 1, b = 2;
for (b in (function() {
return x(a, b, c);
})()) {
var c = 3, d = 4;
x(a, b, c, d);
}
x(a, b, c, d);
}
expect: {
var a = 1, b = 2;
for (b in (function() {
return x(1, b, c);
})()) {
var c = 3, d = 4;
x(1, b, c, d);
}
x(1, b, c, d);
}
}

View File

@ -155,7 +155,7 @@ describe("minify", function() {
assert.strictEqual(code, "// comment1 comment2\nbar();"); assert.strictEqual(code, "// comment1 comment2\nbar();");
}); });
it("should not drop #__PURE__ hint if function is retained", function() { it("should not drop #__PURE__ hint if function is retained", function() {
var result = Uglify.minify("var a = /*#__PURE__*/(function(){return 1})();", { var result = Uglify.minify("var a = /*#__PURE__*/(function(){ foo(); })();", {
fromString: true, fromString: true,
output: { output: {
comments: "all", comments: "all",
@ -163,7 +163,7 @@ describe("minify", function() {
} }
}); });
var code = result.code; var code = result.code;
assert.strictEqual(code, "var a=/*#__PURE__*/function(){return 1}();"); assert.strictEqual(code, "var a=/*#__PURE__*/function(){foo()}();");
}) })
}); });
@ -182,4 +182,13 @@ describe("minify", function() {
}); });
}); });
describe("Compressor", function() {
it("should be backward compatible with ast.transform(compressor)", function() {
var ast = Uglify.parse("function f(a){for(var i=0;i<a;i++)console.log(i)}");
ast.figure_out_scope();
ast = ast.transform(Uglify.Compressor());
assert.strictEqual(ast.print_to_string(), "function f(a){for(var i=0;i<a;i++)console.log(i)}");
});
})
}); });