From fddc5b0dc0791c27c81719351a3d523dacdd6470 Mon Sep 17 00:00:00 2001 From: Jeppe Knockaert Date: Fri, 16 Dec 2022 13:43:11 +0100 Subject: [PATCH] Prevent false positive for NoUnnecessaryCollectionCallRule when using arrow functions (#1483) --- CHANGELOG.md | 1 + src/Rules/NoUnnecessaryCollectionCallRule.php | 2 +- tests/Rules/Data/CorrectCollectionCalls.php | 20 +++++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bcc4a282e..21c29c208 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - feat: conditional return types for `Eloquent\Collection::find()` by @sebdesign - feat: add support for generic paginators by @erikgaal - feat: add support for encrypted and parameterized eloquent casts by @jdjfisher +- fix: prevent false positive for NoUnnecessaryCollectionCallRule when using arrow functions by @JeppeKnockaert ## [2.2.0] - 2022-08-31 diff --git a/src/Rules/NoUnnecessaryCollectionCallRule.php b/src/Rules/NoUnnecessaryCollectionCallRule.php index 6a8ce892c..31a45341c 100644 --- a/src/Rules/NoUnnecessaryCollectionCallRule.php +++ b/src/Rules/NoUnnecessaryCollectionCallRule.php @@ -204,7 +204,7 @@ public function processNode(Node $node, Scope $scope): array // 'contains' can also be called with Model instances or keys as its first argument /** @var \PhpParser\Node\Arg[] $args */ $args = $node->args; - if (count($args) === 1 && ! ($args[0]->value instanceof Node\Expr\Closure)) { + if (count($args) === 1 && ! ($args[0]->value instanceof Node\FunctionLike)) { return [$this->formatError($name->toString())]; } diff --git a/tests/Rules/Data/CorrectCollectionCalls.php b/tests/Rules/Data/CorrectCollectionCalls.php index ee6ec482f..c347b77e7 100644 --- a/tests/Rules/Data/CorrectCollectionCalls.php +++ b/tests/Rules/Data/CorrectCollectionCalls.php @@ -72,6 +72,16 @@ public function testContainsClosure(): bool }); } + /** + * Can't analyze the arrow function as a parameter to contains, so should not throw any error. + * + * @return bool + */ + public function testContainsArrowFunction(): bool + { + return User::where('id', '>', 1)->get()->contains(fn (User $user): bool => $user->id === 2); + } + /** * Can't analyze the closure as a parameter to first, so should not throw any error. * @@ -84,6 +94,16 @@ public function testFirstClosure(): ?User }); } + /** + * Can't analyze the arrow function as a parameter to first, so should not throw any error. + * + * @return User|null + */ + public function testFirstArrowFunction(): ?User + { + return User::where('id', '>', 1)->get()->first(fn (User $user): bool => $user->id === 2); + } + /** @phpstan-return mixed */ public function testAggregateNoArgs() {