Skip to content

Commit

Permalink
Support ARRAY_FILTER_USE_KEY and ARRAY_FILTER_USE_BOTH
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Nov 11, 2020
1 parent 9b0ff1d commit 138cabd
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 3 deletions.
25 changes: 22 additions & 3 deletions src/Analyser/NodeScopeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -2411,9 +2411,28 @@ private function processArgs(
&& $calleeReflection->getName() === 'array_filter'
&& isset($args[0])
) {
$parameterType = new CallableType([
new DummyParameter('item', $scope->getType($args[0]->value)->getIterableValueType(), false, PassedByReference::createNo(), false, null),
], new MixedType(), false);
if (isset($args[2])) {
$mode = $scope->getType($args[2]->value);
if ($mode instanceof ConstantIntegerType) {
if ($mode->getValue() === ARRAY_FILTER_USE_KEY) {
$arrayFilterParameters = [
new DummyParameter('key', $scope->getType($args[0]->value)->getIterableKeyType(), false, PassedByReference::createNo(), false, null),
];
} elseif ($mode->getValue() === ARRAY_FILTER_USE_BOTH) {
$arrayFilterParameters = [
new DummyParameter('item', $scope->getType($args[0]->value)->getIterableValueType(), false, PassedByReference::createNo(), false, null),
new DummyParameter('key', $scope->getType($args[0]->value)->getIterableKeyType(), false, PassedByReference::createNo(), false, null),
];
}
}
}
$parameterType = new CallableType(
$arrayFilterParameters ?? [
new DummyParameter('item', $scope->getType($args[0]->value)->getIterableValueType(), false, PassedByReference::createNo(), false, null),
],
new MixedType(),
false
);
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10322,6 +10322,11 @@ public function dataBug2733(): array
return $this->gatherAssertTypes(__DIR__ . '/data/bug-2733.php');
}

public function dataBug3132(): array
{
return $this->gatherAssertTypes(__DIR__ . '/data/bug-3132.php');
}

/**
* @param string $file
* @return array<string, mixed[]>
Expand Down Expand Up @@ -10499,6 +10504,7 @@ private function gatherAssertTypes(string $file): array
* @dataProvider dataCastToNumericString
* @dataProvider dataBug2539
* @dataProvider dataBug2733
* @dataProvider dataBug3132
* @param string $assertType
* @param string $file
* @param mixed ...$args
Expand Down
48 changes: 48 additions & 0 deletions tests/PHPStan/Analyser/data/bug-3132.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace Bug3132;

use function PHPStan\Analyser\assertType;
use const ARRAY_FILTER_USE_BOTH;

class Foo
{

/**
* @param array<string,object> $objects
*
* @return array<string,object>
*/
function filter(array $objects) : array
{
return array_filter($objects, static function ($key) {
assertType('string', $key);
}, ARRAY_FILTER_USE_KEY);
}

/**
* @param array<string,object> $objects
*
* @return array<string,object>
*/
function bar(array $objects) : array
{
return array_filter($objects, static function ($val) {
assertType('object', $val);
});
}

/**
* @param array<string,object> $objects
*
* @return array<string,object>
*/
function baz(array $objects) : array
{
return array_filter($objects, static function ($val, $key) {
assertType('string', $key);
assertType('object', $val);
}, ARRAY_FILTER_USE_BOTH);
}

}

0 comments on commit 138cabd

Please sign in to comment.