diff --git a/CHANGELOG.md b/CHANGELOG.md index d9ed358..3d7dd88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,18 @@ See [GitHub releases](https://github.com/mll-lab/php-utils/releases). ## Unreleased +## v5.8.0 + +### Added + +- Add PHPStan-Rule `MLL\Utils\PHPStan\Rules\ThrowableClassNameRule` + +## v5.7.0 + +### Added + +- Add PHPStan-Rule `MLL\Utils\PHPStan\Rules\VariableNameIdToIDRule` + ## v5.6.0 ### Added diff --git a/src/PHPStan/Rules/ThrowableClassNameRule.php b/src/PHPStan/Rules/ThrowableClassNameRule.php new file mode 100644 index 0000000..f549e41 --- /dev/null +++ b/src/PHPStan/Rules/ThrowableClassNameRule.php @@ -0,0 +1,51 @@ + + */ +class ThrowableClassNameRule implements Rule +{ + public function getNodeType(): string + { + return Class_::class; + } + + public function processNode(Node $node, Scope $scope): array + { + $className = (string) $node->name; + $extendsThrowable = false; + + if ($node->extends !== null) { + $parentClass = $node->extends->toString(); + $extendsThrowable = is_subclass_of($parentClass, \Throwable::class) || $parentClass === \Throwable::class; + } + + if ($extendsThrowable && ! str_ends_with($className, 'Exception')) { + return [ + RuleErrorBuilder::message(sprintf( + 'Class "%s" extends \Throwable but does not use the suffix "Exception".', + $className + ))->build(), + ]; + } + + if (! $extendsThrowable && str_ends_with($className, 'Exception')) { + return [ + RuleErrorBuilder::message(sprintf( + 'Class "%s" uses the suffix "Exception" but does not extend \Throwable. Consider using "Exemption" or another term.', + $className + ))->build(), + ]; + } + + return []; + } +}