Skip to content

Commit

Permalink
[AutoImport] Handle multiple @\ after GenericTagValueNode (#5277)
Browse files Browse the repository at this point in the history
* [AutoImport] Handle multiple @\ after GenericTagValueNode

* fixing

* reassign

* only use non-numeric key

* fix

* fix

* change back

* fix

* [ci-review] Rector Rectify

* [ci-review] Rector Rectify

---------

Co-authored-by: GitHub Action <actions@github.com>
  • Loading branch information
samsonasik and actions-user committed Nov 25, 2023
1 parent d864d7b commit 19b4201
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 9 deletions.
2 changes: 1 addition & 1 deletion packages/BetterPhpDocParser/PhpDoc/ArrayItemNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public function __toString(): string
{
$value = '';

if ($this->key !== null) {
if ($this->key !== null && ! is_numeric($this->key)) {
$value .= $this->key . '=';
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use Rector\BetterPhpDocParser\ValueObject\PhpDocAttributeKey;
use Rector\BetterPhpDocParser\ValueObject\StartAndEnd;
use Rector\Core\Util\StringUtils;
use Webmozart\Assert\Assert;

final class DoctrineAnnotationDecorator implements PhpDocNodeDecoratorInterface
{
Expand Down Expand Up @@ -217,20 +218,67 @@ private function transformGenericTagValueNodesToDoctrineAnnotationTagValueNodes(
continue;
}

$spacelessPhpDocTagNode = $this->createSpacelessPhpDocTagNode(
$phpDocChildNode->name,
$phpDocChildNode->value,
$fullyQualifiedAnnotationClass,
while (isset($phpDocNode->children[$key]) && $phpDocNode->children[$key] !== $phpDocChildNode) {
++$key;
}

$phpDocTextNode = new PhpDocTextNode($phpDocChildNode->value->value);
$startAndEnd = $phpDocChildNode->value->getAttribute(PhpDocAttributeKey::START_AND_END);

if (! $startAndEnd instanceof StartAndEnd) {
$spacelessPhpDocTagNode = $this->createSpacelessPhpDocTagNode(
$phpDocChildNode->name,
$phpDocChildNode->value,
$fullyQualifiedAnnotationClass,
$currentPhpNode
);

$this->attributeMirrorer->mirror($phpDocChildNode, $spacelessPhpDocTagNode);
$phpDocNode->children[$key] = $spacelessPhpDocTagNode;

continue;
}

$phpDocTextNode->setAttribute(PhpDocAttributeKey::START_AND_END, $startAndEnd);
$spacelessPhpDocTagNodes = $this->resolveFqnAnnotationSpacelessPhpDocTagNode(
$phpDocTextNode,
$currentPhpNode
);

$this->attributeMirrorer->mirror($phpDocChildNode, $spacelessPhpDocTagNode);
if ($spacelessPhpDocTagNodes === []) {
$spacelessPhpDocTagNode = $this->createSpacelessPhpDocTagNode(
$phpDocChildNode->name,
$phpDocChildNode->value,
$fullyQualifiedAnnotationClass,
$currentPhpNode
);

while (isset($phpDocNode->children[$key]) && $phpDocNode->children[$key] !== $phpDocChildNode) {
++$key;
$this->attributeMirrorer->mirror($phpDocChildNode, $spacelessPhpDocTagNode);
$phpDocNode->children[$key] = $spacelessPhpDocTagNode;

continue;
}

Assert::isAOf($phpDocNode->children[$key], PhpDocTagNode::class);

$texts = explode("\n@\\", $phpDocChildNode->value->value);
$phpDocNode->children[$key]->value = new GenericTagValueNode($texts[0]);
$phpDocNode->children[$key]->value->setAttribute(PhpDocAttributeKey::START_AND_END, $startAndEnd);

$spacelessPhpDocTagNode = $this->createSpacelessPhpDocTagNode(
$phpDocNode->children[$key]->name,
$phpDocNode->children[$key]->value,
$fullyQualifiedAnnotationClass,
$currentPhpNode
);

$this->attributeMirrorer->mirror($phpDocNode->children[$key], $spacelessPhpDocTagNode);
$phpDocNode->children[$key] = $spacelessPhpDocTagNode;

// require to reprint the generic
$phpDocNode->children[$key]->setAttribute(PhpDocAttributeKey::IS_AFTER_GENERIC, true);

array_splice($phpDocNode->children, $key + 1, 0, $spacelessPhpDocTagNodes);
}
}

Expand Down
7 changes: 6 additions & 1 deletion packages/BetterPhpDocParser/Printer/PhpDocInfoPrinter.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use PHPStan\PhpDocParser\Ast\PhpDoc\ThrowsTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
use PHPStan\PhpDocParser\Lexer\Lexer;
use Rector\BetterPhpDocParser\PhpDoc\SpacelessPhpDocTagNode;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocNodeVisitor\ChangedPhpDocNodeVisitor;
use Rector\BetterPhpDocParser\ValueObject\PhpDocAttributeKey;
Expand Down Expand Up @@ -341,7 +342,11 @@ private function correctPreviouslyReprintedFirstNode(int $key, StartAndEnd $star
private function shouldReprint(PhpDocChildNode $phpDocChildNode): bool
{
$this->changedPhpDocNodeTraverser->traverse($phpDocChildNode);
return $this->changedPhpDocNodeVisitor->hasChanged();
if ($this->changedPhpDocNodeVisitor->hasChanged()) {
return true;
}

return $phpDocChildNode instanceof SpacelessPhpDocTagNode && $phpDocChildNode->getAttribute(PhpDocAttributeKey::IS_AFTER_GENERIC) === true;
}

private function standardPrintPhpDocChildNode(PhpDocChildNode $phpDocChildNode): string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,9 @@ final class PhpDocAttributeKey
* @var string
*/
public const ORIG_NODE = NativePhpDocAttributeKey::ORIG_NODE;

/**
* @var string
*/
public const IS_AFTER_GENERIC = 'is_after_generic';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace Rector\Core\Tests\Issues\AutoImport\Fixture\DocBlock;

class TwoRoutesAfterGeneric
{
/**
* @OA\Property(
* type="array",
* @OA\Items(ref=@Model(type=TestItem::class))
* )
* @\Symfony\Component\Routing\Annotation\Route("/first", methods={"GET"})
* @\Symfony\Component\Routing\Annotation\Route("/second", methods={"GET"})
*/
public function some(): Response
{
return new Response();
}
}

?>
-----
<?php

namespace Rector\Core\Tests\Issues\AutoImport\Fixture\DocBlock;

use Symfony\Component\Routing\Annotation\Route;
class TwoRoutesAfterGeneric
{
/**
* @OA\Property(type="array", @OA\Items(ref=@Model(type=TestItem::class)))
* @Route("/first", methods={"GET"})
* @Route("/second", methods={"GET"})
*/
public function some(): Response
{
return new Response();
}
}

?>

0 comments on commit 19b4201

Please sign in to comment.