Skip to content

Commit 295d04a

Browse files
authored
Detect also overridden vendor constants (#225)
1 parent 04f976d commit 295d04a

File tree

2 files changed

+39
-9
lines changed

2 files changed

+39
-9
lines changed

src/Provider/VendorUsageProvider.php

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
use Composer\Autoload\ClassLoader;
66
use ReflectionClass;
7+
use ReflectionClassConstant;
78
use ReflectionMethod;
9+
use Reflector;
810
use function array_keys;
911
use function strlen;
1012
use function strpos;
@@ -32,24 +34,40 @@ public function shouldMarkMethodAsUsed(ReflectionMethod $method): ?VirtualUsageD
3234
return null;
3335
}
3436

35-
$reflectionClass = $method->getDeclaringClass();
36-
$methodName = $method->getName();
37+
return $this->shouldMarkMemberAsUsed($method);
38+
}
39+
40+
protected function shouldMarkConstantAsUsed(ReflectionClassConstant $constant): ?VirtualUsageData
41+
{
42+
if (!$this->enabled) {
43+
return null;
44+
}
45+
46+
return $this->shouldMarkMemberAsUsed($constant);
47+
}
3748

38-
$usage = VirtualUsageData::withNote('Method overrides vendor one, thus is expected to be used by vendor code');
49+
/**
50+
* @param ReflectionMethod|ReflectionClassConstant $member
51+
*/
52+
private function shouldMarkMemberAsUsed(Reflector $member): ?VirtualUsageData
53+
{
54+
$reflectionClass = $member->getDeclaringClass();
55+
$memberString = $member instanceof ReflectionMethod ? 'Method' : 'Constant';
56+
$usage = VirtualUsageData::withNote($memberString . ' overrides vendor one, thus is expected to be used by vendor code');
3957

4058
do {
41-
if ($this->isForeignMethod($reflectionClass, $methodName)) {
59+
if ($this->isForeignMember($reflectionClass, $member)) {
4260
return $usage;
4361
}
4462

4563
foreach ($reflectionClass->getInterfaces() as $interface) {
46-
if ($this->isForeignMethod($interface, $methodName)) {
64+
if ($this->isForeignMember($interface, $member)) {
4765
return $usage;
4866
}
4967
}
5068

5169
foreach ($reflectionClass->getTraits() as $trait) {
52-
if ($this->isForeignMethod($trait, $methodName)) {
70+
if ($this->isForeignMember($trait, $member)) {
5371
return $usage;
5472
}
5573
}
@@ -61,14 +79,19 @@ public function shouldMarkMethodAsUsed(ReflectionMethod $method): ?VirtualUsageD
6179
}
6280

6381
/**
82+
* @param ReflectionMethod|ReflectionClassConstant $member
6483
* @param ReflectionClass<object> $reflectionClass
6584
*/
66-
private function isForeignMethod(
85+
private function isForeignMember(
6786
ReflectionClass $reflectionClass,
68-
string $methodName
87+
Reflector $member
6988
): bool
7089
{
71-
if (!$reflectionClass->hasMethod($methodName)) {
90+
if ($member instanceof ReflectionMethod && !$reflectionClass->hasMethod($member->getName())) {
91+
return false;
92+
}
93+
94+
if ($member instanceof ReflectionClassConstant && !$reflectionClass->hasConstant($member->getName())) {
7295
return false;
7396
}
7497

tests/Rule/data/providers/vendor.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,20 @@
44

55
use PhpParser\Node;
66
use PHPStan\Analyser\Scope;
7+
use PHPStan\Rules\Properties\ReadWritePropertiesExtensionProvider;
78
use PHPStan\Rules\Rule as RuleFromVendor;
89

910
interface IMyRule extends RuleFromVendor
1011
{
1112
public function getNodeType(): string;
1213
}
1314

15+
interface MyPropertiesExtensionProvider extends ReadWritePropertiesExtensionProvider {
16+
17+
public const EXTENSION_TAG = 'overridden-from-vendor';
18+
19+
}
20+
1421
class MyRule implements IMyRule {
1522

1623
public function getNodeType(): string

0 commit comments

Comments
 (0)