Skip to content

Commit 5b517d1

Browse files
committed
More if improvements
1 parent e48a1a9 commit 5b517d1

File tree

1 file changed

+54
-42
lines changed

1 file changed

+54
-42
lines changed

src/Analyser/NodeScopeResolver.php

Lines changed: 54 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)