Skip to content

Commit a52fb61

Browse files
committed
Revert "While loop-like fixes for other loops and if condition"
This reverts commit ce6bef1.
1 parent ce6bef1 commit a52fb61

File tree

2 files changed

+57
-87
lines changed

2 files changed

+57
-87
lines changed

phpstan-baseline.neon

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ parameters:
4242
count: 1
4343
path: src/Analyser/MutatingScope.php
4444

45+
-
46+
message: '#^Doing instanceof PHPStan\\Type\\Constant\\ConstantBooleanType is error\-prone and deprecated\. Use Type\:\:isTrue\(\) or Type\:\:isFalse\(\) instead\.$#'
47+
identifier: phpstanApi.instanceofType
48+
count: 2
49+
path: src/Analyser/NodeScopeResolver.php
50+
4551
-
4652
message: '#^Doing instanceof PHPStan\\Type\\Constant\\ConstantStringType is error\-prone and deprecated\. Use Type\:\:getConstantStrings\(\) instead\.$#'
4753
identifier: phpstanApi.instanceofType

src/Analyser/NodeScopeResolver.php

Lines changed: 51 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@
171171
use PHPStan\Type\ClosureType;
172172
use PHPStan\Type\Constant\ConstantArrayType;
173173
use PHPStan\Type\Constant\ConstantArrayTypeBuilder;
174+
use PHPStan\Type\Constant\ConstantBooleanType;
174175
use PHPStan\Type\Constant\ConstantIntegerType;
175176
use PHPStan\Type\Constant\ConstantStringType;
176177
use PHPStan\Type\ErrorType;
@@ -1078,7 +1079,7 @@ private function processStmtNode(
10781079
}
10791080
} elseif ($stmt instanceof If_) {
10801081
$conditionType = ($this->treatPhpDocTypesAsCertain ? $scope->getType($stmt->cond) : $scope->getNativeType($stmt->cond))->toBoolean();
1081-
$ifAlwaysTrue = $conditionType->isTrue();
1082+
$ifAlwaysTrue = $conditionType->isTrue()->yes();
10821083
$condResult = $this->processExprNode($stmt, $stmt->cond, $scope, $nodeCallback, ExpressionContext::createDeep(), $context);
10831084
$exitPoints = [];
10841085
$throwPoints = $overridingThrowPoints ?? $condResult->getThrowPoints();
@@ -1088,54 +1089,47 @@ private function processStmtNode(
10881089
$alwaysTerminating = true;
10891090
$hasYield = $condResult->hasYield();
10901091

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;
1092+
$branchScopeStatementResult = $this->processStmtNodes($stmt, $stmt->stmts, $condResult->getTruthyScope(), $nodeCallback, $context);
1093+
1094+
if (!$conditionType instanceof ConstantBooleanType || $conditionType->getValue()) {
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);
11091107
}
1108+
$hasYield = $branchScopeStatementResult->hasYield() || $hasYield;
11101109
}
11111110

11121111
$scope = $condResult->getFalseyScope();
1113-
$lastElseIfConditionIsTrue = TrinaryLogic::createNo();
1112+
$lastElseIfConditionIsTrue = false;
11141113

