Skip to content

Commit

Permalink
Add ConstantsInTraitsRule
Browse files Browse the repository at this point in the history
  • Loading branch information
paulbalandan committed Nov 8, 2023
1 parent 0205282 commit 9ea56ec
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 0 deletions.
1 change: 1 addition & 0 deletions conf/config.level0.neon
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ rules:
- PHPStan\Rules\Properties\MissingReadOnlyPropertyAssignRule
- PHPStan\Rules\Properties\PropertyAttributesRule
- PHPStan\Rules\Properties\ReadOnlyPropertyRule
- PHPStan\Rules\Traits\ConstantsInTraitsRule
- PHPStan\Rules\Variables\UnsetRule
- PHPStan\Rules\Whitespace\FileWhitespaceRule

Expand Down
5 changes: 5 additions & 0 deletions src/Php/PhpVersion.php
Original file line number Diff line number Diff line change
Expand Up @@ -232,4 +232,9 @@ public function supportsJsonValidate(): bool
return $this->versionId >= 80300;
}

public function supportsConstantsInTraits(): bool
{
return $this->versionId >= 80200;
}

}
51 changes: 51 additions & 0 deletions src/Rules/Traits/ConstantsInTraitsRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php declare(strict_types = 1);

namespace PHPStan\Rules\Traits;

use PhpParser\Node;
use PHPStan\Analyser\Scope;
use PHPStan\Php\PhpVersion;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleError;
use PHPStan\Rules\RuleErrorBuilder;
use function array_map;
use function sprintf;

/**
* @implements Rule<Node\Stmt\ClassConst>
*/
class ConstantsInTraitsRule implements Rule
{

public function __construct(private PhpVersion $phpVersion)
{
}

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

/**
* @param Node\Stmt\ClassConst $node
*/
public function processNode(Node $node, Scope $scope): array
{
if ($this->phpVersion->supportsConstantsInTraits()) {
return [];
}

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

return array_map(
static fn (Node\Const_ $const): RuleError => RuleErrorBuilder::message(sprintf(
'Constant %s is declared inside a trait but is only supported on PHP 8.2 and later.',
$const->name->toString(),
))->identifier('constants.inTraits')->nonIgnorable()->build(),
$node->consts,
);
}

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

namespace PHPStan\Rules\Traits;

use PHPStan\Php\PhpVersion;
use PHPStan\Rules\Rule;
use PHPStan\Rules\Traits\TraitConstantsCollector;
use PHPStan\Testing\RuleTestCase;

/**
* @extends RuleTestCase<ConstantsInTraitsRule>
*/
class ConstantsInTraitsRuleTest extends RuleTestCase
{

private int $phpVersionId;

protected function getRule(): Rule
{
return new ConstantsInTraitsRule(new PhpVersion($this->phpVersionId));
}

public function dataRule(): array
{
return [
[
80100,
[
[
'Constant FOO is declared inside a trait but is only supported on PHP 8.2 and later.',
7,
],
[
'Constant BAR is declared inside a trait but is only supported on PHP 8.2 and later.',
8,
],
[
'Constant QUX is declared inside a trait but is only supported on PHP 8.2 and later.',
8,
],
],
],
[
80200,
[],
],
];
}

/**
* @dataProvider dataRule
*
* @param list<array{0: string, 1: int, 2?: string}> $errors
*/
public function testRule(int $phpVersionId, array $errors): void
{
$this->phpVersionId = $phpVersionId;
$this->analyse([__DIR__ . '/data/constants-in-traits.php'], $errors);
}

}
9 changes: 9 additions & 0 deletions tests/PHPStan/Rules/Traits/data/constants-in-traits.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php // lint >= 8.2

namespace ConstantsInTraits;

trait FooBar
{
const FOO = 'foo';
public const BAR = 'bar', QUX = 'qux';
}

0 comments on commit 9ea56ec

Please sign in to comment.