@@ -80,6 +80,7 @@ function Compressor(options, false_by_default) {
80
80
screw_ie8 : true ,
81
81
drop_console : false ,
82
82
angular : false ,
83
+ expression : false ,
83
84
warnings : true ,
84
85
global_defs : { } ,
85
86
passes : 1 ,
@@ -116,12 +117,18 @@ Compressor.prototype = new TreeTransformer;
116
117
merge ( Compressor . prototype , {
117
118
option : function ( key ) { return this . options [ key ] } ,
118
119
compress : function ( node ) {
120
+ if ( this . option ( "expression" ) ) {
121
+ node = node . process_expression ( true ) ;
122
+ }
119
123
var passes = + this . options . passes || 1 ;
120
124
for ( var pass = 0 ; pass < passes && pass < 3 ; ++ pass ) {
121
125
if ( pass > 0 || this . option ( "reduce_vars" ) )
122
126
node . reset_opt_flags ( this , true ) ;
123
127
node = node . transform ( this ) ;
124
128
}
129
+ if ( this . option ( "expression" ) ) {
130
+ node = node . process_expression ( false ) ;
131
+ }
125
132
return node ;
126
133
} ,
127
134
warn : function ( text , props ) {
@@ -178,6 +185,42 @@ merge(Compressor.prototype, {
178
185
return this . print_to_string ( ) == node . print_to_string ( ) ;
179
186
} ) ;
180
187
188
+ AST_Node . DEFMETHOD ( "process_expression" , function ( insert ) {
189
+ var self = this ;
190
+ var tt = new TreeTransformer ( function ( node ) {
191
+ if ( insert && node instanceof AST_SimpleStatement ) {
192
+ return make_node ( AST_Return , node , {
193
+ value : node . body
194
+ } ) ;
195
+ }
196
+ if ( ! insert && node instanceof AST_Return ) {
197
+ return make_node ( AST_SimpleStatement , node , {
198
+ body : node . value || make_node ( AST_Undefined , node )
199
+ } ) ;
200
+ }
201
+ if ( node instanceof AST_Lambda && node !== self ) {
202
+ return node ;
203
+ }
204
+ if ( node instanceof AST_Block ) {
205
+ var index = node . body . length - 1 ;
206
+ if ( index >= 0 ) {
207
+ node . body [ index ] = node . body [ index ] . transform ( tt ) ;
208
+ }
209
+ }
210
+ if ( node instanceof AST_If ) {
211
+ node . body = node . body . transform ( tt ) ;
212
+ if ( node . alternative ) {
213
+ node . alternative = node . alternative . transform ( tt ) ;
214
+ }
215
+ }
216
+ if ( node instanceof AST_With ) {
217
+ node . body = node . body . transform ( tt ) ;
218
+ }
219
+ return node ;
220
+ } ) ;
221
+ return self . transform ( tt ) ;
222
+ } ) ;
223
+
181
224
AST_Node . DEFMETHOD ( "reset_opt_flags" , function ( compressor , rescan ) {
182
225
var reduce_vars = rescan && compressor . option ( "reduce_vars" ) ;
183
226
var safe_ids = [ ] ;
@@ -2030,7 +2073,14 @@ merge(Compressor.prototype, {
2030
2073
def ( AST_Constant , return_null ) ;
2031
2074
def ( AST_This , return_null ) ;
2032
2075
def ( AST_Call , function ( compressor , first_in_statement ) {
2033
- if ( ! this . has_pure_annotation ( compressor ) && compressor . pure_funcs ( this ) ) return this ;
2076
+ if ( ! this . has_pure_annotation ( compressor ) && compressor . pure_funcs ( this ) ) {
2077
+ if ( this . expression instanceof AST_Function ) {
2078
+ var node = this . clone ( ) ;
2079
+ node . expression = node . expression . process_expression ( false ) ;
2080
+ return node ;
2081
+ }
2082
+ return this ;
2083
+ }
2034
2084
if ( this . pure ) {
2035
2085
compressor . warn ( "Dropping __PURE__ call [{file}:{line},{col}]" , this . start ) ;
2036
2086
this . pure . value = this . pure . value . replace ( / [ @ # ] _ _ P U R E _ _ / g, ' ' ) ;
@@ -2522,12 +2572,13 @@ merge(Compressor.prototype, {
2522
2572
} ) ;
2523
2573
2524
2574
OPT ( AST_Call , function ( self , compressor ) {
2575
+ var exp = self . expression ;
2525
2576
if ( compressor . option ( "unused" )
2526
- && self . expression instanceof AST_Function
2527
- && ! self . expression . uses_arguments
2528
- && ! self . expression . uses_eval
2529
- && self . args . length > self . expression . argnames . length ) {
2530
- var end = self . expression . argnames . length ;
2577
+ && exp instanceof AST_Function
2578
+ && ! exp . uses_arguments
2579
+ && ! exp . uses_eval
2580
+ && self . args . length > exp . argnames . length ) {
2581
+ var end = exp . argnames . length ;
2531
2582
for ( var i = end , len = self . args . length ; i < len ; i ++ ) {
2532
2583
var node = self . args [ i ] . drop_side_effect_free ( compressor ) ;
2533
2584
if ( node ) {
@@ -2537,7 +2588,6 @@ merge(Compressor.prototype, {
2537
2588
self . args . length = end ;
2538
2589
}
2539
2590
if ( compressor . option ( "unsafe" ) ) {
2540
- var exp = self . expression ;
2541
2591
if ( exp instanceof AST_SymbolRef && exp . undeclared ( ) ) {
2542
2592
switch ( exp . name ) {
2543
2593
case "Array" :
@@ -2711,16 +2761,22 @@ merge(Compressor.prototype, {
2711
2761
return best_of ( self , node ) ;
2712
2762
}
2713
2763
}
2714
- if ( compressor . option ( "side_effects" ) ) {
2715
- if ( self . expression instanceof AST_Function
2716
- && self . args . length == 0
2717
- && ! AST_Block . prototype . has_side_effects . call ( self . expression , compressor ) ) {
2718
- return make_node ( AST_Undefined , self ) . transform ( compressor ) ;
2764
+ if ( exp instanceof AST_Function ) {
2765
+ if ( exp . body [ 0 ] instanceof AST_Return
2766
+ && exp . body [ 0 ] . value . is_constant ( ) ) {
2767
+ var args = self . args . concat ( exp . body [ 0 ] . value ) ;
2768
+ return AST_Seq . from_array ( args ) . transform ( compressor ) ;
2769
+ }
2770
+ if ( compressor . option ( "side_effects" ) ) {
2771
+ if ( ! AST_Block . prototype . has_side_effects . call ( exp , compressor ) ) {
2772
+ var args = self . args . concat ( make_node ( AST_Undefined , self ) ) ;
2773
+ return AST_Seq . from_array ( args ) . transform ( compressor ) ;
2774
+ }
2719
2775
}
2720
2776
}
2721
2777
if ( compressor . option ( "drop_console" ) ) {
2722
- if ( self . expression instanceof AST_PropAccess ) {
2723
- var name = self . expression . expression ;
2778
+ if ( exp instanceof AST_PropAccess ) {
2779
+ var name = exp . expression ;
2724
2780
while ( name . expression ) {
2725
2781
name = name . expression ;
2726
2782
}
@@ -2731,12 +2787,6 @@ merge(Compressor.prototype, {
2731
2787
}
2732
2788
}
2733
2789
}
2734
- if ( self . args . length == 0
2735
- && self . expression instanceof AST_Function
2736
- && self . expression . body [ 0 ] instanceof AST_Return
2737
- && self . expression . body [ 0 ] . value . is_constant ( ) ) {
2738
- return self . expression . body [ 0 ] . value ;
2739
- }
2740
2790
if ( compressor . option ( "negate_iife" )
2741
2791
&& compressor . parent ( ) instanceof AST_SimpleStatement
2742
2792
&& is_iife_call ( self ) ) {
0 commit comments