mirror of
https://github.com/rectorphp/rector.git
synced 2024-07-04 00:23:32 +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\All'),
|
||||||
new AnnotationToAttribute('Symfony\Component\Validator\Constraints\Length'),
|
new AnnotationToAttribute('Symfony\Component\Validator\Constraints\Length'),
|
||||||
|
|
||||||
|
// JMS
|
||||||
|
new AnnotationToAttribute('JMS\Serializer\Annotation\AccessType'),
|
||||||
|
|
||||||
// test for alias used
|
// test for alias used
|
||||||
new AnnotationToAttribute(
|
new AnnotationToAttribute(
|
||||||
'Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\Source\UseAlias\TestSmth'
|
'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_;
|
namespace Rector\Php80\Rector\Class_;
|
||||||
|
|
||||||
|
use Doctrine\Common\Annotations\Annotation\Attributes;
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
use PhpParser\Node\AttributeGroup;
|
use PhpParser\Node\AttributeGroup;
|
||||||
use PhpParser\Node\Expr\ArrowFunction;
|
use PhpParser\Node\Expr\ArrowFunction;
|
||||||
|
@ -23,6 +24,7 @@ use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
|
||||||
use Rector\Core\Rector\AbstractRector;
|
use Rector\Core\Rector\AbstractRector;
|
||||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||||
use Rector\Php80\NodeFactory\AttrGroupsFactory;
|
use Rector\Php80\NodeFactory\AttrGroupsFactory;
|
||||||
|
use Rector\Php80\NodeManipulator\AttributeGroupNamedArgumentManipulator;
|
||||||
use Rector\Php80\PhpDoc\PhpDocNodeFinder;
|
use Rector\Php80\PhpDoc\PhpDocNodeFinder;
|
||||||
use Rector\Php80\ValueObject\AnnotationToAttribute;
|
use Rector\Php80\ValueObject\AnnotationToAttribute;
|
||||||
use Rector\Php80\ValueObject\DoctrineTagAndAnnotationToAttribute;
|
use Rector\Php80\ValueObject\DoctrineTagAndAnnotationToAttribute;
|
||||||
|
@ -54,6 +56,7 @@ final class AnnotationToAttributeRector extends AbstractRector implements Config
|
||||||
private readonly PhpDocNodeFinder $phpDocNodeFinder,
|
private readonly PhpDocNodeFinder $phpDocNodeFinder,
|
||||||
private readonly UnwrapableAnnotationAnalyzer $unwrapableAnnotationAnalyzer,
|
private readonly UnwrapableAnnotationAnalyzer $unwrapableAnnotationAnalyzer,
|
||||||
private readonly RemovableAnnotationAnalyzer $removableAnnotationAnalyzer,
|
private readonly RemovableAnnotationAnalyzer $removableAnnotationAnalyzer,
|
||||||
|
private readonly AttributeGroupNamedArgumentManipulator $attributeGroupNamedArgumentManipulator
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,6 +132,7 @@ CODE_SAMPLE
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$attributeGroups = $this->attributeGroupNamedArgumentManipulator->processSpecialClassTypes($attributeGroups);
|
||||||
$node->attrGroups = array_merge($node->attrGroups, $attributeGroups);
|
$node->attrGroups = array_merge($node->attrGroups, $attributeGroups);
|
||||||
|
|
||||||
return $node;
|
return $node;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user