Skip to content

Commit 3361c84

Browse files
staabmondrejmirtes
authored andcommitted
Narrow to non-empty-string/non-falsey-string after mb_strlen()
1 parent 4d162fa commit 3361c84

File tree

3 files changed

+46
-4
lines changed

3 files changed

+46
-4
lines changed

src/Analyser/TypeSpecifier.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -210,11 +210,11 @@ public function specifyTypesInCondition(
210210
$expr->left instanceof FuncCall
211211
&& count($expr->left->getArgs()) === 1
212212
&& $expr->left->name instanceof Name
213-
&& in_array(strtolower((string) $expr->left->name), ['count', 'sizeof', 'strlen'], true)
213+
&& in_array(strtolower((string) $expr->left->name), ['count', 'sizeof', 'strlen', 'mb_strlen'], true)
214214
&& (
215215
!$expr->right instanceof FuncCall
216216
|| !$expr->right->name instanceof Name
217-
|| !in_array(strtolower((string) $expr->right->name), ['count', 'sizeof', 'strlen'], true)
217+
|| !in_array(strtolower((string) $expr->right->name), ['count', 'sizeof', 'strlen', 'mb_strlen'], true)
218218
)
219219
) {
220220
$inverseOperator = $expr instanceof Node\Expr\BinaryOp\Smaller
@@ -265,7 +265,7 @@ public function specifyTypesInCondition(
265265
&& $expr->right instanceof FuncCall
266266
&& count($expr->right->getArgs()) === 1
267267
&& $expr->right->name instanceof Name
268-
&& strtolower((string) $expr->right->name) === 'strlen'
268+
&& in_array(strtolower((string) $expr->right->name), ['strlen', 'mb_strlen'], true)
269269
&& $leftType->isInteger()->yes()
270270
) {
271271
if (
@@ -977,7 +977,7 @@ private function specifyTypesForConstantBinaryExpression(
977977
&& $exprNode instanceof FuncCall
978978
&& count($exprNode->getArgs()) === 1
979979
&& $exprNode->name instanceof Name
980-
&& strtolower((string) $exprNode->name) === 'strlen'
980+
&& in_array(strtolower((string) $exprNode->name), ['strlen', 'mb_strlen'], true)
981981
&& $constantType instanceof ConstantIntegerType
982982
) {
983983
if ($context->truthy() || $constantType->getValue() === 0) {

tests/PHPStan/Analyser/NodeScopeResolverTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,6 +1476,7 @@ public function dataFileAsserts(): iterable
14761476
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-10187.php');
14771477
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-10834.php');
14781478
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-10952.php');
1479+
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-10952b.php');
14791480
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-10893.php');
14801481
}
14811482

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug10952b;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
class HelloWorld
8+
{
9+
public function getString(): string
10+
{
11+
return 'hallo';
12+
}
13+
14+
public function test(): void
15+
{
16+
$string = $this->getString();
17+
18+
if (1 < mb_strlen($string)) {
19+
assertType('non-empty-string', $string);
20+
} else {
21+
assertType("string", $string);
22+
}
23+
24+
if (mb_strlen($string) > 1) {
25+
assertType('non-empty-string', $string);
26+
} else {
27+
assertType("string", $string);
28+
}
29+
30+
if (2 < mb_strlen($string)) {
31+
assertType('non-falsy-string', $string);
32+
} else {
33+
assertType("string", $string);
34+
}
35+
36+
match (true) {
37+
mb_strlen($string) > 0 => assertType('non-empty-string', $string),
38+
default => assertType("''", $string),
39+
};
40+
}
41+
}

0 commit comments

Comments
 (0)