Skip to content

Commit

Permalink
All count functions and methods return 0 or positive-int
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Oct 22, 2020
1 parent 6784a1c commit a78a2e7
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 69 deletions.
94 changes: 47 additions & 47 deletions resources/functionMap.php

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/Reflection/Php/PhpClassReflectionExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -769,7 +769,7 @@ private function inferAndCachePropertyTypes(

$classNameParts = explode('\\', $declaringClass->getName());
$namespace = null;
if (count($classNameParts) > 0) {
if (count($classNameParts) > 1) {
$namespace = implode('\\', array_slice($classNameParts, 0, -1));
}

Expand Down
4 changes: 1 addition & 3 deletions src/Rules/Whitespace/FileWhitespaceRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,7 @@ public function getLastNodes(): array
$nodeTraverser->traverse($nodes);

$lastNodes = $visitor->getLastNodes();
if (count($nodes) > 0) {
$lastNodes[] = $nodes[count($nodes) - 1];
}
$lastNodes[] = $nodes[count($nodes) - 1];
foreach ($lastNodes as $lastNode) {
if (!$lastNode instanceof Node\Stmt\InlineHTML || Strings::match($lastNode->value, '#^(\s+)$#') === null) {
continue;
Expand Down
2 changes: 1 addition & 1 deletion src/Type/ArrayType.php
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ public function toArray(): Type

public function count(): Type
{
return new IntegerType();
return IntegerRangeType::fromInterval(0, null);
}

public static function castToArrayKeyType(Type $offsetType): Type
Expand Down
12 changes: 9 additions & 3 deletions src/Type/Php/CountFunctionReturnTypeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use PHPStan\Reflection\FunctionReflection;
use PHPStan\Reflection\ParametersAcceptorSelector;
use PHPStan\Type\Constant\ConstantIntegerType;
use PHPStan\Type\IntegerRangeType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeCombinator;
use PHPStan\Type\TypeUtils;
Expand Down Expand Up @@ -36,12 +37,17 @@ public function getTypeFromFunctionCall(
}
}

$arrays = TypeUtils::getArrays($scope->getType($functionCall->args[0]->value));
if (count($arrays) === 0) {
$argType = $scope->getType($functionCall->args[0]->value);
$constantArrays = TypeUtils::getConstantArrays($scope->getType($functionCall->args[0]->value));
if (count($constantArrays) === 0) {
if ($argType->isIterableAtLeastOnce()->yes()) {
return IntegerRangeType::fromInterval(1, null);
}

return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType();
}
$countTypes = [];
foreach ($arrays as $array) {
foreach ($constantArrays as $array) {
$countTypes[] = $array->count();
}

Expand Down
12 changes: 9 additions & 3 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2530,7 +2530,7 @@ public function dataBinaryOperations(): array
'count($arrayOfIntegers)',
],
[
'int',
'int<0, max>',
'count($arrayOfIntegers, \COUNT_RECURSIVE)',
],
[
Expand Down Expand Up @@ -2802,11 +2802,11 @@ public function dataBinaryOperations(): array
'count($array)',
],
[
'int',
'int<0, max>',
'count()',
],
[
'int',
'int<0, max>',
'count($appendingToArrayInBranches)',
],
[
Expand Down Expand Up @@ -10204,6 +10204,11 @@ public function dataExtraIntTypes(): array
return $this->gatherAssertTypes(__DIR__ . '/data/extra-int-types.php');
}

public function dataCount(): array
{
return $this->gatherAssertTypes(__DIR__ . '/data/count-type.php');
}

/**
* @dataProvider dataBug2574
* @dataProvider dataBug2577
Expand Down Expand Up @@ -10287,6 +10292,7 @@ public function dataExtraIntTypes(): array
* @dataProvider dataBug3961
* @dataProvider dataBug1924
* @dataProvider dataExtraIntTypes
* @dataProvider dataCount
* @param string $assertType
* @param string $file
* @param mixed ...$args
Expand Down
14 changes: 7 additions & 7 deletions tests/PHPStan/Analyser/data/bug-2648.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public function doFoo(array $list): void
assertType('int<2, max>', count($list));
unset($list['fooo']);
assertType('array<bool>', $list);
assertType('int', count($list));
assertType('int<0, max>', count($list));
}
}

Expand All @@ -28,24 +28,24 @@ public function doBar(array $list): void
if (count($list) > 1) {
assertType('int<2, max>', count($list));
foreach ($list as $key => $item) {
assertType('int<2, max>|int<min, 0>', count($list));
assertType('0|int<2, max>', count($list));
if ($item === false) {
unset($list[$key]);
assertType('int', count($list));
assertType('int<0, max>', count($list));
}

assertType('int', count($list));
assertType('int<0, max>', count($list));

if (count($list) === 1) {
assertType('int', count($list));
assertType('int<1, max>', count($list));
break;
}
}

assertType('int', count($list));
assertType('int<0, max>', count($list));
}

assertType('int', count($list));
assertType('int<0, max>', count($list));
}

}
8 changes: 4 additions & 4 deletions tests/PHPStan/Analyser/data/bug-2750.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@ function (array $input) {
\assert(count($input) > 0);
assertType('int<1, max>', count($input));
array_shift($input);
assertType('int', count($input));
assertType('int<0, max>', count($input));

\assert(count($input) > 0);
assertType('int<1, max>', count($input));
array_pop($input);
assertType('int', count($input));
assertType('int<0, max>', count($input));

\assert(count($input) > 0);
assertType('int<1, max>', count($input));
array_unshift($input, 'test');
assertType('int', count($input));
assertType('int<1, max>', count($input));

\assert(count($input) > 0);
assertType('int<1, max>', count($input));
array_push($input, 'nope');
assertType('int', count($input));
assertType('int<1, max>', count($input));
};
20 changes: 20 additions & 0 deletions tests/PHPStan/Analyser/data/count-type.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace CountType;

use function PHPStan\Analyser\assertType;

class Foo
{

/**
* @param non-empty-array $nonEmpty
*/
public function doFoo(
array $nonEmpty
)
{
assertType('int<1, max>', count($nonEmpty));
}

}

0 comments on commit a78a2e7

Please sign in to comment.