@@ -218,12 +218,16 @@ impl<'a> PeepholeOptimizations {
218
218
let consequent = Self :: get_block_expression ( & mut if_stmt. consequent , ctx) ;
219
219
let else_branch = if_stmt. alternate . as_mut ( ) . unwrap ( ) ;
220
220
let alternate = Self :: get_block_expression ( else_branch, ctx) ;
221
- let expr = ctx. ast . expression_conditional (
221
+ let mut cond_expr = ctx. ast . conditional_expression (
222
222
if_stmt. span ,
223
223
test,
224
224
consequent,
225
225
alternate,
226
226
) ;
227
+ let expr = Self :: try_minimize_conditional ( & mut cond_expr, ctx)
228
+ . unwrap_or_else ( || {
229
+ Expression :: ConditionalExpression ( ctx. ast . alloc ( cond_expr) )
230
+ } ) ;
227
231
return Some ( ctx. ast . statement_expression ( if_stmt. span , expr) ) ;
228
232
}
229
233
}
@@ -281,12 +285,14 @@ impl<'a> PeepholeOptimizations {
281
285
let mut if_stmt = if_stmt. unbox ( ) ;
282
286
let consequent = Self :: get_block_return_expression ( & mut if_stmt. consequent , ctx) ;
283
287
let alternate = Self :: take_return_argument ( & mut stmts[ i + 1 ] , ctx) ;
284
- let argument = ctx. ast . expression_conditional (
288
+ let mut cond_expr = ctx. ast . conditional_expression (
285
289
if_stmt. span ,
286
290
if_stmt. test ,
287
291
consequent,
288
292
alternate,
289
293
) ;
294
+ let argument = Self :: try_minimize_conditional ( & mut cond_expr, ctx)
295
+ . unwrap_or_else ( || Expression :: ConditionalExpression ( ctx. ast . alloc ( cond_expr) ) ) ;
290
296
stmts[ i] = ctx. ast . statement_return ( if_stmt. span , Some ( argument) ) ;
291
297
* changed = true ;
292
298
break ;
@@ -359,21 +365,6 @@ impl<'a> PeepholeOptimizations {
359
365
ctx : & mut TraverseCtx < ' a > ,
360
366
) -> Option < Expression < ' a > > {
361
367
match & mut expr. test {
362
- // `x != y ? b : c` -> `x == y ? c : b`
363
- Expression :: BinaryExpression ( test_expr) => {
364
- if matches ! (
365
- test_expr. operator,
366
- BinaryOperator :: Inequality | BinaryOperator :: StrictInequality
367
- ) {
368
- test_expr. operator = test_expr. operator . equality_inverse_operator ( ) . unwrap ( ) ;
369
- let test = ctx. ast . move_expression ( & mut expr. test ) ;
370
- let consequent = ctx. ast . move_expression ( & mut expr. consequent ) ;
371
- let alternate = ctx. ast . move_expression ( & mut expr. alternate ) ;
372
- return Some (
373
- ctx. ast . expression_conditional ( expr. span , test, alternate, consequent) ,
374
- ) ;
375
- }
376
- }
377
368
// "(a, b) ? c : d" => "a, b ? c : d"
378
369
Expression :: SequenceExpression ( sequence_expr) => {
379
370
if sequence_expr. expressions . len ( ) > 1 {
@@ -431,6 +422,21 @@ impl<'a> PeepholeOptimizations {
431
422
}
432
423
}
433
424
}
425
+ // `x != y ? b : c` -> `x == y ? c : b`
426
+ Expression :: BinaryExpression ( test_expr) => {
427
+ if matches ! (
428
+ test_expr. operator,
429
+ BinaryOperator :: Inequality | BinaryOperator :: StrictInequality
430
+ ) {
431
+ test_expr. operator = test_expr. operator . equality_inverse_operator ( ) . unwrap ( ) ;
432
+ let test = ctx. ast . move_expression ( & mut expr. test ) ;
433
+ let consequent = ctx. ast . move_expression ( & mut expr. consequent ) ;
434
+ let alternate = ctx. ast . move_expression ( & mut expr. alternate ) ;
435
+ return Some (
436
+ ctx. ast . expression_conditional ( expr. span , test, alternate, consequent) ,
437
+ ) ;
438
+ }
439
+ }
434
440
_ => { }
435
441
}
436
442
@@ -637,62 +643,6 @@ impl<'a> PeepholeOptimizations {
637
643
638
644
// TODO: Try using the "??" or "?." operators
639
645
640
- // Non esbuild optimizations
641
-
642
- // `x ? true : y` -> `x || y`
643
- // `x ? false : y` -> `!x && y`
644
- if let ( Expression :: Identifier ( _) , Expression :: BooleanLiteral ( consequent_lit) , _) =
645
- ( & expr. test , & expr. consequent , & expr. alternate )
646
- {
647
- if consequent_lit. value {
648
- let ident = ctx. ast . move_expression ( & mut expr. test ) ;
649
- return Some ( ctx. ast . expression_logical (
650
- expr. span ,
651
- ctx. ast . expression_unary (
652
- ident. span ( ) ,
653
- UnaryOperator :: LogicalNot ,
654
- ctx. ast . expression_unary ( ident. span ( ) , UnaryOperator :: LogicalNot , ident) ,
655
- ) ,
656
- LogicalOperator :: Or ,
657
- ctx. ast . move_expression ( & mut expr. alternate ) ,
658
- ) ) ;
659
- }
660
- let ident = ctx. ast . move_expression ( & mut expr. test ) ;
661
- return Some ( ctx. ast . expression_logical (
662
- expr. span ,
663
- ctx. ast . expression_unary ( expr. span , UnaryOperator :: LogicalNot , ident) ,
664
- LogicalOperator :: And ,
665
- ctx. ast . move_expression ( & mut expr. alternate ) ,
666
- ) ) ;
667
- }
668
-
669
- // `x ? y : true` -> `!x || y`
670
- // `x ? y : false` -> `x && y`
671
- if let ( Expression :: Identifier ( _) , _, Expression :: BooleanLiteral ( alternate_lit) ) =
672
- ( & expr. test , & expr. consequent , & expr. alternate )
673
- {
674
- if alternate_lit. value {
675
- let ident = ctx. ast . move_expression ( & mut expr. test ) ;
676
- return Some ( ctx. ast . expression_logical (
677
- expr. span ,
678
- ctx. ast . expression_unary ( expr. span , UnaryOperator :: LogicalNot , ident) ,
679
- LogicalOperator :: Or ,
680
- ctx. ast . move_expression ( & mut expr. consequent ) ,
681
- ) ) ;
682
- }
683
- let ident = ctx. ast . move_expression ( & mut expr. test ) ;
684
- return Some ( ctx. ast . expression_logical (
685
- expr. span ,
686
- ctx. ast . expression_unary (
687
- expr. span ,
688
- UnaryOperator :: LogicalNot ,
689
- ctx. ast . expression_unary ( ident. span ( ) , UnaryOperator :: LogicalNot , ident) ,
690
- ) ,
691
- LogicalOperator :: And ,
692
- ctx. ast . move_expression ( & mut expr. consequent ) ,
693
- ) ) ;
694
- }
695
-
696
646
if expr. alternate . content_eq ( & expr. consequent ) {
697
647
// TODO:
698
648
// "/* @__PURE__ */ a() ? b : b" => "b"
@@ -1163,11 +1113,11 @@ mod test {
1163
1113
test ( "(x || false) && y()" , "x && y()" ) ;
1164
1114
1165
1115
test ( "let x = foo ? true : false" , "let x = !!foo" ) ;
1166
- test ( "let x = foo ? true : bar" , "let x = !! foo || bar" ) ;
1167
- test ( "let x = foo ? bar : false" , "let x = !! foo && bar" ) ;
1116
+ test ( "let x = foo ? true : bar" , "let x = foo ? !0 : bar" ) ;
1117
+ test ( "let x = foo ? bar : false" , "let x = foo ? bar : !1 " ) ;
1168
1118
test ( "function x () { return a ? true : false }" , "function x() { return !!a }" ) ;
1169
1119
test ( "function x () { return a ? false : true }" , "function x() { return !a }" ) ;
1170
- test ( "function x () { return a ? true : b }" , "function x() { return !!a || b }" ) ;
1120
+ test ( "function x () { return a ? true : b }" , "function x() { return a ? !0 : b }" ) ;
1171
1121
// can't be minified e.g. `a = ''` would return `''`
1172
1122
test ( "function x() { return a && true }" , "function x() { return a && !0 }" ) ;
1173
1123
0 commit comments