@@ -511,31 +511,32 @@ private void removeIfUnnamedBreak(Node maybeBreak) {
511
511
}
512
512
}
513
513
514
- private Node tryRemoveSwitchWithSingleCase (Node n , boolean shouldHoistCondition ) {
515
- Node caseBlock = n .getLastChild ().getLastChild ();
514
+ private Node tryRemoveSwitchWithSingleCase (Node switchNode , boolean shouldHoistCondition ) {
515
+ Node switchBody = switchNode .getSecondChild ();
516
+ Node caseBlock = switchBody .getOnlyChild ().getLastChild ();
516
517
removeIfUnnamedBreak (caseBlock .getLastChild ());
517
518
// Back off if the switch contains statements like "if (a) { break; }"
518
519
if (NodeUtil .has (caseBlock , MATCH_UNNAMED_BREAK , NodeUtil .MATCH_NOT_FUNCTION )) {
519
- return n ;
520
+ return switchNode ;
520
521
}
521
522
if (shouldHoistCondition ) {
522
- Node switchBlock = caseBlock .getGrandparent ();
523
- IR .exprResult (n .removeFirstChild ()).srcref (n ).insertBefore (switchBlock );
523
+ IR .exprResult (switchNode .removeFirstChild ()).srcref (switchNode ).insertBefore (switchNode );
524
524
}
525
- n .replaceWith (caseBlock .detach ());
525
+ switchNode .replaceWith (caseBlock .detach ());
526
526
reportChangeToEnclosingScope (caseBlock );
527
527
return caseBlock ;
528
528
}
529
529
530
530
private Node tryRemoveSwitch (Node n ) {
531
- if (n .hasOneChild ()) {
531
+ Node switchBody = n .getSecondChild ();
532
+ if (!switchBody .hasChildren ()) {
532
533
// Remove the switch if there are no remaining cases
533
534
Node condition = n .removeFirstChild ();
534
535
Node replacement = IR .exprResult (condition ).srcref (n );
535
536
n .replaceWith (replacement );
536
537
reportChangeToEnclosingScope (replacement );
537
538
return replacement ;
538
- } else if (n . hasTwoChildren () && n . getLastChild ().isDefaultCase ()) {
539
+ } else if (switchBody . hasOneChild () && switchBody . getOnlyChild ().isDefaultCase ()) {
539
540
if (n .getFirstChild ().isCall () || n .getFirstChild ().isOptChainCall ()) {
540
541
// Before removing switch, we must preserve the switch condition if it is a call
541
542
return tryRemoveSwitchWithSingleCase (n , true );
@@ -551,16 +552,17 @@ private Node tryRemoveSwitch(Node n) {
551
552
private Node tryOptimizeSwitch (Node n ) {
552
553
checkState (n .isSwitch (), n );
553
554
555
+ Node switchBody = n .getSecondChild ();
554
556
Node defaultCase = tryOptimizeDefaultCase (n );
555
557
556
558
// Generally, it is unsafe to remove other cases when the default case is not the last one.
557
- if (defaultCase == null || n .getLastChild ().isDefaultCase ()) {
559
+ if (defaultCase == null || switchBody .getLastChild ().isDefaultCase ()) {
558
560
Node cond = n .getFirstChild ();
559
561
Node prev = null ;
560
562
Node next = null ;
561
563
Node cur ;
562
564
563
- for (cur = cond . getNext (); cur != null ; cur = next ) {
565
+ for (cur = switchBody . getFirstChild (); cur != null ; cur = next ) {
564
566
next = cur .getNext ();
565
567
if (!mayHaveSideEffects (cur .getFirstChild ()) && isUselessCase (cur , prev , defaultCase )) {
566
568
removeCase (n , cur );
@@ -574,7 +576,7 @@ private Node tryOptimizeSwitch(Node n) {
574
576
Node caseLabel ;
575
577
Tri caseMatches = Tri .TRUE ;
576
578
// Remove cases until you find one that may match
577
- for (cur = cond . getNext (); cur != null ; cur = next ) {
579
+ for (cur = switchBody . getFirstChild (); cur != null ; cur = next ) {
578
580
next = cur .getNext ();
579
581
caseLabel = cur .getFirstChild ();
580
582
caseMatches = PeepholeFoldConstants .evaluateComparison (this , Token .SHEQ , cond , caseLabel );
@@ -637,23 +639,21 @@ private Node tryOptimizeSwitch(Node n) {
637
639
private @ Nullable Node tryOptimizeDefaultCase (Node n ) {
638
640
checkState (n .isSwitch (), n );
639
641
640
- Node lastNonRemovable = n .getFirstChild (); // The switch condition
642
+ Node switchBody = n .getSecondChild ();
643
+ Node lastNonRemovable = null ; // the most recently iterated case known to not be removable.
641
644
642
- // The first child is the switch conditions skip it when looking for cases.
643
- for (Node c = n .getSecondChild (); c != null ; c = c .getNext ()) {
645
+ for (Node c = switchBody .getFirstChild (); c != null ; c = c .getNext ()) {
644
646
if (c .isDefaultCase ()) {
645
- // Remove cases that fall-through to the default case
646
- Node caseToRemove = lastNonRemovable .getNext ();
647
+ // Remove any cases that fall-through to the default case
648
+ Node caseToRemove =
649
+ lastNonRemovable != null ? lastNonRemovable .getNext () : switchBody .getFirstChild ();
647
650
for (Node next ; caseToRemove != c ; caseToRemove = next ) {
648
651
next = caseToRemove .getNext ();
649
652
removeCase (n , caseToRemove );
650
653
}
651
654
652
- // Don't use the switch condition as the previous case.
653
- Node prevCase = (lastNonRemovable == n .getFirstChild ()) ? null : lastNonRemovable ;
654
-
655
655
// Remove the default case if we can
656
- if (isUselessCase (c , prevCase , c )) {
656
+ if (isUselessCase (c , lastNonRemovable , c )) {
657
657
removeCase (n , c );
658
658
return null ;
659
659
}
@@ -690,8 +690,8 @@ private boolean isUselessCase(
690
690
checkState (previousCase == null || previousCase .getNext () == caseNode );
691
691
// A case isn't useless if a previous case falls through to it unless it happens to be the last
692
692
// case in the switch.
693
- Node switchNode = caseNode .getParent ();
694
- if (switchNode .getLastChild () != caseNode && previousCase != null ) {
693
+ Node switchBody = caseNode .getParent ();
694
+ if (switchBody .getLastChild () != caseNode && previousCase != null ) {
695
695
Node previousBlock = previousCase .getLastChild ();
696
696
if (!previousBlock .hasChildren () || !isExit (previousBlock .getLastChild ())) {
697
697
return false ;
@@ -818,7 +818,8 @@ private static boolean isSwitchExit(Node n) {
818
818
819
819
boolean hasDefaultCase = false ;
820
820
821
- for (Node switchCase = n .getSecondChild ();
821
+ Node switchBody = n .getSecondChild ();
822
+ for (Node switchCase = switchBody .getFirstChild ();
822
823
switchCase != null ;
823
824
switchCase = switchCase .getNext ()) {
824
825
if (switchCase .isDefaultCase ()) {
0 commit comments