Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Parser/ArrayFindArgVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public function enterNode(Node $node): ?Node
{
if ($node instanceof Node\Expr\FuncCall && $node->name instanceof Node\Name) {
$functionName = $node->name->toLowerString();
if (in_array($functionName, ['array_find', 'array_find_key'], true)) {
if (in_array($functionName, ['array_all', 'array_any', 'array_find', 'array_find_key'], true)) {
$args = $node->getRawArgs();
if (isset($args[0])) {
$args[0]->setAttribute(self::ATTRIBUTE_NAME, true);
Expand Down
68 changes: 64 additions & 4 deletions tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -886,6 +886,66 @@ public function testArrayFilterCallback(bool $checkExplicitMixed): void
$this->analyse([__DIR__ . '/data/array_filter_callback.php'], $errors);
}

public function testArrayAllCallback(): void
{
if (PHP_VERSION_ID < 80400) {
$this->markTestSkipped('Test skipped on lower version than 8.4 (needs array_all function)');
}

$this->analyse([__DIR__ . '/data/array_all.php'], [
[
'Parameter #2 $callback of function array_all expects callable(1|2, \'bar\'|\'foo\'): bool, Closure(string, int): bool given.',
22,
],
[
'Parameter #2 $callback of function array_all expects callable(1|2, \'bar\'|\'foo\'): bool, Closure(string, int): bool given.',
30,
],
[
'Parameter #2 $callback of function array_all expects callable(1|2, \'bar\'|\'foo\'): bool, Closure(int, string): (\'bar\'|\'foo\') given.',
36,
],
[
'Parameter #2 $callback of function array_all expects callable(mixed, int|string): bool, Closure(string, array): false given.',
52,
],
[
'Parameter #2 $callback of function array_all expects callable(mixed, int|string): bool, Closure(string, int): array{} given.',
55,
],
]);
}

public function testArrayAnyCallback(): void
{
if (PHP_VERSION_ID < 80400) {
$this->markTestSkipped('Test skipped on lower version than 8.4 (needs array_any function)');
}

$this->analyse([__DIR__ . '/data/array_any.php'], [
[
'Parameter #2 $callback of function array_any expects callable(1|2, \'bar\'|\'foo\'): bool, Closure(string, int): bool given.',
22,
],
[
'Parameter #2 $callback of function array_any expects callable(1|2, \'bar\'|\'foo\'): bool, Closure(string, int): bool given.',
30,
],
[
'Parameter #2 $callback of function array_any expects callable(1|2, \'bar\'|\'foo\'): bool, Closure(int, string): (\'bar\'|\'foo\') given.',
36,
],
[
'Parameter #2 $callback of function array_any expects callable(mixed, int|string): bool, Closure(string, array): false given.',
52,
],
[
'Parameter #2 $callback of function array_any expects callable(mixed, int|string): bool, Closure(string, int): array{} given.',
55,
],
]);
}

public function testArrayFindCallback(): void
{
$this->analyse([__DIR__ . '/data/array_find.php'], [
Expand All @@ -903,11 +963,11 @@ public function testArrayFindCallback(): void
],
[
'Parameter #2 $callback of function array_find expects callable(mixed, int|string): bool, Closure(string, array): false given.',
49,
52,
],
[
'Parameter #2 $callback of function array_find expects callable(mixed, int|string): bool, Closure(string, int): array{} given.',
52,
55,
],
]);
}
Expand All @@ -929,11 +989,11 @@ public function testArrayFindKeyCallback(): void
],
[
'Parameter #2 $callback of function array_find_key expects callable(mixed, int|string): bool, Closure(string, array): false given.',
49,
52,
],
[
'Parameter #2 $callback of function array_find_key expects callable(mixed, int|string): bool, Closure(string, int): array{} given.',
52,
55,
],
]);
}
Expand Down
56 changes: 56 additions & 0 deletions tests/PHPStan/Rules/Functions/data/array_all.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php declare(strict_types = 1); // lint >= 8.4

// ok
array_all(
['foo' => 1, 'bar' => 2],
function($value, $key) {
return $key === 0;
}
);

// ok
array_all(
['foo' => 1, 'bar' => 2],
function(int $value, string $key) {
return $key === 0;
}
);

// bad parameters
array_all(
['foo' => 1, 'bar' => 2],
function(string $value, int $key): bool {
return $key === 0;
}
);

// bad parameters
array_all(
['foo' => 1, 'bar' => 2],
fn (string $item, int $key) => $key === 0,
);

// bad return type
array_all(
['foo' => 1, 'bar' => 2],
function(int $value, string $key) {
return $key;
},
);

if (is_array($array)) {
// ok
array_all($array, fn ($value, $key) => $key === 0);

// ok
array_all($array, fn (string $value, int $key) => $key === 0);

// ok
array_all($array, fn (string $value) => $value === 'foo');

// bad parameters
array_all($array, fn (string $item, array $key) => $key === 0);

// bad return type
array_all($array, fn (string $value, int $key): array => []);
}
56 changes: 56 additions & 0 deletions tests/PHPStan/Rules/Functions/data/array_any.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php declare(strict_types = 1); // lint >= 8.4

// ok
array_any(
['foo' => 1, 'bar' => 2],
function($value, $key) {
return $key === 0;
}
);

// ok
array_any(
['foo' => 1, 'bar' => 2],
function(int $value, string $key) {
return $key === 0;
}
);

// bad parameters
array_any(
['foo' => 1, 'bar' => 2],
function(string $value, int $key): bool {
return $key === 0;
}
);

// bad parameters
array_any(
['foo' => 1, 'bar' => 2],
fn (string $item, int $key) => $key === 0,
);

// bad return type
array_any(
['foo' => 1, 'bar' => 2],
function(int $value, string $key) {
return $key;
},
);

if (is_array($array)) {
// ok
array_any($array, fn ($value, $key) => $key === 0);

// ok
array_any($array, fn (string $value, int $key) => $key === 0);

// ok
array_any($array, fn (string $value) => $value === 'foo');

// bad parameters
array_any($array, fn (string $item, array $key) => $key === 0);

// bad return type
array_any($array, fn (string $value, int $key): array => []);
}
3 changes: 3 additions & 0 deletions tests/PHPStan/Rules/Functions/data/array_find.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ function(int $value, string $key) {
// ok
array_find($array, fn (string $value, int $key) => $key === 0);

// ok
array_find($array, fn (string $value) => $key === 0);

// bad parameters
array_find($array, fn (string $item, array $key) => $key === 0);

Expand Down
3 changes: 3 additions & 0 deletions tests/PHPStan/Rules/Functions/data/array_find_key.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ function(int $value, string $key) {
// ok
array_find_key($array, fn (string $value, int $key) => $key === 0);

// ok
array_find_key($array, fn (string $value) => $value === 'foo');

// bad parameters
array_find_key($array, fn (string $item, array $key) => $key === 0);

Expand Down
Loading