Skip to content

Commit 0e6b39e

Browse files
herndlmondrejmirtes
authored andcommitted
Extract ConstructorsHelper
1 parent dd8e601 commit 0e6b39e

9 files changed

+114
-227
lines changed

build/enum-adapter-errors.neon

+15-45
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,21 @@ parameters:
200200
count: 1
201201
path: ../src/Reflection/ClassReflection.php
202202

203+
-
204+
message: "#^Call to method getMethod\\(\\) on an unknown class PHPStan\\\\BetterReflection\\\\Reflection\\\\Adapter\\\\ReflectionEnum\\.$#"
205+
count: 1
206+
path: ../src/Reflection/ConstructorsHelper.php
207+
208+
-
209+
message: "#^Call to method getName\\(\\) on an unknown class PHPStan\\\\BetterReflection\\\\Reflection\\\\Adapter\\\\ReflectionEnum\\.$#"
210+
count: 1
211+
path: ../src/Reflection/ConstructorsHelper.php
212+
213+
-
214+
message: "#^Call to method hasMethod\\(\\) on an unknown class PHPStan\\\\BetterReflection\\\\Reflection\\\\Adapter\\\\ReflectionEnum\\.$#"
215+
count: 1
216+
path: ../src/Reflection/ConstructorsHelper.php
217+
203218
-
204219
message: "#^Call to method getName\\(\\) on an unknown class PHPStan\\\\BetterReflection\\\\Reflection\\\\Adapter\\\\ReflectionEnum\\.$#"
205220
count: 1
@@ -285,51 +300,6 @@ parameters:
285300
count: 1
286301
path: ../src/Rules/Methods/MissingMethodImplementationRule.php
287302

288-
-
289-
message: "#^Call to method getMethod\\(\\) on an unknown class PHPStan\\\\BetterReflection\\\\Reflection\\\\Adapter\\\\ReflectionEnum\\.$#"
290-
count: 1
291-
path: ../src/Rules/Properties/MissingReadOnlyByPhpDocPropertyAssignRule.php
292-
293-
-
294-
message: "#^Call to method getName\\(\\) on an unknown class PHPStan\\\\BetterReflection\\\\Reflection\\\\Adapter\\\\ReflectionEnum\\.$#"
295-
count: 1
296-
path: ../src/Rules/Properties/MissingReadOnlyByPhpDocPropertyAssignRule.php
297-
298-
-
299-
message: "#^Call to method hasMethod\\(\\) on an unknown class PHPStan\\\\BetterReflection\\\\Reflection\\\\Adapter\\\\ReflectionEnum\\.$#"
300-
count: 1
301-
path: ../src/Rules/Properties/MissingReadOnlyByPhpDocPropertyAssignRule.php
302-
303-
-
304-
message: "#^Call to method getMethod\\(\\) on an unknown class PHPStan\\\\BetterReflection\\\\Reflection\\\\Adapter\\\\ReflectionEnum\\.$#"
305-
count: 1
306-
path: ../src/Rules/Properties/MissingReadOnlyPropertyAssignRule.php
307-
308-
-
309-
message: "#^Call to method getName\\(\\) on an unknown class PHPStan\\\\BetterReflection\\\\Reflection\\\\Adapter\\\\ReflectionEnum\\.$#"
310-
count: 1
311-
path: ../src/Rules/Properties/MissingReadOnlyPropertyAssignRule.php
312-
313-
-
314-
message: "#^Call to method hasMethod\\(\\) on an unknown class PHPStan\\\\BetterReflection\\\\Reflection\\\\Adapter\\\\ReflectionEnum\\.$#"
315-
count: 1
316-
path: ../src/Rules/Properties/MissingReadOnlyPropertyAssignRule.php
317-
318-
-
319-
message: "#^Call to method getMethod\\(\\) on an unknown class PHPStan\\\\BetterReflection\\\\Reflection\\\\Adapter\\\\ReflectionEnum\\.$#"
320-
count: 1
321-
path: ../src/Rules/Properties/UninitializedPropertyRule.php
322-
323-
-
324-
message: "#^Call to method getName\\(\\) on an unknown class PHPStan\\\\BetterReflection\\\\Reflection\\\\Adapter\\\\ReflectionEnum\\.$#"
325-
count: 1
326-
path: ../src/Rules/Properties/UninitializedPropertyRule.php
327-
328-
-
329-
message: "#^Call to method hasMethod\\(\\) on an unknown class PHPStan\\\\BetterReflection\\\\Reflection\\\\Adapter\\\\ReflectionEnum\\.$#"
330-
count: 1
331-
path: ../src/Rules/Properties/UninitializedPropertyRule.php
332-
333303
-
334304
message: "#^Call to method isFinal\\(\\) on an unknown class PHPStan\\\\BetterReflection\\\\Reflection\\\\Adapter\\\\ReflectionEnum\\.$#"
335305
count: 2

