Move support for negate_iife in the compressor, rather than code generator
(the code generator doesn't maintain enough context to know whether the return value is important or discarded) Fixes #272
This commit is contained in:
@@ -209,6 +209,9 @@ to set `true`; it's effectively a shortcut for `foo=true`).
|
|||||||
and `x = something(), x` into `x = something()`
|
and `x = something(), x` into `x = something()`
|
||||||
- `warnings` -- display warnings when dropping unreachable code or unused
|
- `warnings` -- display warnings when dropping unreachable code or unused
|
||||||
declarations etc.
|
declarations etc.
|
||||||
|
- `negate_iife` -- negate "Immediately-Called Function Expressions"
|
||||||
|
where the return value is discarded, to avoid the parens that the
|
||||||
|
code generator would insert.
|
||||||
|
|
||||||
### The `unsafe` option
|
### The `unsafe` option
|
||||||
|
|
||||||
@@ -296,10 +299,6 @@ can pass additional arguments that control the code output:
|
|||||||
you pass `false` then whenever possible we will use a newline instead of a
|
you pass `false` then whenever possible we will use a newline instead of a
|
||||||
semicolon, leading to more readable output of uglified code (size before
|
semicolon, leading to more readable output of uglified code (size before
|
||||||
gzip could be smaller; size after gzip insignificantly larger).
|
gzip could be smaller; size after gzip insignificantly larger).
|
||||||
- `negate-iife` (default `!beautify`) -- prefer negation, rather than
|
|
||||||
parens, for "Immediately-Called Function Expressions". This defaults to
|
|
||||||
`true` when beautification is off, and `false` if beautification is on;
|
|
||||||
pass it manually to force a value.
|
|
||||||
|
|
||||||
### Keeping copyright notices or other comments
|
### Keeping copyright notices or other comments
|
||||||
|
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ function Compressor(options, false_by_default) {
|
|||||||
join_vars : !false_by_default,
|
join_vars : !false_by_default,
|
||||||
cascade : !false_by_default,
|
cascade : !false_by_default,
|
||||||
side_effects : !false_by_default,
|
side_effects : !false_by_default,
|
||||||
|
negate_iife : !false_by_default,
|
||||||
screw_ie8 : false,
|
screw_ie8 : false,
|
||||||
|
|
||||||
warnings : true,
|
warnings : true,
|
||||||
@@ -214,6 +215,11 @@ merge(Compressor.prototype, {
|
|||||||
statements = join_consecutive_vars(statements, compressor);
|
statements = join_consecutive_vars(statements, compressor);
|
||||||
}
|
}
|
||||||
} while (CHANGED);
|
} while (CHANGED);
|
||||||
|
|
||||||
|
if (compressor.option("negate_iife")) {
|
||||||
|
negate_iifes(statements, compressor);
|
||||||
|
}
|
||||||
|
|
||||||
return statements;
|
return statements;
|
||||||
|
|
||||||
function eliminate_spurious_blocks(statements) {
|
function eliminate_spurious_blocks(statements) {
|
||||||
@@ -497,6 +503,40 @@ merge(Compressor.prototype, {
|
|||||||
}, []);
|
}, []);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function negate_iifes(statements, compressor) {
|
||||||
|
statements.forEach(function(stat){
|
||||||
|
if (stat instanceof AST_SimpleStatement) {
|
||||||
|
stat.body = (function transform(thing) {
|
||||||
|
return thing.transform(new TreeTransformer(function(node){
|
||||||
|
if (node instanceof AST_Call && node.expression instanceof AST_Function) {
|
||||||
|
return make_node(AST_UnaryPrefix, node, {
|
||||||
|
operator: "!",
|
||||||
|
expression: node
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (node instanceof AST_Call) {
|
||||||
|
node.expression = transform(node.expression);
|
||||||
|
}
|
||||||
|
else if (node instanceof AST_Seq) {
|
||||||
|
node.car = transform(node.car);
|
||||||
|
}
|
||||||
|
else if (node instanceof AST_Conditional) {
|
||||||
|
var expr = transform(node.condition);
|
||||||
|
if (expr !== node.condition) {
|
||||||
|
// it has been negated, reverse
|
||||||
|
node.condition = expr;
|
||||||
|
var tmp = node.consequent;
|
||||||
|
node.consequent = node.alternative;
|
||||||
|
node.alternative = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}));
|
||||||
|
})(stat.body);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function extract_declarations_from_unreachable_code(compressor, stat, target) {
|
function extract_declarations_from_unreachable_code(compressor, stat, target) {
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ function OutputStream(options) {
|
|||||||
comments : false,
|
comments : false,
|
||||||
preserve_line : false,
|
preserve_line : false,
|
||||||
screw_ie8 : false,
|
screw_ie8 : false,
|
||||||
negate_iife : !(options && options.beautify),
|
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
var indentation = 0;
|
var indentation = 0;
|
||||||
@@ -351,20 +350,16 @@ function OutputStream(options) {
|
|||||||
|
|
||||||
AST_Node.DEFMETHOD("print", function(stream, force_parens){
|
AST_Node.DEFMETHOD("print", function(stream, force_parens){
|
||||||
var self = this, generator = self._codegen;
|
var self = this, generator = self._codegen;
|
||||||
|
function doit() {
|
||||||
|
self.add_comments(stream);
|
||||||
|
self.add_source_map(stream);
|
||||||
|
generator(self, stream);
|
||||||
|
}
|
||||||
stream.push_node(self);
|
stream.push_node(self);
|
||||||
var needs_parens = self.needs_parens(stream);
|
if (force_parens || self.needs_parens(stream)) {
|
||||||
var fc = self instanceof AST_Function && stream.option("negate_iife");
|
stream.with_parens(doit);
|
||||||
if (force_parens || (needs_parens && !fc)) {
|
|
||||||
stream.with_parens(function(){
|
|
||||||
self.add_comments(stream);
|
|
||||||
self.add_source_map(stream);
|
|
||||||
generator(self, stream);
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
self.add_comments(stream);
|
doit();
|
||||||
if (needs_parens && fc) stream.print("!");
|
|
||||||
self.add_source_map(stream);
|
|
||||||
generator(self, stream);
|
|
||||||
}
|
}
|
||||||
stream.pop_node();
|
stream.pop_node();
|
||||||
});
|
});
|
||||||
|
|||||||
76
test/compress/negate-iife.js
Normal file
76
test/compress/negate-iife.js
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
negate_iife_1: {
|
||||||
|
options = {
|
||||||
|
negate_iife: true
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
(function(){ stuff() })();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function(){ stuff() }();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
negate_iife_2: {
|
||||||
|
options = {
|
||||||
|
negate_iife: true
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
(function(){ return {} })().x = 10; // should not transform this one
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(){ return {} })().x = 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
negate_iife_3: {
|
||||||
|
options = {
|
||||||
|
negate_iife: true,
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
(function(){ return true })() ? console.log(true) : console.log(false);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function(){ return true }() ? console.log(false) : console.log(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
negate_iife_3: {
|
||||||
|
options = {
|
||||||
|
negate_iife: true,
|
||||||
|
sequences: true
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
(function(){ return true })() ? console.log(true) : console.log(false);
|
||||||
|
(function(){
|
||||||
|
console.log("something");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function(){ return true }() ? console.log(false) : console.log(true), function(){
|
||||||
|
console.log("something");
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
negate_iife_4: {
|
||||||
|
options = {
|
||||||
|
negate_iife: true,
|
||||||
|
sequences: true,
|
||||||
|
conditionals: true,
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
if ((function(){ return true })()) {
|
||||||
|
console.log(true);
|
||||||
|
} else {
|
||||||
|
console.log(false);
|
||||||
|
}
|
||||||
|
(function(){
|
||||||
|
console.log("something");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function(){ return true }() ? console.log(false) : console.log(true), function(){
|
||||||
|
console.log("something");
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user