[Php80] Add handle UniqueConstraint and Index on AnnotationToAttributeRector inside Entity (#994)

* [Php80] Add handle UniqueConstraint on AnnotationToAttributeRector inside Entity

* add for Index

* add join column

* eol

* eol

* temporary disable rector-doctrine from packages-tests

* temporary disable rector-doctrine from packages-tests

* debug

* loop

* [ci-review] Rector Rectify

* Fixed 🎉

* test re-enable rector-doctrine tests

* [ci-review] Rector Rectify

* [ci-review] Rector Rectify

* re-enable as fixture in rector-doctrine basically needs update not produce error

* phpstan

* [ci-review] Rector Rectify

* [ci-review] Rector Rectify

* [ci-review] Rector Rectify

* phpstan

Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
Abdul Malik Ikhsan 2021-10-13 18:58:43 +07:00 committed by GitHub
parent 78c6226bce
commit f5c1f19b54
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 175 additions and 4 deletions

View File

@ -519,3 +519,19 @@ parameters:
-
message: '#Class cognitive complexity is 31, keep it under 30#'
path: rules/Php74/Rector/Property/TypedPropertyRector.php
-
message: '#Class cognitive complexity is 55, keep it under 30#'
path: rules/Php80/Rector/Class_/AnnotationToAttributeRector.php
-
message: '#Cognitive complexity for "Rector\\Php80\\Rector\\Class_\\AnnotationToAttributeRector\:\:processDoctrineAnnotationClasses\(\)" is 33, keep it under 9#'
path: rules/Php80/Rector/Class_/AnnotationToAttributeRector.php
- # possibly bug in phpstan rule in deep foreach
message: '#foreach\(\), while\(\), for\(\) or if\(\) cannot contain a complex expression\. Extract it to a new variable on a line before#'
path: rules/Php80/Rector/Class_/AnnotationToAttributeRector.php
-
message: '#Cognitive complexity for "Rector\\Php80\\Rector\\Class_\\AnnotationToAttributeRector\:\:isNested\(\)" is 12, keep it under 9#'
path: rules/Php80/Rector/Class_/AnnotationToAttributeRector.php

View File

@ -0,0 +1,30 @@
<?php
namespace Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\Fixture;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Index;
/**
* @Entity(indexes={@Index(name="search_idx", columns={"name", "c"})}]
*/
class ECommerceProduct
{
}
?>
-----
<?php
namespace Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\Fixture;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Index;
#[\Doctrine\ORM\Mapping\Entity]
#[\Doctrine\ORM\Mapping\Index(name: 'search_idx', columns: ['name', 'c'])]
class ECommerceProduct
{
}
?>

View File

@ -0,0 +1,33 @@
<?php
namespace Rector\Doctrine\Tests\Set\DoctrineORM29Set\Fixture;
use Doctrine\ORM\Mapping as ORM;
class AnEntity
{
/**
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="entity_id", referencedColumnName="id"),
* @ORM\JoinColumn(name="entity_type", referencedColumnName="entity_type"),
* })
**/
protected $page;
}
?>
-----
<?php
namespace Rector\Doctrine\Tests\Set\DoctrineORM29Set\Fixture;
use Doctrine\ORM\Mapping as ORM;
class AnEntity
{
#[\Doctrine\ORM\Mapping\JoinColumn(name: 'entity_id', referencedColumnName: 'id')]
#[\Doctrine\ORM\Mapping\JoinColumn(name: 'entity_type', referencedColumnName: 'entity_type')]
protected $page;
}
?>

View File

@ -0,0 +1,30 @@
<?php
namespace Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\Fixture;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\UniqueConstraint;
/**
* @Entity(uniqueConstraints={@UniqueConstraint(name="ean", columns={"ean"})})
*/
class ECommerceProduct
{
}
?>
-----
<?php
namespace Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\Fixture;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\UniqueConstraint;
#[\Doctrine\ORM\Mapping\Entity]
#[\Doctrine\ORM\Mapping\UniqueConstraint(name: 'ean', columns: ['ean'])]
class ECommerceProduct
{
}
?>

View File

@ -22,6 +22,10 @@ return static function (ContainerConfigurator $containerConfigurator): void {
new AnnotationToAttribute(Response::class),
new AnnotationToAttribute('Symfony\Component\Routing\Annotation\Route'),
new AnnotationToAttribute('Doctrine\ORM\Mapping\Entity'),
new AnnotationToAttribute('Doctrine\ORM\Mapping\Index'),
new AnnotationToAttribute('Doctrine\ORM\Mapping\JoinColumn'),
new AnnotationToAttribute('Doctrine\ORM\Mapping\UniqueConstraint'),
]),
]]);
};

View File

@ -19,6 +19,7 @@ use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
use Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode;
use Rector\BetterPhpDocParser\PhpDoc\SpacelessPhpDocTagNode;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\ValueObject\PhpDoc\DoctrineAnnotation\CurlyListNode;
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\PhpVersionFeature;
@ -244,10 +245,38 @@ CODE_SAMPLE
continue;
}
$doctrineTagAndAnnotationToAttributes[] = new DoctrineTagAndAnnotationToAttribute(
$doctrineAnnotationTagValueNode,
$annotationToAttribute
);
if ($this->isNested($doctrineAnnotationTagValueNode)) {
$newDoctrineTagValueNode = new DoctrineAnnotationTagValueNode(
$doctrineAnnotationTagValueNode->identifierTypeNode
);
$doctrineTagAndAnnotationToAttributes[] = new DoctrineTagAndAnnotationToAttribute(
$newDoctrineTagValueNode,
$annotationToAttribute
);
/** @var DoctrineAnnotationTagValueNode $doctrineAnnotationTagValueNode */
$values = $doctrineAnnotationTagValueNode->getValues();
foreach ($values as $value) {
$originalValues = $value->getOriginalValues();
foreach ($originalValues as $originalValue) {
$annotationsToAttributesInNested = $this->annotationsToAttributes;
foreach ($annotationsToAttributesInNested as $annotationToAttributeInNested) {
$tag = $annotationToAttributeInNested->getTag();
if ($originalValue->hasClassName($tag)) {
$doctrineTagAndAnnotationToAttributes[] = new DoctrineTagAndAnnotationToAttribute(
$originalValue,
$annotationToAttributeInNested
);
}
}
}
}
} else {
$doctrineTagAndAnnotationToAttributes[] = new DoctrineTagAndAnnotationToAttribute(
$doctrineAnnotationTagValueNode,
$annotationToAttribute
);
}
$phpDocInfo->markAsChanged();
@ -260,4 +289,33 @@ CODE_SAMPLE
return $this->attrGroupsFactory->create($doctrineTagAndAnnotationToAttributes);
}
private function isNested(DoctrineAnnotationTagValueNode $doctrineAnnotationTagValueNode): bool
{
$values = $doctrineAnnotationTagValueNode->getValues();
foreach ($values as $value) {
// early mark as not nested to avoid false positive
if (! $value instanceof CurlyListNode) {
return false;
}
$originalValues = $value->getOriginalValues();
foreach ($originalValues as $originalValue) {
foreach ($this->annotationsToAttributes as $annotationToAttribute) {
// early mark as not nested to avoid false positive
if (! $originalValue instanceof DoctrineAnnotationTagValueNode) {
return false;
}
if (! $originalValue->hasClassName($annotationToAttribute->getTag())) {
continue;
}
return true;
}
}
}
return false;
}
}