Skip to content

Commit

Permalink
Add @readonly rule that disallows default values
Browse files Browse the repository at this point in the history
  • Loading branch information
herndlm committed Jun 3, 2022
1 parent 164e35e commit 8f39f88
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 0 deletions.
5 changes: 5 additions & 0 deletions conf/config.level0.neon
Expand Up @@ -6,6 +6,8 @@ conditionalTags:
phpstan.rules.rule: %featureToggles.nodeConnectingVisitorRule%
PHPStan\Rules\Properties\MissingReadOnlyByPhpDocPropertyAssignRule:
phpstan.rules.rule: %featureToggles.readOnlyByPhpDoc%
PHPStan\Rules\Properties\ReadOnlyByPhpDocPropertyRule:
phpstan.rules.rule: %featureToggles.readOnlyByPhpDoc%
PHPStan\Rules\Properties\UninitializedPropertyRule:
phpstan.rules.rule: %checkUninitializedProperties%
PHPStan\Rules\Methods\ConsistentConstructorRule:
Expand Down Expand Up @@ -188,6 +190,9 @@ services:
tags:
- phpstan.rules.rule

-
class: PHPStan\Rules\Properties\ReadOnlyByPhpDocPropertyRule

-
class: PHPStan\Rules\Properties\UninitializedPropertyRule

Expand Down
36 changes: 36 additions & 0 deletions src/Rules/Properties/ReadOnlyByPhpDocPropertyRule.php
@@ -0,0 +1,36 @@
<?php declare(strict_types = 1);

namespace PHPStan\Rules\Properties;

use PhpParser\Node;
use PHPStan\Analyser\Scope;
use PHPStan\Node\ClassPropertyNode;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;

/**
* @implements Rule<ClassPropertyNode>
*/
class ReadOnlyByPhpDocPropertyRule implements Rule
{

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

public function processNode(Node $node, Scope $scope): array
{
if (!$node->isReadOnlyByPhpDoc()) {
return [];
}

$errors = [];
if ($node->getDefault() !== null) {
$errors[] = RuleErrorBuilder::message('@readonly property cannot have a default value.')->nonIgnorable()->build();
}

return $errors;
}

}
@@ -0,0 +1,29 @@
<?php declare(strict_types = 1);

namespace PHPStan\Rules\Properties;

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

/**
* @extends RuleTestCase<ReadOnlyByPhpDocPropertyRule>
*/
class ReadOnlyByPhpDocPropertyRuleTest extends RuleTestCase
{

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

public function testRule(): void
{
$this->analyse([__DIR__ . '/data/read-only-property-phpdoc.php'], [
[
'@readonly property cannot have a default value.',
21,
],
]);
}

}
23 changes: 23 additions & 0 deletions tests/PHPStan/Rules/Properties/data/read-only-property-phpdoc.php
@@ -0,0 +1,23 @@
<?php

namespace ReadOnlyPropertyPhpDoc;

class Foo
{

/**
* @readonly
* @var int
*/
private $foo;

/** @readonly */
private $bar;

/**
* @readonly
* @var int
*/
private $baz = 0;

}

0 comments on commit 8f39f88

Please sign in to comment.