@@ -809,7 +809,7 @@ private function processStmtNode(
809
809
$ finalScope ,
810
810
$ finalScopeResult ->hasYield () || $ condResult ->hasYield (),
811
811
$ isIterableAtLeastOnce ->yes () && $ finalScopeResult ->isAlwaysTerminating (),
812
- []
812
+ $ finalScopeResult -> getExitPointsForOuterLoop ()
813
813
);
814
814
} elseif ($ stmt instanceof While_) {
815
815
$ condResult = $ this ->processExprNode ($ stmt ->cond , $ scope , static function (): void {
@@ -875,7 +875,7 @@ private function processStmtNode(
875
875
$ finalScope ,
876
876
$ finalScopeResult ->hasYield () || $ condResult ->hasYield (),
877
877
$ isAlwaysTerminating ,
878
- []
878
+ $ finalScopeResult -> getExitPointsForOuterLoop ()
879
879
);
880
880
} elseif ($ stmt instanceof Do_) {
881
881
$ finalScope = null ;
@@ -940,7 +940,7 @@ private function processStmtNode(
940
940
$ finalScope ,
941
941
$ bodyScopeResult ->hasYield () || $ hasYield ,
942
942
$ alwaysTerminating ,
943
- []
943
+ $ bodyScopeResult -> getExitPointsForOuterLoop ()
944
944
);
945
945
} elseif ($ stmt instanceof For_) {
946
946
$ initScope = $ scope ;
@@ -1014,7 +1014,7 @@ private function processStmtNode(
1014
1014
$ finalScope ,
1015
1015
$ finalScopeResult ->hasYield () || $ hasYield ,
1016
1016
false /* $finalScopeResult->isAlwaysTerminating() && $isAlwaysIterable*/ ,
1017
- []
1017
+ $ finalScopeResult -> getExitPointsForOuterLoop ()
1018
1018
);
1019
1019
} elseif ($ stmt instanceof Switch_) {
1020
1020
$ condResult = $ this ->processExprNode ($ stmt ->cond , $ scope , $ nodeCallback , ExpressionContext::createDeep ());
@@ -1025,6 +1025,7 @@ private function processStmtNode(
1025
1025
$ hasDefaultCase = false ;
1026
1026
$ alwaysTerminating = true ;
1027
1027
$ hasYield = $ condResult ->hasYield ();
1028
+ $ exitPointsForOuterLoop = [];
1028
1029
foreach ($ stmt ->cases as $ caseNode ) {
1029
1030
if ($ caseNode ->cond !== null ) {
1030
1031
$ condExpr = new BinaryOp \Equal ($ stmt ->cond , $ caseNode ->cond );
@@ -1047,6 +1048,7 @@ private function processStmtNode(
1047
1048
foreach ($ branchScopeResult ->getExitPointsByType (Continue_::class) as $ continueExitPoint ) {
1048
1049
$ finalScope = $ continueExitPoint ->getScope ()->mergeWith ($ finalScope );
1049
1050
}
1051
+ $ exitPointsForOuterLoop = array_merge ($ exitPointsForOuterLoop , $ branchFinalScopeResult ->getExitPointsForOuterLoop ());
1050
1052
if ($ branchScopeResult ->isAlwaysTerminating ()) {
1051
1053
$ alwaysTerminating = $ alwaysTerminating && $ branchFinalScopeResult ->isAlwaysTerminating ();
1052
1054
$ prevScope = null ;
@@ -1074,7 +1076,7 @@ private function processStmtNode(
1074
1076
$ finalScope = $ scope ->mergeWith ($ finalScope );
1075
1077
}
1076
1078
1077
- return new StatementResult ($ finalScope , $ hasYield , $ alwaysTerminating , [] );
1079
+ return new StatementResult ($ finalScope , $ hasYield , $ alwaysTerminating , $ exitPointsForOuterLoop );
1078
1080
} elseif ($ stmt instanceof TryCatch) {
1079
1081
$ branchScopeResult = $ this ->processStmtNodes ($ stmt , $ stmt ->stmts , $ scope , $ nodeCallback );
1080
1082
$ branchScope = $ branchScopeResult ->getScope ();
0 commit comments