Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace Rector\BetterPhpDocParser\Contract\PhpDocNode;

interface SilentKeyNodeInterface
{
public function getSilentKey(): string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode;
use Rector\BetterPhpDocParser\Attributes\Attribute\AttributeTrait;
use Rector\BetterPhpDocParser\Contract\PhpDocNode\AttributeAwareNodeInterface;
use Rector\BetterPhpDocParser\Contract\PhpDocNode\SilentKeyNodeInterface;
use Rector\BetterPhpDocParser\Contract\PhpDocNode\TagAwareNodeInterface;
use Rector\BetterPhpDocParser\Utils\ArrayItemStaticHelper;

Expand Down Expand Up @@ -67,6 +68,12 @@ abstract class AbstractTagValueNode implements AttributeAwareNodeInterface, PhpD
*/
private $keysByQuotedStatus = [];

public function __construct($annotationOrItems, ?string $originalContent = null)
{
$this->items = $this->resolveItems($annotationOrItems);
$this->resolveOriginalContentSpacingAndOrder($originalContent);
}

/**
* Generic fallback
*/
Expand Down Expand Up @@ -183,11 +190,14 @@ protected function printNestedTag(
protected function resolveOriginalContentSpacingAndOrder(?string $originalContent, ?string $silentKey = null): void
{
$this->keysByQuotedStatus = [];

if ($originalContent === null) {
return;
}

if ($silentKey === null && $this instanceof SilentKeyNodeInterface) {
$silentKey = $this->getSilentKey();
}

$this->originalContent = $originalContent;
$this->orderedVisibleItems = ArrayItemStaticHelper::resolveAnnotationItemsOrder($originalContent, $silentKey);

Expand Down Expand Up @@ -293,4 +303,20 @@ private function createQuotedKeyPattern(?string $silentKey, string $key, string
// @see https://regex101.com/r/VgvK8C/3/
return sprintf('#%s="#', $escapedKey);
}

/**
* @param object|mixed[] $annotationOrItems
*/
private function resolveItems($annotationOrItems): array
{
if (is_array($annotationOrItems)) {
return $annotationOrItems;
}

if (is_object($annotationOrItems)) {
return get_object_vars($annotationOrItems);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TomasVotruba For some reason, this breaks Rector in my application. A Symfony\Component\Routing\Annotation\Route object returns [] in my case.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll try to find out why it fails in my application while the tests are OK, but it's hard to keep up with your development speed at this moment.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for such a fast testing, wow!

That's caused by Route annotation having private properties (made fake public in tests here for now) and get_object_vars() works only on public ones.

Do you have idea how to get into private properties of an object? Effectively.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR tests this bug, see: #3285

}

return [];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,10 @@

namespace Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Class_;

use Doctrine\ORM\Mapping\Embeddable;
use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\AbstractDoctrineTagValueNode;

final class EmbeddableTagValueNode extends AbstractDoctrineTagValueNode
{
public function __construct(Embeddable $embeddable, string $originalContent)
{
$this->items = get_object_vars($embeddable);
$this->resolveOriginalContentSpacingAndOrder($originalContent);
}

public function getShortName(): string
{
return '@ORM\Embeddable';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Class_;

use Doctrine\ORM\Mapping\Entity;
use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\AbstractDoctrineTagValueNode;
use Rector\PhpAttribute\Contract\PhpAttributableTagNodeInterface;
use Rector\PhpAttribute\PhpDocNode\PhpAttributePhpDocNodePrintTrait;
Expand All @@ -13,15 +12,6 @@ final class EntityTagValueNode extends AbstractDoctrineTagValueNode implements P
{
use PhpAttributePhpDocNodePrintTrait;

public function __construct(?Entity $entity = null, ?string $originalContent = null)
{
if ($entity !== null) {
$this->items = get_object_vars($entity);
}

$this->resolveOriginalContentSpacingAndOrder($originalContent);
}

public function removeRepositoryClass(): void
{
$this->items['repositoryClass'] = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,18 @@

namespace Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Class_;

use Doctrine\ORM\Mapping\InheritanceType;
use Rector\BetterPhpDocParser\Contract\PhpDocNode\SilentKeyNodeInterface;
use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\AbstractDoctrineTagValueNode;

final class InheritanceTypeTagValueNode extends AbstractDoctrineTagValueNode
final class InheritanceTypeTagValueNode extends AbstractDoctrineTagValueNode implements SilentKeyNodeInterface
{
public function __construct(InheritanceType $inheritanceType, ?string $originalContent)
public function getShortName(): string
{
$this->items = get_object_vars($inheritanceType);

$this->resolveOriginalContentSpacingAndOrder($originalContent, 'value');
return '@ORM\InheritanceType';
}

public function getShortName(): string
public function getSilentKey(): string
{
return '@ORM\InheritanceType';
return 'value';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@

namespace Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Class_;

use Rector\BetterPhpDocParser\Contract\PhpDocNode\SilentKeyNodeInterface;
use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\AbstractDoctrineTagValueNode;

final class TableTagValueNode extends AbstractDoctrineTagValueNode
final class TableTagValueNode extends AbstractDoctrineTagValueNode implements SilentKeyNodeInterface
{
/**
* @var string|null
Expand Down Expand Up @@ -102,7 +103,6 @@ public function __toString(): string
{
$items = $this->createItems();
$items = $this->makeKeysExplicit($items);

return $this->printContentItems($items);
}

Expand All @@ -111,6 +111,11 @@ public function getShortName(): string
return '@ORM\Table';
}

public function getSilentKey(): string
{
return 'name';
}

private function createItems(): array
{
$items = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Property_;

use Doctrine\ORM\Mapping\Column;
use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\AbstractDoctrineTagValueNode;
use Rector\PhpAttribute\Contract\PhpAttributableTagNodeInterface;
use Rector\PhpAttribute\PhpDocNode\PhpAttributePhpDocNodePrintTrait;
Expand All @@ -13,18 +12,6 @@ final class ColumnTagValueNode extends AbstractDoctrineTagValueNode implements P
{
use PhpAttributePhpDocNodePrintTrait;

public function __construct($items, ?string $originalContent = null)
{
$this->items = $items;
$this->resolveOriginalContentSpacingAndOrder($originalContent);
}

public static function fromColumnAndOriginalContent(Column $column, string $originalContent): self
{
$items = get_object_vars($column);
return new self($items, $originalContent);
}

public function changeType(string $type): void
{
$this->items['type'] = $type;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,10 @@

namespace Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Property_;

use Doctrine\ORM\Mapping\CustomIdGenerator;
use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\AbstractDoctrineTagValueNode;

final class CustomIdGeneratorTagValueNode extends AbstractDoctrineTagValueNode
{
public function __construct(CustomIdGenerator $customIdGenerator, ?string $originalContent = null)
{
$this->items = get_object_vars($customIdGenerator);
$this->resolveOriginalContentSpacingAndOrder($originalContent);
}

public function getShortName(): string
{
return '@ORM\CustomIdGenerator';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,18 @@

namespace Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Property_;

use Doctrine\ORM\Mapping\GeneratedValue;
use Rector\BetterPhpDocParser\Contract\PhpDocNode\SilentKeyNodeInterface;
use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\AbstractDoctrineTagValueNode;
use Rector\PhpAttribute\Contract\PhpAttributableTagNodeInterface;
use Rector\PhpAttribute\PhpDocNode\PhpAttributePhpDocNodePrintTrait;

/**
* @see \Rector\BetterPhpDocParser\Tests\PhpDocParser\TagValueNodeReprint\TagValueNodeReprintTest
*/
final class GeneratedValueTagValueNode extends AbstractDoctrineTagValueNode implements PhpAttributableTagNodeInterface
final class GeneratedValueTagValueNode extends AbstractDoctrineTagValueNode implements PhpAttributableTagNodeInterface, SilentKeyNodeInterface
{
use PhpAttributePhpDocNodePrintTrait;

public function __construct(array $items, ?string $annotationContent = null)
{
$this->items = $items;
$this->resolveOriginalContentSpacingAndOrder($annotationContent, 'strategy');
}

public static function createFromAnnotationAndContent(
GeneratedValue $generatedValue,
string $annotationContent
): self {
$items = get_object_vars($generatedValue);
return new self($items, $annotationContent);
}

public function getShortName(): string
{
return '@ORM\GeneratedValue';
Expand All @@ -40,4 +26,9 @@ public function toAttributeString(): string
// @todo add strategy
return $this->printAttributeContent();
}

public function getSilentKey(): string
{
return 'strategy';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ final class IdTagValueNode extends AbstractDoctrineTagValueNode implements PhpAt
{
use PhpAttributePhpDocNodePrintTrait;

public function __construct(?string $annotationContent = null)
public function __construct(array $items = [], ?string $originalContent = null)
{
$this->resolveOriginalContentSpacingAndOrder($annotationContent);
parent::__construct($items, $originalContent);
}

public function getShortName(): string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,11 @@

namespace Rector\BetterPhpDocParser\PhpDocNode\Gedmo;

use Gedmo\Mapping\Annotation\Blameable;
use Rector\BetterPhpDocParser\Contract\PhpDocNode\ShortNameAwareTagInterface;
use Rector\BetterPhpDocParser\PhpDocNode\AbstractTagValueNode;

final class BlameableTagValueNode extends AbstractTagValueNode implements ShortNameAwareTagInterface
{
public function __construct(Blameable $blameable)
{
$this->items = get_object_vars($blameable);
}

public function getShortName(): string
{
return '@Gedmo\Blameable';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,11 @@

namespace Rector\BetterPhpDocParser\PhpDocNode\Gedmo;

use Gedmo\Mapping\Annotation\Loggable;
use Rector\BetterPhpDocParser\Contract\PhpDocNode\ShortNameAwareTagInterface;
use Rector\BetterPhpDocParser\PhpDocNode\AbstractTagValueNode;

final class LoggableTagValueNode extends AbstractTagValueNode implements ShortNameAwareTagInterface
{
public function __construct(Loggable $loggable)
{
$this->items = get_object_vars($loggable);
}

public function getShortName(): string
{
return '@Gedmo\Loggable';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,12 @@

namespace Rector\BetterPhpDocParser\PhpDocNode\Gedmo;

use Gedmo\Mapping\Annotation\Slug;
use Rector\BetterPhpDocParser\Contract\PhpDocNode\ShortNameAwareTagInterface;
use Rector\BetterPhpDocParser\Contract\PhpDocNode\SilentKeyNodeInterface;
use Rector\BetterPhpDocParser\PhpDocNode\AbstractTagValueNode;

final class SlugTagValueNode extends AbstractTagValueNode implements ShortNameAwareTagInterface
final class SlugTagValueNode extends AbstractTagValueNode implements ShortNameAwareTagInterface, SilentKeyNodeInterface
{
public function __construct(Slug $slug, ?string $originalContent = null)
{
$this->items = get_object_vars($slug);
$this->resolveOriginalContentSpacingAndOrder($originalContent, 'fields');
}

public function getFields(): array
{
return $this->items['fields'];
Expand All @@ -25,4 +19,9 @@ public function getShortName(): string
{
return '@Gedmo\Slug';
}

public function getSilentKey(): string
{
return 'fields';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,11 @@

namespace Rector\BetterPhpDocParser\PhpDocNode\Gedmo;

use Gedmo\Mapping\Annotation\SoftDeleteable;
use Rector\BetterPhpDocParser\Contract\PhpDocNode\ShortNameAwareTagInterface;
use Rector\BetterPhpDocParser\PhpDocNode\AbstractTagValueNode;

final class SoftDeleteableTagValueNode extends AbstractTagValueNode implements ShortNameAwareTagInterface
{
public function __construct(SoftDeleteable $softDeleteable)
{
$this->items = get_object_vars($softDeleteable);
}

public function getFieldName(): string
{
return $this->items['fieldName'];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,8 @@

namespace Rector\BetterPhpDocParser\PhpDocNode\Gedmo;

use Gedmo\Mapping\Annotation\Tree;
use Rector\BetterPhpDocParser\PhpDocNode\AbstractTagValueNode;

final class TreeTagValueNode extends AbstractTagValueNode
{
public function __construct(Tree $tree)
{
$this->items = get_object_vars($tree);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,11 @@

namespace Rector\BetterPhpDocParser\PhpDocNode\JMS;

use JMS\DiExtraBundle\Annotation\InjectParams;
use Rector\BetterPhpDocParser\Contract\PhpDocNode\ShortNameAwareTagInterface;
use Rector\BetterPhpDocParser\PhpDocNode\AbstractTagValueNode;

final class JMSInjectParamsTagValueNode extends AbstractTagValueNode implements ShortNameAwareTagInterface
{
public function __construct(InjectParams $injectParams, string $originalContent)
{
$this->items = get_object_vars($injectParams);
$this->originalContent = $originalContent;
}

public function getShortName(): string
{
return '@DI\InjectParams';
Expand Down
Loading