and `x = something(), x` into `x = something()`
- `warnings` -- display warnings when dropping unreachable code or unused
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
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
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
join_vars : !false_by_default,
cascade : !false_by_default,
side_effects : !false_by_default,
+ negate_iife : !false_by_default,
screw_ie8 : false,
warnings : true,
statements = join_consecutive_vars(statements, compressor);
}
} while (CHANGED);
+
+ if (compressor.option("negate_iife")) {
+ negate_iifes(statements, compressor);
+ }
+
return statements;
function eliminate_spurious_blocks(statements) {
}, []);
};
+ 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) {
comments : false,
preserve_line : false,
screw_ie8 : false,
- negate_iife : !(options && options.beautify),
}, true);
var indentation = 0;
AST_Node.DEFMETHOD("print", function(stream, force_parens){
var self = this, generator = self._codegen;
- stream.push_node(self);
- var needs_parens = self.needs_parens(stream);
- var fc = self instanceof AST_Function && stream.option("negate_iife");
- if (force_parens || (needs_parens && !fc)) {
- stream.with_parens(function(){
- self.add_comments(stream);
- self.add_source_map(stream);
- generator(self, stream);
- });
- } else {
+ function doit() {
self.add_comments(stream);
- if (needs_parens && fc) stream.print("!");
self.add_source_map(stream);
generator(self, stream);
}
+ stream.push_node(self);
+ if (force_parens || self.needs_parens(stream)) {
+ stream.with_parens(doit);
+ } else {
+ doit();
+ }
stream.pop_node();
});
--- /dev/null
+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");
+ }();
+ }
+}