Repository: symplify/symplify (php)

Issue:
[phpstan-rules][symfony] - symfony commands - false positive "missing $this->setName("...") in configure() in configure method"
Hello,

I just jumped from 10.0.9 to 10.0.21 version of symplify/phpstan-rules and I now have this error report for my commands : 

```
 The command is missing $this->setName("...") in configure() method 
 ```

but those commands have already their names defined by the `AsCommand` attribute, like this : 

```php
...
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
...

#[AsCommand(
    name: 'command:dummy',
    description: 'Dummy command',
)]
class DummyCommand extends Command
{
...
```

is there a way to activate the attribute consideration ?

Context : 
|  dependency / tech | version  |
|---|---|
|php | 8.1.2|
|symfony|5.4.4|
|phpstan|1.4.6|
|symplify/phpstan-rules|10.0.21|


Thank you !

Pull request:
[PHPStanRules] RequireNamedCommandRule - AsCommand attribute support
should fix #3929 

Patch:
diff --git a/packages/phpstan-rules/packages/symfony/src/Rules/RequireNamedCommandRule.php b/packages/phpstan-rules/packages/symfony/src/Rules/RequireNamedCommandRule.php
index 263caf0d5..44adab8f7 100644
--- a/packages/phpstan-rules/packages/symfony/src/Rules/RequireNamedCommandRule.php
+++ b/packages/phpstan-rules/packages/symfony/src/Rules/RequireNamedCommandRule.php
@@ -6,12 +6,14 @@ namespace Symplify\PHPStanRules\Symfony\Rules;
 
 use PhpParser\Node;
 use PhpParser\Node\Expr\MethodCall;
+use PhpParser\Node\Stmt\Class_;
 use PhpParser\Node\Stmt\ClassMethod;
 use PHPStan\Analyser\Scope;
 use PHPStan\Reflection\ClassReflection;
 use Symfony\Component\Console\Command\Command;
 use Symplify\Astral\Naming\SimpleNameResolver;
 use Symplify\Astral\NodeFinder\SimpleNodeFinder;
+use Symplify\PHPStanRules\NodeAnalyzer\AttributeFinder;
 use Symplify\PHPStanRules\Rules\AbstractSymplifyRule;
 use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
 use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@@ -26,9 +28,15 @@ final class RequireNamedCommandRule extends AbstractSymplifyRule
      */
     public const ERROR_MESSAGE = 'The command is missing $this->setName("...") in configure() method';
 
+    /**
+     * @var string
+     */
+    private const COMMAND_ATTRIBUTE = 'Symfony\Component\Console\Attribute\AsCommand';
+
     public function __construct(
         private SimpleNameResolver $simpleNameResolver,
         private SimpleNodeFinder $simpleNodeFinder,
+        private AttributeFinder $attributeFinder,
     ) {
     }
 
@@ -58,6 +66,10 @@ final class RequireNamedCommandRule extends AbstractSymplifyRule
             return [];
         }
 
+        if ($this->hasAsCommandAttribute($node)) {
+            return [];
+        }
+
         return [self::ERROR_MESSAGE];
     }
 
@@ -123,4 +135,14 @@ CODE_SAMPLE
 
         return $classReflection->isSubclassOf(Command::class);
     }
+
+    private function hasAsCommandAttribute(ClassMethod $node): bool
+    {
+        $class = $this->simpleNodeFinder->findFirstParentByType($node, Class_::class);
+        if (! $class instanceof Class_) {
+            return false;
+        }
+
+        return $this->attributeFinder->hasAttribute($class, self::COMMAND_ATTRIBUTE);
+    }
 }


Test patch:
diff --git a/packages/phpstan-rules/packages/symfony/tests/Rules/RequireNamedCommandRule/Fixture/SkipAttributeNamedCommand.php b/packages/phpstan-rules/packages/symfony/tests/Rules/RequireNamedCommandRule/Fixture/SkipAttributeNamedCommand.php
new file mode 100644
index 000000000..4c57ab533
--- /dev/null
+++ b/packages/phpstan-rules/packages/symfony/tests/Rules/RequireNamedCommandRule/Fixture/SkipAttributeNamedCommand.php
@@ -0,0 +1,16 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Symplify\PHPStanRules\Symfony\Tests\Rules\RequireNamedCommandRule\Fixture;
+
+use Symfony\Component\Console\Attribute\AsCommand;
+use Symfony\Component\Console\Command\Command;
+
+#[AsCommand(name: 'named')]
+final class SkipAttributeNamedCommand extends Command
+{
+    public function configure()
+    {
+    }
+}
diff --git a/packages/phpstan-rules/packages/symfony/tests/Rules/RequireNamedCommandRule/RequireNamedCommandRuleTest.php b/packages/phpstan-rules/packages/symfony/tests/Rules/RequireNamedCommandRule/RequireNamedCommandRuleTest.php
index e1964cc5e..ef8e3e5a2 100644
--- a/packages/phpstan-rules/packages/symfony/tests/Rules/RequireNamedCommandRule/RequireNamedCommandRuleTest.php
+++ b/packages/phpstan-rules/packages/symfony/tests/Rules/RequireNamedCommandRule/RequireNamedCommandRuleTest.php
@@ -27,6 +27,7 @@ final class RequireNamedCommandRuleTest extends AbstractServiceAwareRuleTestCase
     {
         yield [__DIR__ . '/Fixture/SkipNamedCommand.php', []];
         yield [__DIR__ . '/Fixture/SkipAbstractMissingNameCommand.php', []];
+        yield [__DIR__ . '/Fixture/SkipAttributeNamedCommand.php', []];
 
         yield [__DIR__ . '/Fixture/MissingNameCommand.php', [[RequireNamedCommandRule::ERROR_MESSAGE, 11]]];
     }