conf/config.level0.neon

+6-11
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ rules:
6767
- PHPStan\Rules\Operators\InvalidAssignVarRule
6868
- PHPStan\Rules\Properties\AccessPropertiesInAssignRule
6969
- PHPStan\Rules\Properties\AccessStaticPropertiesInAssignRule
70+
- PHPStan\Rules\Properties\MissingReadOnlyPropertyAssignRule
7071
- PHPStan\Rules\Properties\PropertyAttributesRule
7172
- PHPStan\Rules\Properties\ReadOnlyPropertyRule
7273
- PHPStan\Rules\Variables\UnsetRule
@@ -178,15 +179,6 @@ services:
178179

179180
-
180181
class: PHPStan\Rules\Properties\MissingReadOnlyByPhpDocPropertyAssignRule
181-
arguments:
182-
additionalConstructors: %additionalConstructors%
183-
184-
-
185-
class: PHPStan\Rules\Properties\MissingReadOnlyPropertyAssignRule
186-
arguments:
187-
additionalConstructors: %additionalConstructors%
188-
tags:
189-
- phpstan.rules.rule
190182

191183
-
192184
class: PHPStan\Rules\Properties\OverridingPropertyRule
@@ -198,8 +190,6 @@ services:
198190

199191
-
200192
class: PHPStan\Rules\Properties\UninitializedPropertyRule
201-
arguments:
202-
additionalConstructors: %additionalConstructors%
203193

204194
-
205195
class: PHPStan\Rules\Properties\WritingToReadOnlyPropertiesRule
@@ -241,3 +231,8 @@ services:
241231
globalTypeAliases: %typeAliases%
242232
tags:
243233
- phpstan.rules.rule
234+
235+
-
236+
class: PHPStan\Reflection\ConstructorsHelper
237+
arguments:
238+
additionalConstructors: %additionalConstructors%

src/Reflection/ConstructorsHelper.php

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Reflection;
4+
5+
use ReflectionException;
6+
use function array_key_exists;
7+
use function explode;
8+
9+
final class ConstructorsHelper
10+
{
11+
12+
/** @var array<string, string[]> */
13+
private array $additionalConstructorsCache = [];
14+
15+
/**
16+
* @param list<string> $additionalConstructors
17+
*/
18+
public function __construct(
19+
private array $additionalConstructors,
20+
)
21+
{
22+
}
23+
24+
/**
25+
* @return list<string>
26+
*/
27+
public function getConstructors(ClassReflection $classReflection): array
28+
{
29+
if (array_key_exists($classReflection->getName(), $this->additionalConstructorsCache)) {
30+
return $this->additionalConstructorsCache[$classReflection->getName()];
31+
}
32+
$constructors = [];
33+
if ($classReflection->hasConstructor()) {
34+
$constructors[] = $classReflection->getConstructor()->getName();
35+
}
36+
37+
$nativeReflection = $classReflection->getNativeReflection();
38+
foreach ($this->additionalConstructors as $additionalConstructor) {
39+
[$className, $methodName] = explode('::', $additionalConstructor);
40+
if (!$nativeReflection->hasMethod($methodName)) {
41+
continue;
42+
}
43+
$nativeMethod = $nativeReflection->getMethod($methodName);
44+
if ($nativeMethod->getDeclaringClass()->getName() !== $nativeReflection->getName()) {
45+
continue;
46+
}
47+
48+
try {
49+
$prototype = $nativeMethod->getPrototype();
50+
} catch (ReflectionException) {
51+
$prototype = $nativeMethod;
52+
}
53+
54+
if ($prototype->getDeclaringClass()->getName() !== $className) {
55+
continue;
56+
}
57+
58+
$constructors[] = $methodName;
59+
}
60+
61+
$this->additionalConstructorsCache[$classReflection->getName()] = $constructors;
62+
63+
return $constructors;
64+
}
65+
66+
}

