diff --git a/rules-tests/CodeQuality/Rector/Property/ImproveDoctrineCollectionDocTypeInEntityRector/Fixture/OneToMany/var_and_attribute.php.inc b/rules-tests/CodeQuality/Rector/Property/ImproveDoctrineCollectionDocTypeInEntityRector/Fixture/OneToMany/var_and_attribute.php.inc index d8b12065..85cb54a6 100644 --- a/rules-tests/CodeQuality/Rector/Property/ImproveDoctrineCollectionDocTypeInEntityRector/Fixture/OneToMany/var_and_attribute.php.inc +++ b/rules-tests/CodeQuality/Rector/Property/ImproveDoctrineCollectionDocTypeInEntityRector/Fixture/OneToMany/var_and_attribute.php.inc @@ -35,14 +35,11 @@ use Rector\Doctrine\Tests\CodeQuality\Rector\Property\ImproveDoctrineCollectionD class VarAndAttribute { /** - * @var Collection + * @var \Doctrine\Common\Collections\Collection */ #[ORM\OneToMany(targetEntity:Training::class, mappedBy:"trainer")] private $trainings = []; - /** - * @param Collection|\Training[] $trainings - */ public function setTrainings($trainings) { $this->trainings = $trainings; diff --git a/rules-tests/CodeQuality/Rector/Property/ImproveDoctrineCollectionDocTypeInEntityRector/config/configured_rule.php b/rules-tests/CodeQuality/Rector/Property/ImproveDoctrineCollectionDocTypeInEntityRector/config/configured_rule.php index 82715af5..1ae2bc3e 100644 --- a/rules-tests/CodeQuality/Rector/Property/ImproveDoctrineCollectionDocTypeInEntityRector/config/configured_rule.php +++ b/rules-tests/CodeQuality/Rector/Property/ImproveDoctrineCollectionDocTypeInEntityRector/config/configured_rule.php @@ -6,5 +6,4 @@ use Rector\Doctrine\CodeQuality\Rector\Property\ImproveDoctrineCollectionDocTypeInEntityRector; return RectorConfig::configure() - ->withRules([ImproveDoctrineCollectionDocTypeInEntityRector::class]) - ->withPhpVersion(\Rector\ValueObject\PhpVersionFeature::ATTRIBUTES); + ->withRules([ImproveDoctrineCollectionDocTypeInEntityRector::class]); diff --git a/rules/CodeQuality/Rector/Property/ImproveDoctrineCollectionDocTypeInEntityRector.php b/rules/CodeQuality/Rector/Property/ImproveDoctrineCollectionDocTypeInEntityRector.php index fc71d0b0..298a9e3f 100644 --- a/rules/CodeQuality/Rector/Property/ImproveDoctrineCollectionDocTypeInEntityRector.php +++ b/rules/CodeQuality/Rector/Property/ImproveDoctrineCollectionDocTypeInEntityRector.php @@ -5,6 +5,7 @@ namespace Rector\Doctrine\CodeQuality\Rector\Property; use PhpParser\Node; +use PhpParser\Node\Attribute; use PhpParser\Node\Expr; use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\ClassMethod; @@ -126,6 +127,7 @@ private function refactorProperty(Property $property): ?Property CollectionMapping::TO_MANY_CLASSES, 'targetEntity' ); + if (! $targetEntityExpr instanceof Expr) { return null; } @@ -240,14 +242,24 @@ private function refactorPropertyPhpDocInfo(Property $property, PhpDocInfo $phpD private function refactorAttribute(Expr $expr, PhpDocInfo $phpDocInfo, Property $property): ?Property { - $phpDocVarTagValueNode = $phpDocInfo->getVarTagValueNode(); - $phpDocCollectionVarTagValueNode = $this->collectionVarTagValueNodeResolver->resolve($property); - if ($phpDocVarTagValueNode instanceof VarTagValueNode && ! $phpDocCollectionVarTagValueNode instanceof VarTagValueNode) { - return null; + $toManyAttribute = $this->attributeFinder->findAttributeByClasses( + $property, + CollectionMapping::TO_MANY_CLASSES + ); + if ($toManyAttribute instanceof Attribute) { + $targetEntityClassName = $this->targetEntityResolver->resolveFromAttribute($toManyAttribute); + } else { + $phpDocVarTagValueNode = $phpDocInfo->getVarTagValueNode(); + $phpDocCollectionVarTagValueNode = $this->collectionVarTagValueNodeResolver->resolve($property); + + if ($phpDocVarTagValueNode instanceof VarTagValueNode && ! $phpDocCollectionVarTagValueNode instanceof VarTagValueNode) { + return null; + } + + $targetEntityClassName = $this->targetEntityResolver->resolveFromExpr($expr); } - $targetEntityClassName = $this->targetEntityResolver->resolveFromExpr($expr); if ($targetEntityClassName === null) { return null; } diff --git a/src/NodeAnalyzer/TargetEntityResolver.php b/src/NodeAnalyzer/TargetEntityResolver.php index a7120da5..ef7c0f4c 100644 --- a/src/NodeAnalyzer/TargetEntityResolver.php +++ b/src/NodeAnalyzer/TargetEntityResolver.php @@ -4,8 +4,10 @@ namespace Rector\Doctrine\NodeAnalyzer; +use PhpParser\Node\Attribute; use PhpParser\Node\Expr; use PhpParser\Node\Expr\ClassConstFetch; +use PhpParser\Node\Identifier; use PhpParser\Node\Scalar\String_; use PHPStan\Reflection\ReflectionProvider; use Rector\Exception\NotImplementedYetException; @@ -19,6 +21,23 @@ public function __construct( ) { } + public function resolveFromAttribute(Attribute $attribute): ?string + { + foreach ($attribute->args as $arg) { + if (! $arg->name instanceof Identifier) { + continue; + } + + if ($arg->name->toString() !== 'targetEntity') { + continue; + } + + return $this->resolveFromExpr($arg->value); + } + + return null; + } + public function resolveFromExpr(Expr $targetEntityExpr): string|null { if ($targetEntityExpr instanceof ClassConstFetch) {