diff --git a/config/extension.neon b/config/extension.neon index 75caa21..0166ca6 100644 --- a/config/extension.neon +++ b/config/extension.neon @@ -98,7 +98,7 @@ services: - phpstan.collector - - class: TomasVotruba\UnusedPublic\Collectors\Callable_\CallbackFunctionCollector + class: TomasVotruba\UnusedPublic\Collectors\Callable_\CallableTypeCollector tags: - phpstan.collector diff --git a/src/Collectors/Callable_/CallbackFunctionCollector.php b/src/Collectors/Callable_/CallableTypeCollector.php similarity index 69% rename from src/Collectors/Callable_/CallbackFunctionCollector.php rename to src/Collectors/Callable_/CallableTypeCollector.php index a4a8ed4..f714b13 100644 --- a/src/Collectors/Callable_/CallbackFunctionCollector.php +++ b/src/Collectors/Callable_/CallableTypeCollector.php @@ -15,9 +15,9 @@ use TomasVotruba\UnusedPublic\Configuration; /** - * @implements Collector|null> + * @implements Collector|null> */ -final readonly class CallbackFunctionCollector implements Collector +final readonly class CallableTypeCollector implements Collector { public function __construct( private Configuration $configuration, @@ -27,11 +27,11 @@ public function __construct( public function getNodeType(): string { - return FuncCall::class; + return Expr\Array_::class; } /** - * @param FuncCall $node + * @param Expr\Array_ $node * @return string[]|null */ public function processNode(Node $node, Scope $scope): ?array @@ -40,15 +40,6 @@ public function processNode(Node $node, Scope $scope): ?array return null; } - if ($this->shouldSkipNode($node)) { - return null; - } - - $args = $node->getArgs(); - if (count($args) < 1) { - return null; - } - // skip calls in tests, as they are not used in production $classReflection = $scope->getClassReflection(); if ($classReflection instanceof ClassReflection @@ -56,7 +47,7 @@ public function processNode(Node $node, Scope $scope): ?array return null; } - $callableType = $scope->getType($args[0]->value); + $callableType = $scope->getType($node); if (! $callableType instanceof ConstantArrayType) { return null; } @@ -82,20 +73,4 @@ public function processNode(Node $node, Scope $scope): ?array return $classMethodReferences; } - /** - * @param FuncCall $node - */ - private function shouldSkipNode(Node $node): bool - { - // unable to resolve method name - if ($node->name instanceof Expr) { - return true; - } - - return !in_array( - strtolower($node->name->toString()), - ['call_user_func', 'register_shutdown_function'], - true - ); - } } diff --git a/src/NodeCollectorExtractor.php b/src/NodeCollectorExtractor.php index cad94df..0c4d8d6 100644 --- a/src/NodeCollectorExtractor.php +++ b/src/NodeCollectorExtractor.php @@ -7,7 +7,7 @@ use PHPStan\Node\CollectedDataNode; use TomasVotruba\UnusedPublic\CollectorMapper\MethodCallCollectorMapper; use TomasVotruba\UnusedPublic\Collectors\Callable_\AttributeCallableCollector; -use TomasVotruba\UnusedPublic\Collectors\Callable_\CallbackFunctionCollector; +use TomasVotruba\UnusedPublic\Collectors\Callable_\CallableTypeCollector; use TomasVotruba\UnusedPublic\Collectors\MethodCall\MethodCallableCollector; use TomasVotruba\UnusedPublic\Collectors\MethodCall\MethodCallCollector; use TomasVotruba\UnusedPublic\Collectors\StaticCall\StaticMethodCallableCollector; @@ -48,7 +48,7 @@ private function extractCollectedDatas(CollectedDataNode $collectedDataNode): ar $collectedDataNode->get(StaticMethodCallCollector::class), $collectedDataNode->get(StaticMethodCallableCollector::class), $collectedDataNode->get(AttributeCallableCollector::class), - $collectedDataNode->get(CallbackFunctionCollector::class), + $collectedDataNode->get(CallableTypeCollector::class), ]; } } diff --git a/tests/Rules/LocalOnlyPublicClassMethodRule/LocalOnlyPublicClassMethodRuleTest.php b/tests/Rules/LocalOnlyPublicClassMethodRule/LocalOnlyPublicClassMethodRuleTest.php index 6a8ee4a..7389ca4 100644 --- a/tests/Rules/LocalOnlyPublicClassMethodRule/LocalOnlyPublicClassMethodRuleTest.php +++ b/tests/Rules/LocalOnlyPublicClassMethodRule/LocalOnlyPublicClassMethodRuleTest.php @@ -10,7 +10,7 @@ use PHPStan\Testing\RuleTestCase; use PHPUnit\Framework\Attributes\DataProvider; use TomasVotruba\UnusedPublic\Collectors\Callable_\AttributeCallableCollector; -use TomasVotruba\UnusedPublic\Collectors\Callable_\CallbackFunctionCollector; +use TomasVotruba\UnusedPublic\Collectors\Callable_\CallableTypeCollector; use TomasVotruba\UnusedPublic\Collectors\MethodCall\MethodCallCollector; use TomasVotruba\UnusedPublic\Collectors\PublicClassMethodCollector; use TomasVotruba\UnusedPublic\Collectors\StaticCall\StaticMethodCallCollector; @@ -80,7 +80,7 @@ protected function getCollectors(): array self::getContainer()->getByType(MethodCallCollector::class), self::getContainer()->getByType(StaticMethodCallCollector::class), self::getContainer()->getByType(AttributeCallableCollector::class), - self::getContainer()->getByType(CallbackFunctionCollector::class), + self::getContainer()->getByType(CallableTypeCollector::class), ]; } diff --git a/tests/Rules/RelativeUnusedPublicClassMethodRule/RelativeUnusedPublicClassMethodRuleTest.php b/tests/Rules/RelativeUnusedPublicClassMethodRule/RelativeUnusedPublicClassMethodRuleTest.php index be5a0de..fb44283 100644 --- a/tests/Rules/RelativeUnusedPublicClassMethodRule/RelativeUnusedPublicClassMethodRuleTest.php +++ b/tests/Rules/RelativeUnusedPublicClassMethodRule/RelativeUnusedPublicClassMethodRuleTest.php @@ -10,7 +10,7 @@ use PHPStan\Testing\RuleTestCase; use PHPUnit\Framework\Attributes\DataProvider; use TomasVotruba\UnusedPublic\Collectors\Callable_\AttributeCallableCollector; -use TomasVotruba\UnusedPublic\Collectors\Callable_\CallbackFunctionCollector; +use TomasVotruba\UnusedPublic\Collectors\Callable_\CallableTypeCollector; use TomasVotruba\UnusedPublic\Collectors\FormTypeClassCollector; use TomasVotruba\UnusedPublic\Collectors\MethodCall\MethodCallableCollector; use TomasVotruba\UnusedPublic\Collectors\MethodCall\MethodCallCollector; @@ -64,7 +64,7 @@ protected function getCollectors(): array // callables self::getContainer()->getByType(StaticMethodCallableCollector::class), self::getContainer()->getByType(AttributeCallableCollector::class), - self::getContainer()->getByType(CallbackFunctionCollector::class), + self::getContainer()->getByType(CallableTypeCollector::class), ]; } diff --git a/tests/Rules/UnusedPublicClassMethodRule/Fixture/plain-call-custom-function.php b/tests/Rules/UnusedPublicClassMethodRule/Fixture/plain-call-custom-function.php new file mode 100644 index 0000000..691c12f --- /dev/null +++ b/tests/Rules/UnusedPublicClassMethodRule/Fixture/plain-call-custom-function.php @@ -0,0 +1,13 @@ +myMethod([$caller1, 'callIt']); + +class MyClass { + function myMethod(callable $c) {} +} diff --git a/tests/Rules/UnusedPublicClassMethodRule/UnusedPublicClassMethodRuleTest.php b/tests/Rules/UnusedPublicClassMethodRule/UnusedPublicClassMethodRuleTest.php index f03411f..7a6a454 100644 --- a/tests/Rules/UnusedPublicClassMethodRule/UnusedPublicClassMethodRuleTest.php +++ b/tests/Rules/UnusedPublicClassMethodRule/UnusedPublicClassMethodRuleTest.php @@ -10,7 +10,7 @@ use PHPStan\Testing\RuleTestCase; use PHPUnit\Framework\Attributes\DataProvider; use TomasVotruba\UnusedPublic\Collectors\Callable_\AttributeCallableCollector; -use TomasVotruba\UnusedPublic\Collectors\Callable_\CallbackFunctionCollector; +use TomasVotruba\UnusedPublic\Collectors\Callable_\CallableTypeCollector; use TomasVotruba\UnusedPublic\Collectors\FormTypeClassCollector; use TomasVotruba\UnusedPublic\Collectors\MethodCall\MethodCallableCollector; use TomasVotruba\UnusedPublic\Collectors\MethodCall\MethodCallCollector; @@ -175,6 +175,8 @@ public static function provideData(): Iterator yield [[__DIR__ . '/Fixture/plain.php', __DIR__ . '/Source/Caller1.php'], []]; yield [[__DIR__ . '/Fixture/plain-call-user-func.php', __DIR__ . '/Source/Caller1.php'], []]; yield [[__DIR__ . '/Fixture/plain-call-shutdown-function.php', __DIR__ . '/Source/Caller1.php'], []]; + yield [[__DIR__ . '/Fixture/plain-call-custom-function.php', __DIR__ . '/Source/Caller1.php'], []]; + yield [[__DIR__ . '/Fixture/plain-call-custom-method.php', __DIR__ . '/Source/Caller1.php'], []]; yield [[__DIR__ . '/Fixture/SkipCrashBug89.php.inc'], []]; yield [[__DIR__ . '/Fixture/SkipJsonSerialize.php'], []]; @@ -204,7 +206,7 @@ protected function getCollectors(): array // callables self::getContainer()->getByType(StaticMethodCallableCollector::class), self::getContainer()->getByType(AttributeCallableCollector::class), - self::getContainer()->getByType(CallbackFunctionCollector::class), + self::getContainer()->getByType(CallableTypeCollector::class), ]; }