@@ -1078,7 +1078,7 @@ private function processStmtNode(
10781078 }
10791079 } elseif ($ stmt instanceof If_) {
10801080 $ conditionType = ($ this ->treatPhpDocTypesAsCertain ? $ scope ->getType ($ stmt ->cond ) : $ scope ->getNativeType ($ stmt ->cond ))->toBoolean ();
1081- $ ifAlwaysTrue = $ conditionType ->isTrue ()-> yes () ;
1081+ $ ifAlwaysTrue = $ conditionType ->isTrue ();
10821082 $ condResult = $ this ->processExprNode ($ stmt , $ stmt ->cond , $ scope , $ nodeCallback , ExpressionContext::createDeep (), $ context );
10831083 $ exitPoints = [];
10841084 $ throwPoints = $ overridingThrowPoints ?? $ condResult ->getThrowPoints ();
@@ -1088,41 +1088,53 @@ private function processStmtNode(
10881088 $ alwaysTerminating = true ;
10891089 $ hasYield = $ condResult ->hasYield ();
10901090
1091- $ branchScopeStatementResult = $ this ->processStmtNodes ($ stmt , $ stmt ->stmts , $ condResult ->getTruthyScope (), $ nodeCallback , $ context );
1092-
1093- if (!$ conditionType ->isTrue ()->no ()) {
1094- $ exitPoints = $ branchScopeStatementResult ->getExitPoints ();
1095- $ throwPoints = array_merge ($ throwPoints , $ branchScopeStatementResult ->getThrowPoints ());
1096- $ impurePoints = array_merge ($ impurePoints , $ branchScopeStatementResult ->getImpurePoints ());
1097- $ branchScope = $ branchScopeStatementResult ->getScope ();
1098- $ finalScope = $ branchScopeStatementResult ->isAlwaysTerminating () ? null : $ branchScope ;
1099- $ alwaysTerminating = $ branchScopeStatementResult ->isAlwaysTerminating ();
1100- if (count ($ branchScopeStatementResult ->getEndStatements ()) > 0 ) {
1101- $ endStatements = array_merge ($ endStatements , $ branchScopeStatementResult ->getEndStatements ());
1102- } elseif (count ($ stmt ->stmts ) > 0 ) {
1103- $ endStatements [] = new EndStatementResult ($ stmt ->stmts [count ($ stmt ->stmts ) - 1 ], $ branchScopeStatementResult );
1104- } else {
1105- $ endStatements [] = new EndStatementResult ($ stmt , $ branchScopeStatementResult );
1091+ if ($ context ->isTopLevel () || !$ conditionType ->isTrue ()->no ()) {
1092+ $ branchScopeStatementResult = $ this ->processStmtNodes ($ stmt , $ stmt ->stmts , $ condResult ->getTruthyScope (), $ nodeCallback , $ context );
1093+
1094+ if (!$ conditionType ->isTrue ()->no ()) {
1095+ $ exitPoints = $ branchScopeStatementResult ->getExitPoints ();
1096+ $ throwPoints = array_merge ($ throwPoints , $ branchScopeStatementResult ->getThrowPoints ());
1097+ $ impurePoints = array_merge ($ impurePoints , $ branchScopeStatementResult ->getImpurePoints ());
1098+ $ branchScope = $ branchScopeStatementResult ->getScope ();
1099+ $ finalScope = $ branchScopeStatementResult ->isAlwaysTerminating () ? null : $ branchScope ;
1100+ $ alwaysTerminating = $ branchScopeStatementResult ->isAlwaysTerminating ();
1101+ if (count ($ branchScopeStatementResult ->getEndStatements ()) > 0 ) {
1102+ $ endStatements = array_merge ($ endStatements , $ branchScopeStatementResult ->getEndStatements ());
1103+ } elseif (count ($ stmt ->stmts ) > 0 ) {
1104+ $ endStatements [] = new EndStatementResult ($ stmt ->stmts [count ($ stmt ->stmts ) - 1 ], $ branchScopeStatementResult );
1105+ } else {
1106+ $ endStatements [] = new EndStatementResult ($ stmt , $ branchScopeStatementResult );
1107+ }
1108+ $ hasYield = $ branchScopeStatementResult ->hasYield () || $ hasYield ;
11061109 }
1107- $ hasYield = $ branchScopeStatementResult ->hasYield () || $ hasYield ;
11081110 }
11091111
11101112 $ scope = $ condResult ->getFalseyScope ();
1111- $ lastElseIfConditionIsTrue = false ;
1113+ $ lastElseIfConditionIsTrue = TrinaryLogic:: createNo () ;
11121114
11131115 $ condScope = $ scope ;
11141116 foreach ($ stmt ->elseifs as $ elseif ) {
11151117 $ nodeCallback ($ elseif , $ scope );
1118+ if (!$ context ->isTopLevel ()) {
1119+ if ($ ifAlwaysTrue ->yes () || $ lastElseIfConditionIsTrue ->yes ()) {
1120+ continue ;
1121+ }
1122+ }
11161123 $ elseIfConditionType = ($ this ->treatPhpDocTypesAsCertain ? $ condScope ->getType ($ elseif ->cond ) : $ scope ->getNativeType ($ elseif ->cond ))->toBoolean ();
11171124 $ condResult = $ this ->processExprNode ($ stmt , $ elseif ->cond , $ condScope , $ nodeCallback , ExpressionContext::createDeep (), $ context );
11181125 $ throwPoints = array_merge ($ throwPoints , $ condResult ->getThrowPoints ());
11191126 $ impurePoints = array_merge ($ impurePoints , $ condResult ->getImpurePoints ());
11201127 $ condScope = $ condResult ->getScope ();
11211128 $ branchScopeStatementResult = $ this ->processStmtNodes ($ elseif , $ elseif ->stmts , $ condResult ->getTruthyScope (), $ nodeCallback , $ context );
11221129
1130+ if (!$ context ->isTopLevel () && $ elseIfConditionType ->isTrue ()->no ()) {
1131+ $ scope = $ condScope ->filterByFalseyValue ($ elseif ->cond );
1132+ continue ;
1133+ }
1134+
11231135 if (
1124- !$ ifAlwaysTrue
1125- && !$ lastElseIfConditionIsTrue
1136+ !$ ifAlwaysTrue-> yes ()
1137+ && !$ lastElseIfConditionIsTrue-> yes ()
11261138 && !$ elseIfConditionType ->isTrue ()->no ()
11271139 ) {
11281140 $ exitPoints = array_merge ($ exitPoints , $ branchScopeStatementResult ->getExitPoints ());
@@ -1141,48 +1153,48 @@ private function processStmtNode(
11411153 $ hasYield = $ hasYield || $ branchScopeStatementResult ->hasYield ();
11421154 }
11431155
1144- if (
1145- $ elseIfConditionType ->isTrue ()->yes ()
1146- ) {
1147- $ lastElseIfConditionIsTrue = true ;
1156+ if ($ elseIfConditionType ->isTrue ()->yes ()) {
1157+ $ lastElseIfConditionIsTrue = $ elseIfConditionType ->isTrue ();
11481158 }
1149-
11501159 $ condScope = $ condScope ->filterByFalseyValue ($ elseif ->cond );
11511160 $ scope = $ condScope ;
11521161 }
11531162
11541163 if ($ stmt ->else === null ) {
1155- if (!$ ifAlwaysTrue && !$ lastElseIfConditionIsTrue ) {
1164+ if (!$ ifAlwaysTrue-> yes () && !$ lastElseIfConditionIsTrue-> yes () ) {
11561165 $ finalScope = $ scope ->mergeWith ($ finalScope );
11571166 $ alwaysTerminating = false ;
11581167 }
11591168 } else {
11601169 $ nodeCallback ($ stmt ->else , $ scope );
1161- $ branchScopeStatementResult = $ this ->processStmtNodes ($ stmt ->else , $ stmt ->else ->stmts , $ scope , $ nodeCallback , $ context );
11621170
1163- if (!$ ifAlwaysTrue && !$ lastElseIfConditionIsTrue ) {
1164- $ exitPoints = array_merge ($ exitPoints , $ branchScopeStatementResult ->getExitPoints ());
1165- $ throwPoints = array_merge ($ throwPoints , $ branchScopeStatementResult ->getThrowPoints ());
1166- $ impurePoints = array_merge ($ impurePoints , $ branchScopeStatementResult ->getImpurePoints ());
1167- $ branchScope = $ branchScopeStatementResult ->getScope ();
1168- $ finalScope = $ branchScopeStatementResult ->isAlwaysTerminating () ? $ finalScope : $ branchScope ->mergeWith ($ finalScope );
1169- $ alwaysTerminating = $ alwaysTerminating && $ branchScopeStatementResult ->isAlwaysTerminating ();
1170- if (count ($ branchScopeStatementResult ->getEndStatements ()) > 0 ) {
1171- $ endStatements = array_merge ($ endStatements , $ branchScopeStatementResult ->getEndStatements ());
1172- } elseif (count ($ stmt ->else ->stmts ) > 0 ) {
1173- $ endStatements [] = new EndStatementResult ($ stmt ->else ->stmts [count ($ stmt ->else ->stmts ) - 1 ], $ branchScopeStatementResult );
1174- } else {
1175- $ endStatements [] = new EndStatementResult ($ stmt ->else , $ branchScopeStatementResult );
1171+ if ($ context ->isTopLevel () || (!$ ifAlwaysTrue ->yes () && !$ lastElseIfConditionIsTrue ->yes ())) {
1172+ $ branchScopeStatementResult = $ this ->processStmtNodes ($ stmt ->else , $ stmt ->else ->stmts , $ scope , $ nodeCallback , $ context );
1173+
1174+ if (!$ ifAlwaysTrue ->yes () && !$ lastElseIfConditionIsTrue ->yes ()) {
1175+ $ exitPoints = array_merge ($ exitPoints , $ branchScopeStatementResult ->getExitPoints ());
1176+ $ throwPoints = array_merge ($ throwPoints , $ branchScopeStatementResult ->getThrowPoints ());
1177+ $ impurePoints = array_merge ($ impurePoints , $ branchScopeStatementResult ->getImpurePoints ());
1178+ $ branchScope = $ branchScopeStatementResult ->getScope ();
1179+ $ finalScope = $ branchScopeStatementResult ->isAlwaysTerminating () ? $ finalScope : $ branchScope ->mergeWith ($ finalScope );
1180+ $ alwaysTerminating = $ alwaysTerminating && $ branchScopeStatementResult ->isAlwaysTerminating ();
1181+ if (count ($ branchScopeStatementResult ->getEndStatements ()) > 0 ) {
1182+ $ endStatements = array_merge ($ endStatements , $ branchScopeStatementResult ->getEndStatements ());
1183+ } elseif (count ($ stmt ->else ->stmts ) > 0 ) {
1184+ $ endStatements [] = new EndStatementResult ($ stmt ->else ->stmts [count ($ stmt ->else ->stmts ) - 1 ], $ branchScopeStatementResult );
1185+ } else {
1186+ $ endStatements [] = new EndStatementResult ($ stmt ->else , $ branchScopeStatementResult );
1187+ }
1188+ $ hasYield = $ hasYield || $ branchScopeStatementResult ->hasYield ();
11761189 }
1177- $ hasYield = $ hasYield || $ branchScopeStatementResult ->hasYield ();
11781190 }
11791191 }
11801192
11811193 if ($ finalScope === null ) {
11821194 $ finalScope = $ scope ;
11831195 }
11841196
1185- if ($ stmt ->else === null && !$ ifAlwaysTrue && !$ lastElseIfConditionIsTrue ) {
1197+ if ($ stmt ->else === null && !$ ifAlwaysTrue-> yes () && !$ lastElseIfConditionIsTrue-> yes () ) {
11861198 $ endStatements [] = new EndStatementResult ($ stmt , new StatementResult ($ finalScope , $ hasYield , $ alwaysTerminating , $ exitPoints , $ throwPoints , $ impurePoints ));
11871199 }
11881200
0 commit comments