Skip to content

Commit

Permalink
[Php80] Handle nested annotation not end with () on AnnotationToAttri…
Browse files Browse the repository at this point in the history
…buteRector (#3017)

Co-authored-by: GitHub Action <action@github.com>
  • Loading branch information
samsonasik and actions-user committed Oct 27, 2022
1 parent 478cf14 commit 4bf1587
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Scalar\String_;
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
use Rector\BetterPhpDocParser\PhpDoc\ArrayItemNode;
use Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode;
use Rector\Core\Validation\RectorAssert;
use Rector\PhpAttribute\AnnotationToAttributeMapper;
use Rector\PhpAttribute\Contract\AnnotationToAttributeMapperInterface;
use Rector\PhpAttribute\Enum\DocTagNodeState;
use Symfony\Contracts\Service\Attribute\Required;
use Webmozart\Assert\InvalidArgumentException;

/**
* @implements AnnotationToAttributeMapperInterface<ArrayItemNode>
Expand Down Expand Up @@ -55,11 +59,40 @@ public function map($arrayItemNode): Expr
/** @var Expr $keyExpr */
$keyExpr = $this->annotationToAttributeMapper->map($keyValue);
} else {
if ($this->hasNoParenthesesAnnotation($arrayItemNode)) {
try {
RectorAssert::className(ltrim((string) $arrayItemNode->value, '@'));

$identifierTypeNode = new IdentifierTypeNode($arrayItemNode->value);
$arrayItemNode->value = new DoctrineAnnotationTagValueNode($identifierTypeNode);

return $this->map($arrayItemNode);
} catch (InvalidArgumentException) {
}
}

$keyExpr = null;
}

// @todo how to skip natural integer keys?
return new ArrayItem($valueExpr, $keyExpr);
}

private function hasNoParenthesesAnnotation(ArrayItemNode $arrayItemNode): bool
{
if (is_int($arrayItemNode->kindValueQuoted)) {
return false;
}

if (! is_string($arrayItemNode->value)) {
return false;
}

if (! str_starts_with($arrayItemNode->value, '@')) {
return false;
}

return ! str_ends_with($arrayItemNode->value, ')');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\FixturePhp81;

use Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\SourcePhp81 as Assert;

final class MultipleNestedAttributeWithoutParentheses
{
/**
* @Assert\All({
* @Assert\NotNull,
* @Assert\NotNumber(secondValue=1000),
* @Assert\NotNumber(hey=10, hi="hello"),
* })
*/
public $value;
}

?>
-----
<?php

namespace Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\FixturePhp81;

use Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\SourcePhp81 as Assert;

final class MultipleNestedAttributeWithoutParentheses
{
#[Assert\All([new Assert\NotNull(), new Assert\NotNumber(secondValue: 1000), new Assert\NotNumber(hey: 10, hi: 'hello')])]
public $value;
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\FixturePhp81;

use Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\SourcePhp81 as Assert;

final class NestedAttributeWithoutParentheses
{
/**
* @Assert\All({
* @Assert\NotNull
* })
*/
public $value;
}

?>
-----
<?php

namespace Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\FixturePhp81;

use Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\SourcePhp81 as Assert;

final class NestedAttributeWithoutParentheses
{
#[Assert\All([new Assert\NotNull()])]
public $value;
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\FixturePhp81;

use Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\SourcePhp81 as Assert;

final class NestedAttributeWithoutParentheses2
{
/**
* @Assert\All({@Assert\NotNull})
*/
public $value;
}

?>
-----
<?php

namespace Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\FixturePhp81;

use Rector\Tests\Php80\Rector\Class_\AnnotationToAttributeRector\SourcePhp81 as Assert;

final class NestedAttributeWithoutParentheses2
{
#[Assert\All([new Assert\NotNull()])]
public $value;
}

?>

0 comments on commit 4bf1587

Please sign in to comment.