diff --git a/CHANGELOG.md b/CHANGELOG.md index ee7700e..459f1e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +2.1.0 (unreleased) +===== + +* (feature) Add custom PHPStan rule to detect wrong `Task` class names. + + 2.0.0 ===== diff --git a/composer.json b/composer.json index 6fcffbc..53cdeb5 100644 --- a/composer.json +++ b/composer.json @@ -20,6 +20,7 @@ "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", "composer/composer": "^2.8.9", + "phpstan/phpstan": "^2.1.17", "roave/security-advisories": "dev-latest" }, "autoload": { diff --git a/phpstan/lib.neon b/phpstan/lib.neon index 7fcba53..7ca38c0 100644 --- a/phpstan/lib.neon +++ b/phpstan/lib.neon @@ -33,3 +33,6 @@ parameters: - identifier: method.deprecated path: %currentWorkingDirectory%/tests/* + +rules: + - Janus\Phpstan\Rule\TaskRule diff --git a/src/Phpstan/Rule/TaskRule.php b/src/Phpstan/Rule/TaskRule.php new file mode 100644 index 0000000..34ea8f3 --- /dev/null +++ b/src/Phpstan/Rule/TaskRule.php @@ -0,0 +1,58 @@ + + * + * @final + */ +readonly class TaskRule implements Rule +{ + /** + * @inheritDoc + */ + #[\Override] + public function getNodeType () : string + { + return Class_::class; + } + + /** + * @inheritDoc + */ + #[\Override] + public function processNode (Node $node, Scope $scope) : array + { + \assert($node instanceof Class_); + $className = $node->name?->toString(); + + if (null === $className || !$node->extends instanceof Name) + { + return []; + } + + $extendedClassName = $node->extends->toString(); + + if ( + "Torr\\TaskManager\\Task\\Task" === $extendedClassName + && !str_ends_with($className, "Task") + ) + { + return [ + RuleErrorBuilder::message("Task classes must use the 'Task' suffix.") + ->identifier("21torr.custom.task.suffix") + ->build(), + ]; + } + + return []; + } +}