-
-
Notifications
You must be signed in to change notification settings - Fork 336
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[PHP 8.0] Add NestedAnnotationToAttribute
- Loading branch information
1 parent
7e866bb
commit 9213cb9
Showing
15 changed files
with
421 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
127 changes: 127 additions & 0 deletions
127
packages/PhpAttribute/NodeFactory/PhpNestedAttributeGroupFactory.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Rector\PhpAttribute\NodeFactory; | ||
|
||
use Nette\Utils\Strings; | ||
use PhpParser\Node\Arg; | ||
use PhpParser\Node\Attribute; | ||
use PhpParser\Node\AttributeGroup; | ||
use PhpParser\Node\Expr; | ||
use PhpParser\Node\Name; | ||
use PhpParser\Node\Name\FullyQualified; | ||
use PhpParser\Node\Stmt\Use_; | ||
use Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode; | ||
use Rector\BetterPhpDocParser\ValueObject\PhpDoc\DoctrineAnnotation\CurlyListNode; | ||
use Rector\Php80\ValueObject\NestedAnnotationToAttribute; | ||
use Rector\PhpAttribute\AnnotationToAttributeMapper; | ||
use Rector\PhpAttribute\AttributeArrayNameInliner; | ||
use Rector\PhpAttribute\NodeAnalyzer\ExprParameterReflectionTypeCorrector; | ||
|
||
final class PhpNestedAttributeGroupFactory | ||
{ | ||
public function __construct( | ||
private readonly AnnotationToAttributeMapper $annotationToAttributeMapper, | ||
private readonly AttributeNameFactory $attributeNameFactory, | ||
private readonly NamedArgsFactory $namedArgsFactory, | ||
private readonly ExprParameterReflectionTypeCorrector $exprParameterReflectionTypeCorrector, | ||
private readonly AttributeArrayNameInliner $attributeArrayNameInliner | ||
) { | ||
} | ||
|
||
/** | ||
* @param Use_[] $uses | ||
*/ | ||
public function create( | ||
DoctrineAnnotationTagValueNode $doctrineAnnotationTagValueNode, | ||
NestedAnnotationToAttribute $nestedAnnotationToAttribute, | ||
array $uses | ||
): AttributeGroup { | ||
$values = $doctrineAnnotationTagValueNode->getValuesWithExplicitSilentAndWithoutQuotes(); | ||
|
||
$args = $this->createArgsFromItems($values, $nestedAnnotationToAttribute); | ||
$args = $this->attributeArrayNameInliner->inlineArrayToArgs($args); | ||
|
||
$attributeName = $this->attributeNameFactory->create( | ||
$nestedAnnotationToAttribute, | ||
$doctrineAnnotationTagValueNode, | ||
$uses | ||
); | ||
|
||
$attribute = new Attribute($attributeName, $args); | ||
return new AttributeGroup([$attribute]); | ||
} | ||
|
||
/** | ||
* @param Use_[] $uses | ||
* @return AttributeGroup[] | ||
*/ | ||
public function createNested( | ||
DoctrineAnnotationTagValueNode $doctrineAnnotationTagValueNode, | ||
NestedAnnotationToAttribute $nestedAnnotationToAttribute, | ||
array $uses | ||
): array { | ||
$attributeGroups = []; | ||
|
||
$values = $doctrineAnnotationTagValueNode->getValuesWithExplicitSilentAndWithoutQuotes(); | ||
|
||
foreach ($nestedAnnotationToAttribute->getAnnotationPropertiesToAttributeClasses() as $itemName => $nestedAttributeClass) { | ||
$nestedValues = $values[$itemName] ?? null; | ||
if ($nestedValues === null) { | ||
continue; | ||
} | ||
|
||
if ($nestedValues instanceof CurlyListNode) { | ||
foreach ($nestedValues->getValues() as $nestedDoctrineAnnotationTagValueNode) { | ||
/** @var DoctrineAnnotationTagValueNode $nestedDoctrineAnnotationTagValueNode */ | ||
$args = $this->createArgsFromItems( | ||
$nestedDoctrineAnnotationTagValueNode->getValuesWithExplicitSilentAndWithoutQuotes(), | ||
$nestedAnnotationToAttribute | ||
); | ||
|
||
$args = $this->attributeArrayNameInliner->inlineArrayToArgs($args); | ||
|
||
$originalIdentifier = $nestedDoctrineAnnotationTagValueNode->identifierTypeNode->name; | ||
|
||
// @todo improve this hardcoded approach later | ||
if (Strings::match($originalIdentifier, '#^@ORM#')) { | ||
// or alias | ||
$shortDoctrineAttributeName = Strings::after($nestedAttributeClass, '\\', -1); | ||
$attributeName = new Name('ORM\\' . $shortDoctrineAttributeName); | ||
} else { | ||
// @todo improve aliasing | ||
$attributeName = new FullyQualified($nestedAttributeClass); | ||
} | ||
|
||
$attribute = new Attribute($attributeName, $args); | ||
$attributeGroups[] = new AttributeGroup([$attribute]); | ||
} | ||
} | ||
} | ||
|
||
return $attributeGroups; | ||
} | ||
|
||
/** | ||
* @param mixed[] $items | ||
* @return Arg[] | ||
*/ | ||
private function createArgsFromItems(array $items, NestedAnnotationToAttribute $nestedAnnotationToAttribute): array | ||
{ | ||
// remove nested items | ||
foreach (array_keys($nestedAnnotationToAttribute->getAnnotationPropertiesToAttributeClasses()) as $itemName) { | ||
unset($items[$itemName]); | ||
} | ||
|
||
/** @var Expr[]|Expr\Array_ $items */ | ||
$items = $this->annotationToAttributeMapper->map($items); | ||
|
||
$items = $this->exprParameterReflectionTypeCorrector->correctItemsByAttributeClass( | ||
$items, | ||
$nestedAnnotationToAttribute->getTag() | ||
); | ||
|
||
return $this->namedArgsFactory->createFromValues($items); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
...Property/NestedAnnotationToAttributeRector/Fixture/multiple_inversed_join_columns.php.inc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<?php | ||
|
||
namespace Rector\Tests\Php80\Rector\Property\NestedAnnotationToAttributeRector\Fixture; | ||
|
||
use Doctrine\ORM\Mapping as ORM; | ||
|
||
final class MultipleInversedJoinColumns | ||
{ | ||
/** | ||
* @ORM\JoinTable(name="join_table_name", | ||
* inverseJoinColumns={ | ||
* @ORM\JoinColumn(name="target_id"), | ||
* @ORM\JoinColumn(name="another_id") | ||
* } | ||
* ) | ||
*/ | ||
private $collection; | ||
} | ||
|
||
?> | ||
----- | ||
<?php | ||
|
||
namespace Rector\Tests\Php80\Rector\Property\NestedAnnotationToAttributeRector\Fixture; | ||
|
||
use Doctrine\ORM\Mapping as ORM; | ||
|
||
final class MultipleInversedJoinColumns | ||
{ | ||
#[ORM\JoinTable(name: 'join_table_name')] | ||
#[ORM\InverseJoinColumn(name: 'target_id')] | ||
#[ORM\InverseJoinColumn(name: 'another_id')] | ||
private $collection; | ||
} | ||
|
||
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
rules/Php80/Contract/ValueObject/AnnotationToAttributeInterface.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Rector\Php80\Contract\ValueObject; | ||
|
||
interface AnnotationToAttributeInterface | ||
{ | ||
public function getTag(): string; | ||
|
||
public function getAttributeClass(): string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Rector\Php80\NodeFactory; | ||
|
||
use PhpParser\Node\AttributeGroup; | ||
use PhpParser\Node\Stmt\Use_; | ||
use Rector\Php80\ValueObject\NestedDoctrineTagAndAnnotationToAttribute; | ||
use Rector\PhpAttribute\NodeFactory\PhpNestedAttributeGroupFactory; | ||
|
||
final class NestedAttrGroupsFactory | ||
{ | ||
public function __construct( | ||
private readonly PhpNestedAttributeGroupFactory $phpNestedAttributeGroupFactory | ||
) { | ||
} | ||
|
||
/** | ||
* @param NestedDoctrineTagAndAnnotationToAttribute[] $nestedDoctrineTagAndAnnotationToAttributes | ||
* @param Use_[] $uses | ||
* @return AttributeGroup[] | ||
*/ | ||
public function create(array $nestedDoctrineTagAndAnnotationToAttributes, array $uses): array | ||
{ | ||
$attributeGroups = []; | ||
|
||
foreach ($nestedDoctrineTagAndAnnotationToAttributes as $nestedDoctrineTagAndAnnotationToAttribute) { | ||
$doctrineAnnotationTagValueNode = $nestedDoctrineTagAndAnnotationToAttribute->getDoctrineAnnotationTagValueNode(); | ||
|
||
// add attributes | ||
$attributeGroups[] = $this->phpNestedAttributeGroupFactory->create( | ||
$doctrineAnnotationTagValueNode, | ||
$nestedDoctrineTagAndAnnotationToAttribute->getNestedAnnotationToAttribute(), | ||
$uses | ||
); | ||
|
||
$nestedAttributeGroups = $this->phpNestedAttributeGroupFactory->createNested( | ||
$doctrineAnnotationTagValueNode, | ||
$nestedDoctrineTagAndAnnotationToAttribute->getNestedAnnotationToAttribute(), | ||
$uses | ||
); | ||
|
||
$attributeGroups = array_merge($attributeGroups, $nestedAttributeGroups); | ||
} | ||
|
||
return $attributeGroups; | ||
} | ||
} |
Oops, something went wrong.