11151114
$condScope = $scope;
11161115
foreach ($stmt->elseifs as $elseif) {
11171116
$nodeCallback($elseif, $scope);
1118-
if (!$context->isTopLevel()) {
1119-
if ($ifAlwaysTrue->yes() || $lastElseIfConditionIsTrue->yes()) {
1120-
continue;
1121-
}
1122-
}
11231117
$elseIfConditionType = ($this->treatPhpDocTypesAsCertain ? $condScope->getType($elseif->cond) : $scope->getNativeType($elseif->cond))->toBoolean();
11241118
$condResult = $this->processExprNode($stmt, $elseif->cond, $condScope, $nodeCallback, ExpressionContext::createDeep(), $context);
11251119
$throwPoints = array_merge($throwPoints, $condResult->getThrowPoints());
11261120
$impurePoints = array_merge($impurePoints, $condResult->getImpurePoints());
11271121
$condScope = $condResult->getScope();
11281122
$branchScopeStatementResult = $this->processStmtNodes($elseif, $elseif->stmts, $condResult->getTruthyScope(), $nodeCallback, $context);
11291123

1130-
if (!$context->isTopLevel() && $elseIfConditionType->isTrue()->no()) {
1131-
$scope = $condScope->filterByFalseyValue($elseif->cond);
1132-
continue;
1133-
}
1134-
11351124
if (
1136-
!$ifAlwaysTrue->yes()
1137-
&& !$lastElseIfConditionIsTrue->yes()
1138-
&& !$elseIfConditionType->isTrue()->no()
1125+
!$ifAlwaysTrue
1126+
&& (
1127+
!$lastElseIfConditionIsTrue
1128+
&& (
1129+
!$elseIfConditionType instanceof ConstantBooleanType
1130+
|| $elseIfConditionType->getValue()
1131+
)
1132+
)
11391133
) {
11401134
$exitPoints = array_merge($exitPoints, $branchScopeStatementResult->getExitPoints());
11411135
$throwPoints = array_merge($throwPoints, $branchScopeStatementResult->getThrowPoints());
@@ -1153,48 +1147,48 @@ private function processStmtNode(
11531147
$hasYield = $hasYield || $branchScopeStatementResult->hasYield();
11541148
}
11551149

1156-
if ($elseIfConditionType->isTrue()->yes()) {
1157-
$lastElseIfConditionIsTrue = $elseIfConditionType->isTrue();
1150+
if (
1151+
$elseIfConditionType->isTrue()->yes()
1152+
) {
1153+
$lastElseIfConditionIsTrue = true;
11581154
}
1155+
11591156
$condScope = $condScope->filterByFalseyValue($elseif->cond);
11601157
$scope = $condScope;
11611158
}
11621159

11631160
if ($stmt->else === null) {
1164-
if (!$ifAlwaysTrue->yes() && !$lastElseIfConditionIsTrue->yes()) {
1161+
if (!$ifAlwaysTrue && !$lastElseIfConditionIsTrue) {
11651162
$finalScope = $scope->mergeWith($finalScope);
11661163
$alwaysTerminating = false;
11671164
}
11681165
} else {
11691166
$nodeCallback($stmt->else, $scope);
1167+
$branchScopeStatementResult = $this->processStmtNodes($stmt->else, $stmt->else->stmts, $scope, $nodeCallback, $context);
11701168

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();
1169+
if (!$ifAlwaysTrue && !$lastElseIfConditionIsTrue) {
1170+
$exitPoints = array_merge($exitPoints, $branchScopeStatementResult->getExitPoints());
1171+
$throwPoints = array_merge($throwPoints, $branchScopeStatementResult->getThrowPoints());
1172+
$impurePoints = array_merge($impurePoints, $branchScopeStatementResult->getImpurePoints());
1173+
$branchScope = $branchScopeStatementResult->getScope();
1174+
$finalScope = $branchScopeStatementResult->isAlwaysTerminating() ? $finalScope : $branchScope->mergeWith($finalScope);
1175+
$alwaysTerminating = $alwaysTerminating && $branchScopeStatementResult->isAlwaysTerminating();
1176+
if (count($branchScopeStatementResult->getEndStatements()) > 0) {
1177+
$endStatements = array_merge($endStatements, $branchScopeStatementResult->getEndStatements());
1178+
} elseif (count($stmt->else->stmts) > 0) {
1179+
$endStatements[] = new EndStatementResult($stmt->else->stmts[count($stmt->else->stmts) - 1], $branchScopeStatementResult);
1180+
} else {
1181+
$endStatements[] = new EndStatementResult($stmt->else, $branchScopeStatementResult);
11891182
}
1183+
$hasYield = $hasYield || $branchScopeStatementResult->hasYield();
11901184
}
11911185
}
11921186

11931187
if ($finalScope === null) {
11941188
$finalScope = $scope;
11951189
}
11961190

1197-
if ($stmt->else === null && !$ifAlwaysTrue->yes() && !$lastElseIfConditionIsTrue->yes()) {
1191+
if ($stmt->else === null && !$ifAlwaysTrue && !$lastElseIfConditionIsTrue) {
11981192
$endStatements[] = new EndStatementResult($stmt, new StatementResult($finalScope, $hasYield, $alwaysTerminating, $exitPoints, $throwPoints, $impurePoints));
11991193
}
12001194

@@ -1208,7 +1202,6 @@ private function processStmtNode(
12081202
$condResult = $this->processExprNode($stmt, $stmt->expr, $scope, $nodeCallback, ExpressionContext::createDeep(), $context);
12091203
$throwPoints = $overridingThrowPoints ?? $condResult->getThrowPoints();
12101204
$impurePoints = $condResult->getImpurePoints();
1211-
$exprType = $scope->getType($stmt->expr);
12121205
$scope = $condResult->getScope();
12131206
$arrayComparisonExpr = new BinaryOp\NotIdentical(
12141207
$stmt->expr,
@@ -1221,18 +1214,6 @@ private function processStmtNode(
12211214
$originalScope = $scope;
12221215
$bodyScope = $scope;
12231216

1224-
$isIterableAtLeastOnce = $exprType->isIterableAtLeastOnce();
1225-
if (!$context->isTopLevel() && $isIterableAtLeastOnce->no()) {
1226-
return new StatementResult(
1227-
$scope,
1228-
$condResult->hasYield(),
1229-
$condResult->isAlwaysTerminating(),
1230-
[],
1231-
$throwPoints,
1232-
$impurePoints,
1233-
);
1234-
}
1235-
12361217
if ($context->isTopLevel()) {
12371218
$originalScope = $this->polluteScopeWithAlwaysIterableForeach ? $scope->filterByTruthyValue($arrayComparisonExpr) : $scope;
12381219
$bodyScope = $this->enterForeach($originalScope, $originalScope, $stmt);
@@ -1269,6 +1250,8 @@ private function processStmtNode(
12691250
$finalScope = $breakExitPoint->getScope()->mergeWith($finalScope);
12701251
}
12711252

1253+
$exprType = $scope->getType($stmt->expr);
1254+
$isIterableAtLeastOnce = $exprType->isIterableAtLeastOnce();
12721255
if ($exprType->isIterable()->no() || $isIterableAtLeastOnce->maybe()) {
12731256
$finalScope = $finalScope->mergeWith($scope->filterByTruthyValue(new BooleanOr(
12741257
new BinaryOp\Identical(
@@ -1511,25 +1494,6 @@ private function processStmtNode(
15111494
$bodyScope = $condResult->getTruthyScope();
15121495
}
15131496

1514-
if (!$context->isTopLevel() && $isIterableAtLeastOnce->no()) {
1515-
if (!isset($condResult)) {
1516-
throw new ShouldNotHappenException();
1517-
}
1518-
if ($this->polluteScopeWithLoopInitialAssignments) {
1519-
$finalScope = $condResult->getFalseyScope()->mergeWith($initScope);
1520-
} else {
1521-
$finalScope = $condResult->getFalseyScope()->mergeWith($scope);
1522-
}
1523-
return new StatementResult(
1524-
$finalScope,
1525-
$hasYield,
1526-
false,
1527-
[],
1528-
$throwPoints,
1529-
$impurePoints,
1530-
);
1531-
}
1532-
15331497
if ($context->isTopLevel()) {
15341498
$count = 0;
15351499
do {

0 commit comments

Comments
 (0)