Skip to content

Commit 66ce943

Browse files
committed
detect override of deprecated constant
1 parent c603060 commit 66ce943

File tree

4 files changed

+132
-0
lines changed

4 files changed

+132
-0
lines changed

Diff for: rules.neon

+4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ services:
1919
class: PHPStan\Rules\Deprecations\OverrideDeprecatedPropertyRule
2020
-
2121
class: PHPStan\Rules\Deprecations\OverrideDeprecatedMethodRule
22+
-
23+
class: PHPStan\Rules\Deprecations\OverrideDeprecatedConstantRule
2224

2325
rules:
2426
- PHPStan\Rules\Deprecations\AccessDeprecatedPropertyRule
@@ -43,3 +45,5 @@ conditionalTags:
4345
phpstan.rules.rule: %featureToggles.bleedingEdge%
4446
PHPStan\Rules\Deprecations\OverrideDeprecatedMethodRule:
4547
phpstan.rules.rule: %featureToggles.bleedingEdge%
48+
PHPStan\Rules\Deprecations\OverrideDeprecatedConstantRule:
49+
phpstan.rules.rule: %featureToggles.bleedingEdge%
+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules\Deprecations;
4+
5+
use PhpParser\Node;
6+
use PhpParser\Node\Stmt\ClassConst;
7+
use PHPStan\Analyser\Scope;
8+
use PHPStan\Rules\Rule;
9+
use PHPStan\Rules\RuleErrorBuilder;
10+
use function sprintf;
11+
12+
/**
13+
* @implements Rule<ClassConst>
14+
*/
15+
class OverrideDeprecatedConstantRule implements Rule
16+
{
17+
18+
/** @var DeprecatedScopeHelper */
19+
private $deprecatedScopeHelper;
20+
21+
public function __construct(DeprecatedScopeHelper $deprecatedScopeHelper)
22+
{
23+
$this->deprecatedScopeHelper = $deprecatedScopeHelper;
24+
}
25+
26+
public function getNodeType(): string
27+
{
28+
return ClassConst::class;
29+
}
30+
31+
public function processNode(Node $node, Scope $scope): array
32+
{
33+
if ($this->deprecatedScopeHelper->isScopeDeprecated($scope)) {
34+
return [];
35+
}
36+
37+
if (!$scope->isInClass()) {
38+
return [];
39+
}
40+
41+
if ($node->isPrivate()) {
42+
return [];
43+
}
44+
45+
$class = $scope->getClassReflection();
46+
47+
$parents = $class->getParents();
48+
49+
$name = (string) $node->consts[0]->name;
50+
51+
foreach ($parents as $parent) {
52+
if (!$parent->hasConstant($name)) {
53+
continue;
54+
}
55+
56+
$parentConst = $parent->getConstant($name);
57+
58+
if (!$parentConst->isDeprecated()->yes()) {
59+
return [];
60+
}
61+
62+
return [RuleErrorBuilder::message(sprintf(
63+
'Class %s overrides deprecated const %s of class %s.',
64+
$class->getName(),
65+
$name,
66+
$parent->getName()
67+
))->identifier('constant.deprecated')->build()];
68+
}
69+
70+
return [];
71+
}
72+
73+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules\Deprecations;
4+
5+
use PHPStan\Rules\Rule;
6+
use PHPStan\Testing\RuleTestCase;
7+
8+
/**
9+
* @extends RuleTestCase<OverrideDeprecatedConstantRule>
10+
*/
11+
class OverrideDeprecatedConstantRuleTest extends RuleTestCase
12+
{
13+
14+
protected function getRule(): Rule
15+
{
16+
return new OverrideDeprecatedConstantRule(new DeprecatedScopeHelper([new DefaultDeprecatedScopeResolver()]));
17+
}
18+
19+
public function testDeprecatedConstantOverride(): void
20+
{
21+
$this->analyse(
22+
[__DIR__ . '/data/override-deprecated-constant.php'],
23+
[
24+
[
25+
'Class OverrideDeprecatedConstant\Child overrides deprecated const DEPRECATED of class OverrideDeprecatedConstant\Ancestor.',
26+
20,
27+
],
28+
]
29+
);
30+
}
31+
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace OverrideDeprecatedConstant;
4+
5+
class Ancestor
6+
{
7+
/**
8+
* @deprecated
9+
*/
10+
public const DEPRECATED = '';
11+
12+
/**
13+
* @deprecated
14+
*/
15+
private const PRIVATE_DEPRECATED = '';
16+
}
17+
18+
class Child extends Ancestor
19+
{
20+
public const DEPRECATED = '';
21+
22+
private const PRIVATE_DEPRECATED = '';
23+
}

0 commit comments

Comments
 (0)