diff --git a/config/configurable-rules.neon b/config/configurable-rules.neon index c8e82c0b..58ef076c 100644 --- a/config/configurable-rules.neon +++ b/config/configurable-rules.neon @@ -1,10 +1,4 @@ services: - - - class: Symplify\PHPStanRules\Rules\NoDuplicatedShortClassNameRule - tags: [phpstan.rules.rule] - arguments: - toleratedNestingLevel: 2 - - class: Symplify\PHPStanRules\Rules\ForbiddenNodeRule tags: [phpstan.rules.rule] diff --git a/docs/rules_overview.md b/docs/rules_overview.md index 63613e55..7f486fc2 100644 --- a/docs/rules_overview.md +++ b/docs/rules_overview.md @@ -1,4 +1,4 @@ -# 32 Rules Overview +# 31 Rules Overview ## AnnotateRegexClassConstWithRegexLinkRule @@ -415,61 +415,6 @@ class SomeClass
-## NoDuplicatedShortClassNameRule - -Class with base "%s" name is already used in "%s". Use unique name to make classes easy to recognize - -:wrench: **configure it!** - -- class: [`Symplify\PHPStanRules\Rules\NoDuplicatedShortClassNameRule`](../src/Rules/NoDuplicatedShortClassNameRule.php) - -```yaml -services: - - - class: Symplify\PHPStanRules\Rules\NoDuplicatedShortClassNameRule - tags: [phpstan.rules.rule] - arguments: - toleratedNestingLevel: 1 -``` - -↓ - -```php -namespace App; - -class SomeClass -{ -} - -namespace App\Nested; - -class SomeClass -{ -} -``` - -:x: - -
- -```php -namespace App; - -class SomeClass -{ -} - -namespace App\Nested; - -class AnotherClass -{ -} -``` - -:+1: - -
- ## NoDynamicNameRule Use explicit names over dynamic ones diff --git a/src/Rules/NoDuplicatedShortClassNameRule.php b/src/Rules/NoDuplicatedShortClassNameRule.php deleted file mode 100644 index 0c638720..00000000 --- a/src/Rules/NoDuplicatedShortClassNameRule.php +++ /dev/null @@ -1,173 +0,0 @@ - - */ - private array $declaredClassesByShortName = []; - - public function __construct( - private readonly int $toleratedNestingLevel - ) { - } - - /** - * @return class-string - */ - public function getNodeType(): string - { - return InClassNode::class; - } - - /** - * @param InClassNode $node - * @return string[] - */ - public function processNode(Node $node, Scope $scope): array - { - $classReflection = $node->getClassReflection(); - - $className = $classReflection->getName(); - if ($this->isAllowedClass($className)) { - return []; - } - - $classLike = $node->getOriginalNode(); - if (! $classLike->name instanceof Identifier) { - return []; - } - - $shortClassName = $classLike->name->toString(); - - // make sure classes are unique - $existingClassesByShortClassName = $this->resolveExistingClassesByShortClassName($shortClassName, $className); - $this->declaredClassesByShortName[$shortClassName] = $existingClassesByShortClassName; - - $classes = $this->declaredClassesByShortName[$shortClassName] ?? []; - if (count($classes) <= 1) { - return []; - } - - // is nesting level tolerated? - e.g. in case of monorepo project, it's ok to have duplicated classes in 2 levels, e.g. Symplify\\CodingStandard\\ - $classesByToleratedNamespace = []; - - $classesByShortNameCount = count($classes); - - foreach ($classes as $class) { - $toleratedNamespace = Strings::before($class, '\\', $this->toleratedNestingLevel); - $classesByToleratedNamespace[$toleratedNamespace][] = $class; - } - - $toleratedNamespaces = array_keys($classesByToleratedNamespace); - - // this namespace has many classes tolerated → skip it - if (count($toleratedNamespaces) >= $classesByShortNameCount) { - return []; - } - - $errorMessage = sprintf(self::ERROR_MESSAGE, $shortClassName, implode('", "', $classes)); - return [$errorMessage]; - } - - public function getRuleDefinition(): RuleDefinition - { - return new RuleDefinition(self::ERROR_MESSAGE, [ - new ConfiguredCodeSample( - <<<'CODE_SAMPLE' -namespace App; - -class SomeClass -{ -} - -namespace App\Nested; - -class SomeClass -{ -} -CODE_SAMPLE - , - <<<'CODE_SAMPLE' -namespace App; - -class SomeClass -{ -} - -namespace App\Nested; - -class AnotherClass -{ -} -CODE_SAMPLE - , - [ - 'toleratedNestingLevel' => 1, - ] - ), - ]); - } - - private function isAllowedClass(string $name): bool - { - // is allowed - foreach (self::ALLOWED_CLASS_NAMES as $allowedClassName) { - if (! Strings::match($name, $allowedClassName)) { - continue; - } - - return true; - } - - return false; - } - - /** - * @return string[] - */ - private function resolveExistingClassesByShortClassName(string $shortClassName, string $className): array - { - $existingClassesByShortClassName = $this->declaredClassesByShortName[$shortClassName] ?? []; - $existingClassesByShortClassName[] = $className; - - return array_unique($existingClassesByShortClassName); - } -} diff --git a/tests/Rules/NoDuplicatedShortClassNameRule/Fixture/Nested/OneMoreNested/SameShortName.php b/tests/Rules/NoDuplicatedShortClassNameRule/Fixture/Nested/OneMoreNested/SameShortName.php deleted file mode 100644 index 4503cae3..00000000 --- a/tests/Rules/NoDuplicatedShortClassNameRule/Fixture/Nested/OneMoreNested/SameShortName.php +++ /dev/null @@ -1,10 +0,0 @@ -analyse($filePaths, $expectedErrorMessagesWithLines); - } - - /** - * @return Iterator - */ - public static function provideData(): Iterator - { - // might be same, but skipped for shallow nesting - see config file - yield [ - [ - __DIR__ . '/Fixture/SkipAlreadyExistingShortName.php', - __DIR__ . '/Source/SkipAlreadyExistingShortName.php', - ], - [], - ]; - - $errorMessage = sprintf( - NoDuplicatedShortClassNameRule::ERROR_MESSAGE, - 'SameShortName', - implode( - '", "', - [SameShortName::class, - \Symplify\PHPStanRules\Tests\Rules\NoDuplicatedShortClassNameRule\Fixture\Nested\OneMoreNested\SameShortName::class, - ] - ) - ); - - yield [ - [ - __DIR__ . '/Fixture/Nested/SameShortName.php', - __DIR__ . '/Fixture/Nested/OneMoreNested/SameShortName.php', - ], - [[$errorMessage, 7]], - ]; - } - - /** - * @return string[] - */ - public static function getAdditionalConfigFiles(): array - { - return [__DIR__ . '/config/configured_rule.neon']; - } - - protected function getRule(): Rule - { - return self::getContainer()->getByType(NoDuplicatedShortClassNameRule::class); - } -} diff --git a/tests/Rules/NoDuplicatedShortClassNameRule/Source/SkipAlreadyExistingShortName.php b/tests/Rules/NoDuplicatedShortClassNameRule/Source/SkipAlreadyExistingShortName.php deleted file mode 100644 index c13c8858..00000000 --- a/tests/Rules/NoDuplicatedShortClassNameRule/Source/SkipAlreadyExistingShortName.php +++ /dev/null @@ -1,10 +0,0 @@ -