src/Rules/Properties/MissingReadOnlyByPhpDocPropertyAssignRule.php

+3-54
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,10 @@
55
use PhpParser\Node;
66
use PHPStan\Analyser\Scope;
77
use PHPStan\Node\ClassPropertiesNode;
8-
use PHPStan\Reflection\ClassReflection;
8+
use PHPStan\Reflection\ConstructorsHelper;
99
use PHPStan\Rules\Rule;
1010
use PHPStan\Rules\RuleErrorBuilder;
1111
use PHPStan\ShouldNotHappenException;
12-
use ReflectionException;
13-
use function array_key_exists;
14-
use function explode;
1512
use function sprintf;
1613

1714
/**
@@ -20,14 +17,8 @@
2017
class MissingReadOnlyByPhpDocPropertyAssignRule implements Rule
2118
{
2219

23-
/** @var array<string, string[]> */
24-
private array $additionalConstructorsCache = [];
25-
26-
/**
27-
* @param string[] $additionalConstructors
28-
*/
2920
public function __construct(
30-
private array $additionalConstructors,
21+
private ConstructorsHelper $constructorsHelper,
3122
)
3223
{
3324
}
@@ -43,7 +34,7 @@ public function processNode(Node $node, Scope $scope): array
4334
throw new ShouldNotHappenException();
4435
}
4536
$classReflection = $scope->getClassReflection();
46-
[$properties, $prematureAccess, $additionalAssigns] = $node->getUninitializedProperties($scope, $this->getConstructors($classReflection), []);
37+
[$properties, $prematureAccess, $additionalAssigns] = $node->getUninitializedProperties($scope, $this->constructorsHelper->getConstructors($classReflection), []);
4738

4839
$errors = [];
4940
foreach ($properties as $propertyName => $propertyNode) {
@@ -82,46 +73,4 @@ public function processNode(Node $node, Scope $scope): array
8273
return $errors;
8374
}
8475

85-
/**
86-
* @return string[]
87-
*/
88-
private function getConstructors(ClassReflection $classReflection): array
89-
{
90-
if (array_key_exists($classReflection->getName(), $this->additionalConstructorsCache)) {
91-
return $this->additionalConstructorsCache[$classReflection->getName()];
92-
}
93-
$constructors = [];
94-
if ($classReflection->hasConstructor()) {
95-
$constructors[] = $classReflection->getConstructor()->getName();
96-
}
97-
98-
$nativeReflection = $classReflection->getNativeReflection();
99-
foreach ($this->additionalConstructors as $additionalConstructor) {
100-
[$className, $methodName] = explode('::', $additionalConstructor);
101-
if (!$nativeReflection->hasMethod($methodName)) {
102-
continue;
103-
}
104-
$nativeMethod = $nativeReflection->getMethod($methodName);
105-
if ($nativeMethod->getDeclaringClass()->getName() !== $nativeReflection->getName()) {
106-
continue;
107-
}
108-
109-
try {
110-
$prototype = $nativeMethod->getPrototype();
111-
} catch (ReflectionException) {
112-
$prototype = $nativeMethod;
113-
}
114-
115-
if ($prototype->getDeclaringClass()->getName() !== $className) {
116-
continue;
117-
}
118-
119-
$constructors[] = $methodName;
120-
}
121-
122-
$this->additionalConstructorsCache[$classReflection->getName()] = $constructors;
123-
124-
return $constructors;
125-
}
126-
12776
}

