From 8f39f88b2e41acb45727036ef2b68bd5995fa470 Mon Sep 17 00:00:00 2001 From: Martin Herndl Date: Thu, 2 Jun 2022 20:31:49 +0200 Subject: [PATCH] Add @readonly rule that disallows default values --- conf/config.level0.neon | 5 +++ .../ReadOnlyByPhpDocPropertyRule.php | 36 +++++++++++++++++++ .../ReadOnlyByPhpDocPropertyRuleTest.php | 29 +++++++++++++++ .../data/read-only-property-phpdoc.php | 23 ++++++++++++ 4 files changed, 93 insertions(+) create mode 100644 src/Rules/Properties/ReadOnlyByPhpDocPropertyRule.php create mode 100644 tests/PHPStan/Rules/Properties/ReadOnlyByPhpDocPropertyRuleTest.php create mode 100644 tests/PHPStan/Rules/Properties/data/read-only-property-phpdoc.php diff --git a/conf/config.level0.neon b/conf/config.level0.neon index 95f20d25287..482aae9d648 100644 --- a/conf/config.level0.neon +++ b/conf/config.level0.neon @@ -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: @@ -188,6 +190,9 @@ services: tags: - phpstan.rules.rule + - + class: PHPStan\Rules\Properties\ReadOnlyByPhpDocPropertyRule + - class: PHPStan\Rules\Properties\UninitializedPropertyRule diff --git a/src/Rules/Properties/ReadOnlyByPhpDocPropertyRule.php b/src/Rules/Properties/ReadOnlyByPhpDocPropertyRule.php new file mode 100644 index 00000000000..e0f4b00532b --- /dev/null +++ b/src/Rules/Properties/ReadOnlyByPhpDocPropertyRule.php @@ -0,0 +1,36 @@ + + */ +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; + } + +} diff --git a/tests/PHPStan/Rules/Properties/ReadOnlyByPhpDocPropertyRuleTest.php b/tests/PHPStan/Rules/Properties/ReadOnlyByPhpDocPropertyRuleTest.php new file mode 100644 index 00000000000..b13c566b4fd --- /dev/null +++ b/tests/PHPStan/Rules/Properties/ReadOnlyByPhpDocPropertyRuleTest.php @@ -0,0 +1,29 @@ + + */ +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, + ], + ]); + } + +} diff --git a/tests/PHPStan/Rules/Properties/data/read-only-property-phpdoc.php b/tests/PHPStan/Rules/Properties/data/read-only-property-phpdoc.php new file mode 100644 index 00000000000..6522f2668b8 --- /dev/null +++ b/tests/PHPStan/Rules/Properties/data/read-only-property-phpdoc.php @@ -0,0 +1,23 @@ +