@@ -218,12 +218,16 @@ impl<'a> PeepholeOptimizations {
218218 let consequent = Self :: get_block_expression ( & mut if_stmt. consequent , ctx) ;
219219 let else_branch = if_stmt. alternate . as_mut ( ) . unwrap ( ) ;
220220 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 (
222222 if_stmt. span ,
223223 test,
224224 consequent,
225225 alternate,
226226 ) ;
227+ let expr = Self :: try_minimize_conditional ( & mut cond_expr, ctx)
228+ . unwrap_or_else ( || {
229+ Expression :: ConditionalExpression ( ctx. ast . alloc ( cond_expr) )
230+ } ) ;
227231 return Some ( ctx. ast . statement_expression ( if_stmt. span , expr) ) ;
228232 }
229233 }
@@ -281,12 +285,14 @@ impl<'a> PeepholeOptimizations {
281285 let mut if_stmt = if_stmt. unbox ( ) ;
282286 let consequent = Self :: get_block_return_expression ( & mut if_stmt. consequent , ctx) ;
283287 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 (
285289 if_stmt. span ,
286290 if_stmt. test ,
287291 consequent,
288292 alternate,
289293 ) ;
294+ let argument = Self :: try_minimize_conditional ( & mut cond_expr, ctx)
295+ . unwrap_or_else ( || Expression :: ConditionalExpression ( ctx. ast . alloc ( cond_expr) ) ) ;
290296 stmts[ i] = ctx. ast . statement_return ( if_stmt. span , Some ( argument) ) ;
291297 * changed = true ;
292298 break ;
@@ -359,21 +365,6 @@ impl<'a> PeepholeOptimizations {
359365 ctx : & mut TraverseCtx < ' a > ,
360366 ) -> Option < Expression < ' a > > {
361367 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- }
377368 // "(a, b) ? c : d" => "a, b ? c : d"
378369 Expression :: SequenceExpression ( sequence_expr) => {
379370 if sequence_expr. expressions . len ( ) > 1 {
@@ -431,6 +422,21 @@ impl<'a> PeepholeOptimizations {
431422 }
432423 }
433424 }
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+ }
434440 _ => { }
435441 }
436442
@@ -637,62 +643,6 @@ impl<'a> PeepholeOptimizations {
637643
638644 // TODO: Try using the "??" or "?." operators
639645
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-
696646 if expr. alternate . content_eq ( & expr. consequent ) {
697647 // TODO:
698648 // "/* @__PURE__ */ a() ? b : b" => "b"
@@ -1163,11 +1113,11 @@ mod test {
11631113 test ( "(x || false) && y()" , "x && y()" ) ;
11641114
11651115 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 " ) ;
11681118 test ( "function x () { return a ? true : false }" , "function x() { return !!a }" ) ;
11691119 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 }" ) ;
11711121 // can't be minified e.g. `a = ''` would return `''`
11721122 test ( "function x() { return a && true }" , "function x() { return a && !0 }" ) ;
11731123
0 commit comments