Skip to content

Commit cee5bbe

Browse files
authored
added sizeof() as alias of count() for Smaller/SmallerOrEqual
1 parent 114a38f commit cee5bbe

File tree

3 files changed

+72
-3
lines changed

3 files changed

+72
-3
lines changed

src/Analyser/TypeSpecifier.php

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,26 @@ public function specifyTypesInCondition(
326326
$context->true() ? TypeSpecifierContext::createTruthy() : TypeSpecifierContext::createTruthy()->negate()
327327
);
328328
}
329+
330+
if (
331+
!$context->null()
332+
&& $exprNode instanceof FuncCall
333+
&& count($exprNode->args) === 1
334+
&& $exprNode->name instanceof Name
335+
&& in_array(strtolower((string) $exprNode->name), ['count', 'sizeof'], true)
336+
&& $constantType instanceof ConstantIntegerType
337+
) {
338+
if ($context->truthy() || $constantType->getValue() === 0) {
339+
$newContext = $context;
340+
if ($constantType->getValue() === 0) {
341+
$newContext = $newContext->negate();
342+
}
343+
$argType = $scope->getType($exprNode->args[0]->value);
344+
if ($argType->isArray()->yes()) {
345+
return $this->create($exprNode->args[0]->value, new NonEmptyArrayType(), $newContext, false, $scope);
346+
}
347+
}
348+
}
329349
}
330350

331351
$leftType = $scope->getType($expr->left);
@@ -404,11 +424,11 @@ public function specifyTypesInCondition(
404424
$expr->left instanceof FuncCall
405425
&& count($expr->left->args) === 1
406426
&& $expr->left->name instanceof Name
407-
&& in_array(strtolower((string) $expr->left->name), ['count', 'strlen'], true)
427+
&& in_array(strtolower((string) $expr->left->name), ['count', 'sizeof', 'strlen'], true)
408428
&& (
409429
!$expr->right instanceof FuncCall
410430
|| !$expr->right->name instanceof Name
411-
|| !in_array(strtolower((string) $expr->right->name), ['count', 'strlen'], true)
431+
|| !in_array(strtolower((string) $expr->right->name), ['count', 'sizeof', 'strlen'], true)
412432
)
413433
) {
414434
$inverseOperator = $expr instanceof Node\Expr\BinaryOp\Smaller
@@ -429,7 +449,7 @@ public function specifyTypesInCondition(
429449
&& $expr->right instanceof FuncCall
430450
&& count($expr->right->args) === 1
431451
&& $expr->right->name instanceof Name
432-
&& strtolower((string) $expr->right->name) === 'count'
452+
&& in_array(strtolower((string) $expr->right->name), ['count', 'sizeof'], true)
433453
&& (new IntegerType())->isSuperTypeOf($leftType)->yes()
434454
) {
435455
if (

tests/PHPStan/Analyser/NodeScopeResolverTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,8 @@ public function dataFileAsserts(): iterable
487487
}
488488

489489
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-5529.php');
490+
491+
yield from $this->gatherAssertTypes(__DIR__ . '/data/sizeof.php');
490492
}
491493

492494
/**
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
namespace sizeof;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
8+
class Sizeof
9+
{
10+
/**
11+
* @param int[] $ints
12+
*/
13+
function doFoo1(array $ints): string
14+
{
15+
if (count($ints) <= 0) {
16+
assertType('false', min($ints));
17+
assertType('false', max($ints));
18+
}
19+
}
20+
21+
/**
22+
* @param int[] $ints
23+
*/
24+
function doFoo2(array $ints): string
25+
{
26+
if (sizeof($ints) <= 0) {
27+
assertType('false', min($ints));
28+
assertType('false', max($ints));
29+
}
30+
}
31+
32+
function doFoo3(array $arr): string
33+
{
34+
if (0 != count($arr)) {
35+
assertType('array&nonEmpty', $arr);
36+
}
37+
return "";
38+
}
39+
40+
function doFoo4(array $arr): string
41+
{
42+
if (0 != sizeof($arr)) {
43+
assertType('array&nonEmpty', $arr);
44+
}
45+
return "";
46+
}
47+
}

0 commit comments

Comments
 (0)