diff --git a/phpstan.neon b/phpstan.neon index 1446fd13de6..d479d17988d 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -303,7 +303,7 @@ parameters: paths: - src/NodeNameResolver/NodeNameResolver.php - src/BetterPhpDocParser/PhpDocParser/BetterPhpDocParser.php - - src/BetterPhpDocParser/PhpDocParser/DoctrineAnnotationDecorator.php + - src/BetterPhpDocParser/NodeDecorator/DoctrineAnnotationDecorator.php - identifier: symplify.forbiddenFuncCall diff --git a/rules-tests/DeadCode/Rector/Assign/RemoveDoubleSelfAssignRector/Fixture/skip_different_variable.php.inc b/rules-tests/DeadCode/Rector/Assign/RemoveDoubleSelfAssignRector/Fixture/skip_different_variable.php.inc index 167ca86a371..a770c39349e 100644 --- a/rules-tests/DeadCode/Rector/Assign/RemoveDoubleSelfAssignRector/Fixture/skip_different_variable.php.inc +++ b/rules-tests/DeadCode/Rector/Assign/RemoveDoubleSelfAssignRector/Fixture/skip_different_variable.php.inc @@ -2,4 +2,4 @@ namespace Rector\Tests\DeadCode\Rector\Assign\RemoveDoubleSelfAssignRector\Fixture; -$first = $second = createValidator(); +$first = $second = 1234; diff --git a/src/BetterPhpDocParser/PhpDocParser/ArrayItemClassNameDecorator.php b/src/BetterPhpDocParser/NodeDecorator/ArrayItemClassNameDecorator.php similarity index 97% rename from src/BetterPhpDocParser/PhpDocParser/ArrayItemClassNameDecorator.php rename to src/BetterPhpDocParser/NodeDecorator/ArrayItemClassNameDecorator.php index 66ad52c98ff..f6c5cc0b313 100644 --- a/src/BetterPhpDocParser/PhpDocParser/ArrayItemClassNameDecorator.php +++ b/src/BetterPhpDocParser/NodeDecorator/ArrayItemClassNameDecorator.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Rector\BetterPhpDocParser\PhpDocParser; +namespace Rector\BetterPhpDocParser\NodeDecorator; use PhpParser\Node as PhpNode; use PHPStan\PhpDocParser\Ast\Node; diff --git a/src/BetterPhpDocParser/PhpDocParser/ConstExprClassNameDecorator.php b/src/BetterPhpDocParser/NodeDecorator/ConstExprClassNameDecorator.php similarity index 97% rename from src/BetterPhpDocParser/PhpDocParser/ConstExprClassNameDecorator.php rename to src/BetterPhpDocParser/NodeDecorator/ConstExprClassNameDecorator.php index d3a67f243b6..3e5f72b4ce9 100644 --- a/src/BetterPhpDocParser/PhpDocParser/ConstExprClassNameDecorator.php +++ b/src/BetterPhpDocParser/NodeDecorator/ConstExprClassNameDecorator.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Rector\BetterPhpDocParser\PhpDocParser; +namespace Rector\BetterPhpDocParser\NodeDecorator; use PhpParser\Node as PhpNode; use PHPStan\PhpDocParser\Ast\ConstExpr\ConstFetchNode; diff --git a/src/BetterPhpDocParser/PhpDocParser/DoctrineAnnotationDecorator.php b/src/BetterPhpDocParser/NodeDecorator/DoctrineAnnotationDecorator.php similarity index 99% rename from src/BetterPhpDocParser/PhpDocParser/DoctrineAnnotationDecorator.php rename to src/BetterPhpDocParser/NodeDecorator/DoctrineAnnotationDecorator.php index 505c86f9165..8ffdeb580a2 100644 --- a/src/BetterPhpDocParser/PhpDocParser/DoctrineAnnotationDecorator.php +++ b/src/BetterPhpDocParser/NodeDecorator/DoctrineAnnotationDecorator.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Rector\BetterPhpDocParser\PhpDocParser; +namespace Rector\BetterPhpDocParser\NodeDecorator; use Nette\Utils\Strings; use PhpParser\Node; @@ -21,6 +21,8 @@ use Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode; use Rector\BetterPhpDocParser\PhpDoc\SpacelessPhpDocTagNode; use Rector\BetterPhpDocParser\PhpDocInfo\TokenIteratorFactory; +use Rector\BetterPhpDocParser\PhpDocParser\ClassAnnotationMatcher; +use Rector\BetterPhpDocParser\PhpDocParser\StaticDoctrineAnnotationParser; use Rector\BetterPhpDocParser\ValueObject\DoctrineAnnotation\SilentKeyMap; use Rector\BetterPhpDocParser\ValueObject\PhpDocAttributeKey; use Rector\BetterPhpDocParser\ValueObject\StartAndEnd; diff --git a/src/BetterPhpDocParser/PhpDocParser/PhpDocTagGenericUsesDecorator.php b/src/BetterPhpDocParser/NodeDecorator/PhpDocTagGenericUsesDecorator.php similarity index 98% rename from src/BetterPhpDocParser/PhpDocParser/PhpDocTagGenericUsesDecorator.php rename to src/BetterPhpDocParser/NodeDecorator/PhpDocTagGenericUsesDecorator.php index df31fe464a9..58e97a14d2f 100644 --- a/src/BetterPhpDocParser/PhpDocParser/PhpDocTagGenericUsesDecorator.php +++ b/src/BetterPhpDocParser/NodeDecorator/PhpDocTagGenericUsesDecorator.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Rector\BetterPhpDocParser\PhpDocParser; +namespace Rector\BetterPhpDocParser\NodeDecorator; use PhpParser\Node as PhpNode; use PHPStan\PhpDocParser\Ast\Node; diff --git a/src/BetterPhpDocParser/PhpDocParser/BetterPhpDocParser.php b/src/BetterPhpDocParser/PhpDocParser/BetterPhpDocParser.php index fe9b99f2084..fc08c491ecc 100644 --- a/src/BetterPhpDocParser/PhpDocParser/BetterPhpDocParser.php +++ b/src/BetterPhpDocParser/PhpDocParser/BetterPhpDocParser.php @@ -21,6 +21,10 @@ use PHPStan\PhpDocParser\Parser\TypeParser; use PHPStan\PhpDocParser\ParserConfig; use Rector\BetterPhpDocParser\Contract\PhpDocParser\PhpDocNodeDecoratorInterface; +use Rector\BetterPhpDocParser\NodeDecorator\ArrayItemClassNameDecorator; +use Rector\BetterPhpDocParser\NodeDecorator\ConstExprClassNameDecorator; +use Rector\BetterPhpDocParser\NodeDecorator\DoctrineAnnotationDecorator; +use Rector\BetterPhpDocParser\NodeDecorator\PhpDocTagGenericUsesDecorator; use Rector\BetterPhpDocParser\PhpDocInfo\TokenIteratorFactory; use Rector\BetterPhpDocParser\ValueObject\Parser\BetterTokenIterator; use Rector\BetterPhpDocParser\ValueObject\PhpDocAttributeKey; @@ -44,16 +48,32 @@ final class BetterPhpDocParser extends PhpDocParser private const string MULTI_NEW_LINES_REGEX = '#(?\r\n|\n){2,}#'; /** - * @param PhpDocNodeDecoratorInterface[] $phpDocNodeDecorators + * @var PhpDocNodeDecoratorInterface[] */ + private readonly array $phpDocNodeDecorators; + public function __construct( ParserConfig $parserConfig, TypeParser $typeParser, ConstExprParser $constExprParser, private readonly TokenIteratorFactory $tokenIteratorFactory, - private readonly array $phpDocNodeDecorators, + ConstExprClassNameDecorator $constExprClassNameDecorator, + DoctrineAnnotationDecorator $doctrineAnnotationDecorator, + ArrayItemClassNameDecorator $arrayItemClassNameDecorator, + PhpDocTagGenericUsesDecorator $phpDocTagGenericUsesDecorator, private readonly PrivatesAccessor $privatesAccessor, ) { + // The decorator order below is significant; keep it as is. DoctrineAnnotationDecorator must + // run before ArrayItemClassNameDecorator, which resolves class names inside the array items the + // former produces. A wrong order silently drops annotation class usages and strips their imports. + // They are injected explicitly, not autodiscovered, so the order stays under our control. + $this->phpDocNodeDecorators = [ + $constExprClassNameDecorator, + $doctrineAnnotationDecorator, + $arrayItemClassNameDecorator, + $phpDocTagGenericUsesDecorator, + ]; + parent::__construct( // ParserConfig $parserConfig, diff --git a/src/DependencyInjection/LazyContainerFactory.php b/src/DependencyInjection/LazyContainerFactory.php index d420e687fad..7c60bb2a9ae 100644 --- a/src/DependencyInjection/LazyContainerFactory.php +++ b/src/DependencyInjection/LazyContainerFactory.php @@ -19,16 +19,11 @@ use Rector\Application\Provider\CurrentFileProvider; use Rector\BetterPhpDocParser\Comment\CommentsMerger; use Rector\BetterPhpDocParser\Contract\BasePhpDocNodeVisitorInterface; -use Rector\BetterPhpDocParser\Contract\PhpDocParser\PhpDocNodeDecoratorInterface; use Rector\BetterPhpDocParser\PhpDocNodeVisitor\ArrayTypePhpDocNodeVisitor; use Rector\BetterPhpDocParser\PhpDocNodeVisitor\CallableTypePhpDocNodeVisitor; use Rector\BetterPhpDocParser\PhpDocNodeVisitor\IntersectionTypeNodePhpDocNodeVisitor; use Rector\BetterPhpDocParser\PhpDocNodeVisitor\TemplatePhpDocNodeVisitor; use Rector\BetterPhpDocParser\PhpDocNodeVisitor\UnionTypeNodePhpDocNodeVisitor; -use Rector\BetterPhpDocParser\PhpDocParser\ArrayItemClassNameDecorator; -use Rector\BetterPhpDocParser\PhpDocParser\ConstExprClassNameDecorator; -use Rector\BetterPhpDocParser\PhpDocParser\DoctrineAnnotationDecorator; -use Rector\BetterPhpDocParser\PhpDocParser\PhpDocTagGenericUsesDecorator; use Rector\BetterPhpDocParser\PhpDocParser\StaticDoctrineAnnotationParser; use Rector\BetterPhpDocParser\PhpDocParser\StaticDoctrineAnnotationParser\ArrayParser; use Rector\BetterPhpDocParser\PhpDocParser\StaticDoctrineAnnotationParser\PlainValueParser; @@ -107,16 +102,6 @@ final class LazyContainerFactory DefaultValueNodeVisitor::class, ]; - /** - * @var array> - */ - private const array PHP_DOC_NODE_DECORATOR_CLASSES = [ - ConstExprClassNameDecorator::class, - DoctrineAnnotationDecorator::class, - ArrayItemClassNameDecorator::class, - PhpDocTagGenericUsesDecorator::class, - ]; - /** * @var array */ @@ -276,12 +261,6 @@ static function (AbstractRector $rector) use ($rectorConfig): void { $rectorConfig->autodiscover(__DIR__ . '/../StaticTypeMapper/PhpParser'); - $this->registerTagged( - $rectorConfig, - self::PHP_DOC_NODE_DECORATOR_CLASSES, - PhpDocNodeDecoratorInterface::class - ); - $this->registerTagged( $rectorConfig, self::BASE_PHP_DOC_NODE_VISITORS, diff --git a/src/PhpAttribute/NodeFactory/PhpNestedAttributeGroupFactory.php b/src/PhpAttribute/NodeFactory/PhpNestedAttributeGroupFactory.php index 05c62bc3c72..ad24174e6c5 100644 --- a/src/PhpAttribute/NodeFactory/PhpNestedAttributeGroupFactory.php +++ b/src/PhpAttribute/NodeFactory/PhpNestedAttributeGroupFactory.php @@ -14,10 +14,10 @@ use PhpParser\Node\Stmt\Nop; use PhpParser\Node\Stmt\Use_; use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode; +use Rector\BetterPhpDocParser\NodeDecorator\DoctrineAnnotationDecorator; use Rector\BetterPhpDocParser\PhpDoc\ArrayItemNode; use Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode; use Rector\BetterPhpDocParser\PhpDocInfo\TokenIteratorFactory; -use Rector\BetterPhpDocParser\PhpDocParser\DoctrineAnnotationDecorator; use Rector\BetterPhpDocParser\PhpDocParser\StaticDoctrineAnnotationParser; use Rector\BetterPhpDocParser\ValueObject\PhpDoc\DoctrineAnnotation\CurlyListNode; use Rector\BetterPhpDocParser\ValueObject\PhpDocAttributeKey;