From 941684de220680840e2d1fdc61d5c835300bca57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Ma=C5=A1a?= Date: Fri, 8 Jun 2018 14:00:06 +0200 Subject: [PATCH] Generalize filtered array with maybe falsey values --- ...terFunctionReturnTypeReturnTypeExtension.php | 17 ++++++++++++----- .../PHPStan/Analyser/NodeScopeResolverTest.php | 4 ++++ tests/PHPStan/Analyser/data/array-functions.php | 7 +++++++ 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/Type/Php/ArrayFilterFunctionReturnTypeReturnTypeExtension.php b/src/Type/Php/ArrayFilterFunctionReturnTypeReturnTypeExtension.php index c4a4fa329a..ec9dbf4665 100644 --- a/src/Type/Php/ArrayFilterFunctionReturnTypeReturnTypeExtension.php +++ b/src/Type/Php/ArrayFilterFunctionReturnTypeReturnTypeExtension.php @@ -84,15 +84,22 @@ public function removeFalsey(Type $type): Type $keys = $type->getKeyTypes(); $values = $type->getValueTypes(); + $generalize = false; + foreach ($values as $offset => $value) { - if (!$falseyTypes->isSuperTypeOf($value)->yes()) { - continue; - } + $isFalsey = $falseyTypes->isSuperTypeOf($value); - unset($keys[$offset], $values[$offset]); + if ($isFalsey->yes()) { + unset($keys[$offset], $values[$offset]); + } elseif ($isFalsey->maybe()) { + $values[$offset] = TypeCombinator::remove($values[$offset], $falseyTypes); + $generalize = true; + } } - return new ConstantArrayType(array_values($keys), array_values($values)); + $filteredArray = new ConstantArrayType(array_values($keys), array_values($values)); + + return $generalize ? $filteredArray->generalize() : $filteredArray; } $keyType = $type->getIterableKeyType(); diff --git a/tests/PHPStan/Analyser/NodeScopeResolverTest.php b/tests/PHPStan/Analyser/NodeScopeResolverTest.php index 37056d0815..9a7f5781e2 100644 --- a/tests/PHPStan/Analyser/NodeScopeResolverTest.php +++ b/tests/PHPStan/Analyser/NodeScopeResolverTest.php @@ -4144,6 +4144,10 @@ public function dataArrayFunctions(): array 'array(\'a\' => 1)', 'array_filter($union)', ], + [ + 'array', + 'array_filter($withPossiblyFalsey)', + ], ]; } diff --git a/tests/PHPStan/Analyser/data/array-functions.php b/tests/PHPStan/Analyser/data/array-functions.php index 3dddf23370..63f15ef954 100644 --- a/tests/PHPStan/Analyser/data/array-functions.php +++ b/tests/PHPStan/Analyser/data/array-functions.php @@ -56,6 +56,13 @@ $union['b'] = false; } +/** @var bool $bool */ +$bool = doFoo(); +/** @var int $integer */ +$integer = doFoo(); + +$withPossiblyFalsey = [$bool, $integer, '', 'a' => 0]; + /** @var array $generalStringKeys */ $generalStringKeys = doFoo();