Skip to content

Commit 3fc29fd

Browse files
authored
MethodCallCollector: emit data once per class (#30)
1 parent 6f0b3d1 commit 3fc29fd

File tree

1 file changed

+26
-37
lines changed

1 file changed

+26
-37
lines changed

src/Collector/MethodCallCollector.php

+26-37
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use PhpParser\Node\Name;
1414
use PHPStan\Analyser\Scope;
1515
use PHPStan\Collectors\Collector;
16+
use PHPStan\Node\ClassMethodsNode;
1617
use PHPStan\Node\MethodCallableNode;
1718
use PHPStan\Node\StaticMethodCallableNode;
1819
use PHPStan\Reflection\ClassReflection;
@@ -28,6 +29,11 @@ class MethodCallCollector implements Collector
2829

2930
private ReflectionProvider $reflectionProvider;
3031

32+
/**
33+
* @var list<string>
34+
*/
35+
private array $callsBuffer = [];
36+
3137
public function __construct(ReflectionProvider $reflectionProvider)
3238
{
3339
$this->reflectionProvider = $reflectionProvider;
@@ -47,66 +53,64 @@ public function processNode(
4753
): ?array
4854
{
4955
if ($node instanceof MethodCallableNode) { // @phpstan-ignore-line ignore BC promise
50-
return $this->registerMethodCall($node->getOriginalNode(), $scope);
56+
$this->registerMethodCall($node->getOriginalNode(), $scope);
5157
}
5258

5359
if ($node instanceof StaticMethodCallableNode) { // @phpstan-ignore-line ignore BC promise
54-
return $this->registerStaticCall($node->getOriginalNode(), $scope);
60+
$this->registerStaticCall($node->getOriginalNode(), $scope);
5561
}
5662

5763
if ($node instanceof MethodCall || $node instanceof NullsafeMethodCall) {
58-
return $this->registerMethodCall($node, $scope);
64+
$this->registerMethodCall($node, $scope);
5965
}
6066

6167
if ($node instanceof StaticCall) {
62-
return $this->registerStaticCall($node, $scope);
68+
$this->registerStaticCall($node, $scope);
6369
}
6470

6571
if ($node instanceof FuncCall) {
66-
return $this->registerFuncCall($node, $scope);
72+
$this->registerFuncCall($node, $scope);
73+
}
74+
75+
if (!$scope->isInClass() || $node instanceof ClassMethodsNode) { // @phpstan-ignore-line ignore BC promise
76+
$data = $this->callsBuffer;
77+
$this->callsBuffer = [];
78+
return $data === [] ? null : $data; // collect data once per class to save memory & resultCache size
6779
}
6880

6981
return null;
7082
}
7183

7284
/**
7385
* @param NullsafeMethodCall|MethodCall $methodCall
74-
* @return list<string>|null
7586
*/
7687
private function registerMethodCall(
7788
CallLike $methodCall,
7889
Scope $scope
79-
): ?array
90+
): void
8091
{
8192
$methodName = $this->getMethodName($methodCall);
8293
$callerType = $scope->getType($methodCall->var);
8394

8495
if ($methodName === null) {
85-
return null;
96+
return;
8697
}
8798

88-
$result = [];
89-
9099
foreach ($this->getReflectionsWithMethod($callerType, $methodName) as $classWithMethod) {
91100
$className = $classWithMethod->getMethod($methodName, $scope)->getDeclaringClass()->getName();
92-
$result[] = DeadCodeHelper::composeMethodKey($className, $methodName);
101+
$this->callsBuffer[] = DeadCodeHelper::composeMethodKey($className, $methodName);
93102
}
94-
95-
return $result !== [] ? $result : null;
96103
}
97104

98-
/**
99-
* @return list<string>|null
100-
*/
101105
private function registerStaticCall(
102106
StaticCall $staticCall,
103107
Scope $scope
104-
): ?array
108+
): void
105109
{
106110
$methodName = $this->getMethodName($staticCall);
107111

108112
if ($methodName === null) {
109-
return null;
113+
return;
110114
}
111115

112116
if ($staticCall->class instanceof Expr) {
@@ -124,26 +128,19 @@ private function registerStaticCall(
124128
}
125129
}
126130

127-
$result = [];
128-
129131
foreach ($classReflections as $classWithMethod) {
130132
$className = $classWithMethod->getMethod($methodName, $scope)->getDeclaringClass()->getName();
131-
$result[] = DeadCodeHelper::composeMethodKey($className, $methodName);
133+
$this->callsBuffer[] = DeadCodeHelper::composeMethodKey($className, $methodName);
132134
}
133-
134-
return $result !== [] ? $result : null;
135135
}
136136

137-
/**
138-
* @return list<string>|null
139-
*/
140137
private function registerFuncCall(
141138
FuncCall $functionCall,
142139
Scope $scope
143-
): ?array
140+
): void
144141
{
145142
if (!$functionCall->name instanceof Name || $functionCall->name->toString() !== 'array_map') { // we should support all native fns
146-
return null;
143+
return;
147144
}
148145

149146
$callableType = $scope->getType($functionCall->getArgs()[0]->value);
@@ -152,24 +149,16 @@ private function registerFuncCall(
152149
foreach ($callableType->getConstantArrays() as $constantArray) {
153150
$callableTypeAndNames = $constantArray->findTypeAndMethodNames();
154151

155-
$result = [];
156-
157152
foreach ($callableTypeAndNames as $typeAndName) {
158153
$methodName = $typeAndName->getMethod();
159154

160155
foreach ($this->getReflectionsWithMethod($typeAndName->getType(), $methodName) as $classWithMethod) {
161156
$className = $classWithMethod->getMethod($methodName, $scope)->getDeclaringClass()->getName();
162-
$result[] = DeadCodeHelper::composeMethodKey($className, $methodName);
157+
$this->callsBuffer[] = DeadCodeHelper::composeMethodKey($className, $methodName);
163158
}
164159
}
165-
166-
if ($result !== []) {
167-
return $result;
168-
}
169160
}
170161
}
171-
172-
return null;
173162
}
174163

175164
/**

0 commit comments

Comments
 (0)