mirror of
https://github.com/rectorphp/rector.git
synced 2024-07-01 23:23:30 +00:00
[Php80] Handle named type on JMS\AccessType on AnnotationToAttributeRector (#2141)
* Add failing test for JMS AccessType * Configure rule for testing transform of JMS\AccessType * Closes #2118 * [ci-review] Rector Rectify Co-authored-by: Dominik Ritter <dritter03@googlemail.com> Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
parent
eb1090c934
commit
e4858d9a60
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\Fixture\JMS;
|
||||
|
||||
use JMS\Serializer\Annotation as JMS;
|
||||
|
||||
/**
|
||||
* @JMS\AccessType("public_method")
|
||||
*/
|
||||
class MyClass
|
||||
{
|
||||
}
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\Fixture\JMS;
|
||||
|
||||
use JMS\Serializer\Annotation as JMS;
|
||||
|
||||
#[JMS\AccessType(type: 'public_method')]
|
||||
class MyClass
|
||||
{
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\Fixture\JMS;
|
||||
|
||||
/**
|
||||
* @\JMS\Serializer\Annotation\AccessType("public_method")
|
||||
*/
|
||||
class MyClass2
|
||||
{
|
||||
}
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\Fixture\JMS;
|
||||
|
||||
#[\JMS\Serializer\Annotation\AccessType(type: 'public_method')]
|
||||
class MyClass2
|
||||
{
|
||||
}
|
||||
?>
|
|
@ -34,6 +34,9 @@ return static function (RectorConfig $rectorConfig): void {
|
|||
new AnnotationToAttribute('Symfony\Component\Validator\Constraints\All'),
|
||||
new AnnotationToAttribute('Symfony\Component\Validator\Constraints\Length'),
|
||||
|
||||
// JMS
|
||||
new AnnotationToAttribute('JMS\Serializer\Annotation\AccessType'),
|
||||
|
||||
// test for alias used
|
||||
new AnnotationToAttribute(
|
||||
'Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\Source\UseAlias\TestSmth'
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Php80\NodeManipulator;
|
||||
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Attribute;
|
||||
use PhpParser\Node\AttributeGroup;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Identifier;
|
||||
use Rector\Core\NodeAnalyzer\ArgsAnalyzer;
|
||||
|
||||
final class AttributeGroupNamedArgumentManipulator
|
||||
{
|
||||
/**
|
||||
* @var array<string, array<string, string|class-string<Expr>>>
|
||||
*/
|
||||
private const SPECIAL_CLASS_TYPES = [
|
||||
'JMS\Serializer\Annotation\AccessType' => [
|
||||
'common_aliased' => 'JMS\AccessType',
|
||||
'value' => 'PhpParser\Node\Scalar\String_',
|
||||
'name' => 'type',
|
||||
],
|
||||
];
|
||||
|
||||
public function __construct(private readonly ArgsAnalyzer $argsAnalyzer)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AttributeGroup[] $attributeGroups
|
||||
* @return AttributeGroup[]
|
||||
*/
|
||||
public function processSpecialClassTypes(array $attributeGroups): array
|
||||
{
|
||||
foreach ($attributeGroups as $attributeGroup) {
|
||||
$attrs = $attributeGroup->attrs;
|
||||
|
||||
foreach ($attrs as $attr) {
|
||||
$attrName = ltrim($attr->name->toString(), '\\');
|
||||
$this->processReplaceAttr($attr, $attrName);
|
||||
}
|
||||
}
|
||||
|
||||
return $attributeGroups;
|
||||
}
|
||||
|
||||
private function processReplaceAttr(Attribute $attribute, string $attrName): void
|
||||
{
|
||||
foreach (self::SPECIAL_CLASS_TYPES as $classType => $specialClasssType) {
|
||||
if ($attrName !== $classType && $attrName !== $specialClasssType['common_aliased']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$args = $attribute->args;
|
||||
if (count($args) !== 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! $this->argsAnalyzer->isArgInstanceInArgsPosition($args, 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/** @var Arg $currentArg */
|
||||
$currentArg = $args[0];
|
||||
if ($currentArg->name !== null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! $currentArg->value instanceof $specialClasssType['value']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$currentArg->name = new Identifier($specialClasssType['name']);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace Rector\Php80\Rector\Class_;
|
||||
|
||||
use Doctrine\Common\Annotations\Annotation\Attributes;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\AttributeGroup;
|
||||
use PhpParser\Node\Expr\ArrowFunction;
|
||||
|
@ -23,6 +24,7 @@ use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
|
|||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
use Rector\Php80\NodeFactory\AttrGroupsFactory;
|
||||
use Rector\Php80\NodeManipulator\AttributeGroupNamedArgumentManipulator;
|
||||
use Rector\Php80\PhpDoc\PhpDocNodeFinder;
|
||||
use Rector\Php80\ValueObject\AnnotationToAttribute;
|
||||
use Rector\Php80\ValueObject\DoctrineTagAndAnnotationToAttribute;
|
||||
|
@ -54,6 +56,7 @@ final class AnnotationToAttributeRector extends AbstractRector implements Config
|
|||
private readonly PhpDocNodeFinder $phpDocNodeFinder,
|
||||
private readonly UnwrapableAnnotationAnalyzer $unwrapableAnnotationAnalyzer,
|
||||
private readonly RemovableAnnotationAnalyzer $removableAnnotationAnalyzer,
|
||||
private readonly AttributeGroupNamedArgumentManipulator $attributeGroupNamedArgumentManipulator
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -129,6 +132,7 @@ CODE_SAMPLE
|
|||
return null;
|
||||
}
|
||||
|
||||
$attributeGroups = $this->attributeGroupNamedArgumentManipulator->processSpecialClassTypes($attributeGroups);
|
||||
$node->attrGroups = array_merge($node->attrGroups, $attributeGroups);
|
||||
|
||||
return $node;
|
||||
|
|
Loading…
Reference in New Issue
Block a user