Skip to content

Commit

Permalink
MutatingScope - process ternary cond before getting type of the whole…
Browse files Browse the repository at this point in the history
… expression
  • Loading branch information
ondrejmirtes committed Jun 30, 2023
1 parent 989dd6f commit faba805
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 8 deletions.
19 changes: 11 additions & 8 deletions src/Analyser/MutatingScope.php
Original file line number Diff line number Diff line change
Expand Up @@ -1611,35 +1611,38 @@ private function resolveType(string $exprString, Expr $node): Type
}

if ($node instanceof Expr\Ternary) {
$noopCallback = static function (): void {
};
$condResult = $this->nodeScopeResolver->processExprNode($node->cond, $this, $noopCallback, ExpressionContext::createDeep());
if ($node->if === null) {
$conditionType = $this->getType($node->cond);
$booleanConditionType = $conditionType->toBoolean();
if ($booleanConditionType->isTrue()->yes()) {
return $this->filterByTruthyValue($node->cond)->getType($node->cond);
return $condResult->getTruthyScope()->getType($node->cond);
}

if ($booleanConditionType->isFalse()->yes()) {
return $this->filterByFalseyValue($node->cond)->getType($node->else);
return $condResult->getFalseyScope()->getType($node->else);
}

return TypeCombinator::union(
TypeCombinator::removeFalsey($this->filterByTruthyValue($node->cond)->getType($node->cond)),
$this->filterByFalseyValue($node->cond)->getType($node->else),
TypeCombinator::removeFalsey($condResult->getTruthyScope()->getType($node->cond)),
$condResult->getFalseyScope()->getType($node->else),
);
}

$booleanConditionType = $this->getType($node->cond)->toBoolean();
if ($booleanConditionType->isTrue()->yes()) {
return $this->filterByTruthyValue($node->cond)->getType($node->if);
return $condResult->getTruthyScope()->getType($node->if);
}

if ($booleanConditionType->isFalse()->yes()) {
return $this->filterByFalseyValue($node->cond)->getType($node->else);
return $condResult->getFalseyScope()->getType($node->else);
}

return TypeCombinator::union(
$this->filterByTruthyValue($node->cond)->getType($node->if),
$this->filterByFalseyValue($node->cond)->getType($node->else),
$condResult->getTruthyScope()->getType($node->if),
$condResult->getFalseyScope()->getType($node->else),
);
}

Expand Down
8 changes: 8 additions & 0 deletions tests/PHPStan/Rules/Comparison/data/bug-5365.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,11 @@ function (): void {
$found = (bool)preg_match( $pattern, $subject, $matches ) && isset( $matches['productId'] );
assertType('bool', $found);
};

function (): void {
$matches = [];
$pattern = '#^C\s+(?<productId>\d+)$#i';
$subject = 'C 1234567890';

assertType('bool', preg_match( $pattern, $subject, $matches ) ? isset( $matches['productId'] ) : false);
};

0 comments on commit faba805

Please sign in to comment.