Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/1.5.x' into 1.6.x
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Apr 19, 2024
2 parents 1a51fae + 8afd4af commit c7b4d28
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 0 deletions.
36 changes: 36 additions & 0 deletions src/Rules/Functions/ArrayFilterStrictRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;
use PHPStan\Type\Type;
use PHPStan\Type\UnionType;
use PHPStan\Type\VerbosityLevel;
use function count;
use function sprintf;
Expand Down Expand Up @@ -82,6 +83,41 @@ public function processNode(Node $node, Scope $scope): array
}

if (count($args) === 1) {
if ($this->treatPhpDocTypesAsCertain) {
$arrayType = $scope->getType($args[0]->value);
} else {
$arrayType = $scope->getNativeType($args[0]->value);
}

$itemType = $arrayType->getIterableValueType();
if ($itemType instanceof UnionType) {
$hasTruthy = false;
$hasFalsey = false;
foreach ($itemType->getTypes() as $innerType) {
$booleanType = $innerType->toBoolean();
if ($booleanType->isTrue()->yes()) {
$hasTruthy = true;
continue;
}
if ($booleanType->isFalse()->yes()) {
$hasFalsey = true;
continue;
}

$hasTruthy = false;
$hasFalsey = false;
break;
}

if ($hasTruthy && $hasFalsey) {
return [];
}
} elseif ($itemType->isBoolean()->yes()) {
return [];
} elseif ($itemType->isArray()->yes()) {
return [];
}

return [
RuleErrorBuilder::message('Call to function array_filter() requires parameter #2 to be passed to avoid loose comparison semantics.')
->identifier('arrayFilter.strict')
Expand Down
20 changes: 20 additions & 0 deletions tests/Rules/Functions/ArrayFilterStrictRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,24 @@ public function testRule(): void
]);
}

public function testRuleAllowMissingCallbackInSomeCases(): void
{
$this->treatPhpDocTypesAsCertain = true;
$this->checkNullables = true;
$this->analyse([__DIR__ . '/data/array-filter-allow.php'], [
[
'Call to function array_filter() requires parameter #2 to be passed to avoid loose comparison semantics.',
27,
],
[
'Call to function array_filter() requires parameter #2 to be passed to avoid loose comparison semantics.',
37,
],
[
'Call to function array_filter() requires parameter #2 to be passed to avoid loose comparison semantics.',
49,
],
]);
}

}
58 changes: 58 additions & 0 deletions tests/Rules/Functions/data/array-filter-allow.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

namespace ArrayFilterAllow;

use function array_filter;

class Foo
{

/**
* @param array<self|null> $a
*/
public function doFoo(
array $a
): array
{
return array_filter($a);
}

/**
* @param array<self> $a
*/
public function doFoo2(
array $a
): array
{
return array_filter($a);
}

/**
* @param array<int|null> $a
*/
public function doFoo3(
array $a
): array
{
return array_filter($a);
}

/** @param array<bool> $a */
public function doFoo4(array $a): array
{
return array_filter($a);
}

/** @param array<int> $a */
public function doFoo5(array $a): array
{
return array_filter($a);
}

/** @param array<array<int>> $a */
public function doFoo6(array $a): array
{
return array_filter($a);
}

}

0 comments on commit c7b4d28

Please sign in to comment.