diff --git a/src/Collector/MethodCallCollector.php b/src/Collector/MethodCallCollector.php index 2d90e00..66e31d7 100644 --- a/src/Collector/MethodCallCollector.php +++ b/src/Collector/MethodCallCollector.php @@ -13,6 +13,7 @@ use PhpParser\Node\Name; use PHPStan\Analyser\Scope; use PHPStan\Collectors\Collector; +use PHPStan\Node\ClassMethodsNode; use PHPStan\Node\MethodCallableNode; use PHPStan\Node\StaticMethodCallableNode; use PHPStan\Reflection\ClassReflection; @@ -28,6 +29,11 @@ class MethodCallCollector implements Collector private ReflectionProvider $reflectionProvider; + /** + * @var list + */ + private array $callsBuffer = []; + public function __construct(ReflectionProvider $reflectionProvider) { $this->reflectionProvider = $reflectionProvider; @@ -47,23 +53,29 @@ public function processNode( ): ?array { if ($node instanceof MethodCallableNode) { // @phpstan-ignore-line ignore BC promise - return $this->registerMethodCall($node->getOriginalNode(), $scope); + $this->registerMethodCall($node->getOriginalNode(), $scope); } if ($node instanceof StaticMethodCallableNode) { // @phpstan-ignore-line ignore BC promise - return $this->registerStaticCall($node->getOriginalNode(), $scope); + $this->registerStaticCall($node->getOriginalNode(), $scope); } if ($node instanceof MethodCall || $node instanceof NullsafeMethodCall) { - return $this->registerMethodCall($node, $scope); + $this->registerMethodCall($node, $scope); } if ($node instanceof StaticCall) { - return $this->registerStaticCall($node, $scope); + $this->registerStaticCall($node, $scope); } if ($node instanceof FuncCall) { - return $this->registerFuncCall($node, $scope); + $this->registerFuncCall($node, $scope); + } + + if (!$scope->isInClass() || $node instanceof ClassMethodsNode) { // @phpstan-ignore-line ignore BC promise + $data = $this->callsBuffer; + $this->callsBuffer = []; + return $data === [] ? null : $data; // collect data once per class to save memory & resultCache size } return null; @@ -71,42 +83,34 @@ public function processNode( /** * @param NullsafeMethodCall|MethodCall $methodCall - * @return list|null */ private function registerMethodCall( CallLike $methodCall, Scope $scope - ): ?array + ): void { $methodName = $this->getMethodName($methodCall); $callerType = $scope->getType($methodCall->var); if ($methodName === null) { - return null; + return; } - $result = []; - foreach ($this->getReflectionsWithMethod($callerType, $methodName) as $classWithMethod) { $className = $classWithMethod->getMethod($methodName, $scope)->getDeclaringClass()->getName(); - $result[] = DeadCodeHelper::composeMethodKey($className, $methodName); + $this->callsBuffer[] = DeadCodeHelper::composeMethodKey($className, $methodName); } - - return $result !== [] ? $result : null; } - /** - * @return list|null - */ private function registerStaticCall( StaticCall $staticCall, Scope $scope - ): ?array + ): void { $methodName = $this->getMethodName($staticCall); if ($methodName === null) { - return null; + return; } if ($staticCall->class instanceof Expr) { @@ -124,26 +128,19 @@ private function registerStaticCall( } } - $result = []; - foreach ($classReflections as $classWithMethod) { $className = $classWithMethod->getMethod($methodName, $scope)->getDeclaringClass()->getName(); - $result[] = DeadCodeHelper::composeMethodKey($className, $methodName); + $this->callsBuffer[] = DeadCodeHelper::composeMethodKey($className, $methodName); } - - return $result !== [] ? $result : null; } - /** - * @return list|null - */ private function registerFuncCall( FuncCall $functionCall, Scope $scope - ): ?array + ): void { if (!$functionCall->name instanceof Name || $functionCall->name->toString() !== 'array_map') { // we should support all native fns - return null; + return; } $callableType = $scope->getType($functionCall->getArgs()[0]->value); @@ -152,24 +149,16 @@ private function registerFuncCall( foreach ($callableType->getConstantArrays() as $constantArray) { $callableTypeAndNames = $constantArray->findTypeAndMethodNames(); - $result = []; - foreach ($callableTypeAndNames as $typeAndName) { $methodName = $typeAndName->getMethod(); foreach ($this->getReflectionsWithMethod($typeAndName->getType(), $methodName) as $classWithMethod) { $className = $classWithMethod->getMethod($methodName, $scope)->getDeclaringClass()->getName(); - $result[] = DeadCodeHelper::composeMethodKey($className, $methodName); + $this->callsBuffer[] = DeadCodeHelper::composeMethodKey($className, $methodName); } } - - if ($result !== []) { - return $result; - } } } - - return null; } /**