src/Rules/Properties/MissingReadOnlyPropertyAssignRule.php

+3-54
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,10 @@
55
use PhpParser\Node;
66
use PHPStan\Analyser\Scope;
77
use PHPStan\Node\ClassPropertiesNode;
8-
use PHPStan\Reflection\ClassReflection;
8+
use PHPStan\Reflection\ConstructorsHelper;
99
use PHPStan\Rules\Rule;
1010
use PHPStan\Rules\RuleErrorBuilder;
1111
use PHPStan\ShouldNotHappenException;
12-
use ReflectionException;
13-
use function array_key_exists;
14-
use function explode;
1512
use function sprintf;
1613

1714
/**
@@ -20,14 +17,8 @@
2017
class MissingReadOnlyPropertyAssignRule implements Rule
2118
{
2219

23-
/** @var array<string, string[]> */
24-
private array $additionalConstructorsCache = [];
25-
26-
/**
27-
* @param string[] $additionalConstructors
28-
*/
2920
public function __construct(
30-
private array $additionalConstructors,
21+
private ConstructorsHelper $constructorsHelper,
3122
)
3223
{
3324
}
@@ -43,7 +34,7 @@ public function processNode(Node $node, Scope $scope): array
4334
throw new ShouldNotHappenException();
4435
}
4536
$classReflection = $scope->getClassReflection();
46-
[$properties, $prematureAccess, $additionalAssigns] = $node->getUninitializedProperties($scope, $this->getConstructors($classReflection), []);
37+
[$properties, $prematureAccess, $additionalAssigns] = $node->getUninitializedProperties($scope, $this->constructorsHelper->getConstructors($classReflection), []);
4738

4839
$errors = [];
4940
foreach ($properties as $propertyName => $propertyNode) {
@@ -82,46 +73,4 @@ public function processNode(Node $node, Scope $scope): array
8273
return $errors;
8374
}
8475

85-
/**
86-
* @return string[]
87-
*/
88-
private function getConstructors(ClassReflection $classReflection): array
89-
{
90-
if (array_key_exists($classReflection->getName(), $this->additionalConstructorsCache)) {
91-
return $this->additionalConstructorsCache[$classReflection->getName()];
92-
}
93-
$constructors = [];
94-
if ($classReflection->hasConstructor()) {
95-
$constructors[] = $classReflection->getConstructor()->getName();
96-
}
97-
98-
$nativeReflection = $classReflection->getNativeReflection();
99-
foreach ($this->additionalConstructors as $additionalConstructor) {
100-
[$className, $methodName] = explode('::', $additionalConstructor);
101-
if (!$nativeReflection->hasMethod($methodName)) {
102-
continue;
103-
}
104-
$nativeMethod = $nativeReflection->getMethod($methodName);
105-
if ($nativeMethod->getDeclaringClass()->getName() !== $nativeReflection->getName()) {
106-
continue;
107-
}
108-
109-
try {
110-
$prototype = $nativeMethod->getPrototype();
111-
} catch (ReflectionException) {
112-
$prototype = $nativeMethod;
113-
}
114-
115-
if ($prototype->getDeclaringClass()->getName() !== $className) {
116-
continue;
117-
}
118-
119-
$constructors[] = $methodName;
120-
}
121-
122-
$this->additionalConstructorsCache[$classReflection->getName()] = $constructors;
123-
124-
return $constructors;
125-
}
126-
12776
}

0 commit comments

Comments
 (0)