Skip to content

Commit

Permalink
detect override of deprecated constant
Browse files Browse the repository at this point in the history
  • Loading branch information
Khartir committed Mar 31, 2023
1 parent 6a3795d commit 2226d83
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 0 deletions.
4 changes: 4 additions & 0 deletions rules.neon
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ services:
class: PHPStan\Rules\Deprecations\OverrideDeprecatedPropertyRule
-
class: PHPStan\Rules\Deprecations\OverrideDeprecatedMethodRule
-
class: PHPStan\Rules\Deprecations\OverrideDeprecatedConstantRule

rules:
- PHPStan\Rules\Deprecations\AccessDeprecatedPropertyRule
Expand All @@ -32,3 +34,5 @@ conditionalTags:
phpstan.rules.rule: %featureToggles.bleedingEdge%
PHPStan\Rules\Deprecations\OverrideDeprecatedMethodRule:
phpstan.rules.rule: %featureToggles.bleedingEdge%
PHPStan\Rules\Deprecations\OverrideDeprecatedConstantRule:
phpstan.rules.rule: %featureToggles.bleedingEdge%
64 changes: 64 additions & 0 deletions src/Rules/Deprecations/OverrideDeprecatedConstantRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php declare(strict_types = 1);

namespace PHPStan\Rules\Deprecations;

use PhpParser\Node;
use PhpParser\Node\Stmt\ClassConst;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use function sprintf;

/**
* @implements Rule<ClassConst>
*/
class OverrideDeprecatedConstantRule implements Rule
{

public function getNodeType(): string
{
return ClassConst::class;
}

public function processNode(Node $node, Scope $scope): array
{
if (DeprecatedScopeHelper::isScopeDeprecated($scope)) {
return [];
}

if (!$scope->isInClass()) {
return [];
}

if ($node->isPrivate()) {
return [];
}

$class = $scope->getClassReflection();

$parents = $class->getParents();

$name = (string) $node->consts[0]->name;

foreach ($parents as $parent) {
if (!$parent->hasConstant($name)) {
continue;
}

$parentConst = $parent->getConstant($name);

if (!$parentConst->isDeprecated()->yes()) {
return [];
}

return [sprintf(
'Class %s overrides deprecated const %s of class %s.',
$class->getName(),
$name,
$parent->getName()
)];
}

return [];
}

}
32 changes: 32 additions & 0 deletions tests/Rules/Deprecations/OverrideDeprecatedConstantRuleTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php declare(strict_types = 1);

namespace PHPStan\Rules\Deprecations;

use PHPStan\Rules\Rule;
use PHPStan\Testing\RuleTestCase;

/**
* @extends RuleTestCase<OverrideDeprecatedConstantRule>
*/
class OverrideDeprecatedConstantRuleTest extends RuleTestCase
{

protected function getRule(): Rule
{
return new OverrideDeprecatedConstantRule();
}

public function testDeprecatedConstantOverride(): void
{
$this->analyse(
[__DIR__ . '/data/override-deprecated-constant.php'],
[
[
'Class OverrideDeprecatedConstant\Child overrides deprecated const FOO of class OverrideDeprecatedConstant\Foo.',
20,
],
]
);
}

}
23 changes: 23 additions & 0 deletions tests/Rules/Deprecations/data/override-deprecated-constant.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace OverrideDeprecatedConstant;

class Foo
{
/**
* @deprecated
*/
public const FOO = '';

/**
* @deprecated
*/
private const BAR = '';
}

class Child extends Foo
{
public const FOO = '';

private const BAR = '';
}

0 comments on commit 2226d83

Please sign in to comment.