mirror of
https://github.com/rectorphp/rector.git
synced 2025-01-17 21:38:22 +01:00
Print only changed docblocks 🎉🎉🎉 (#5251)
This commit is contained in:
parent
85e7f7fa2c
commit
87494ce3a6
@ -448,6 +448,10 @@ final class PhpDocInfo
|
||||
|
||||
public function hasChanged(): bool
|
||||
{
|
||||
if ($this->isNewNode()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->hasChanged;
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace Rector\BetterPhpDocParser\PhpDocManipulator;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Param;
|
||||
use PHPStan\Type\Constant\ConstantArrayType;
|
||||
use PHPStan\Type\MixedType;
|
||||
@ -13,9 +12,6 @@ use PHPStan\Type\Type;
|
||||
use Rector\AttributeAwarePhpDoc\Ast\PhpDoc\AttributeAwareReturnTagValueNode;
|
||||
use Rector\AttributeAwarePhpDoc\Ast\PhpDoc\AttributeAwareVarTagValueNode;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
||||
use Rector\ChangesReporting\Collector\RectorChangeCollector;
|
||||
use Rector\Core\Configuration\CurrentNodeProvider;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\NodeTypeResolver\PHPStan\TypeComparator;
|
||||
use Rector\StaticTypeMapper\StaticTypeMapper;
|
||||
use Rector\TypeDeclaration\PhpDocParser\ParamPhpDocNodeFactory;
|
||||
@ -32,16 +28,6 @@ final class PhpDocTypeChanger
|
||||
*/
|
||||
private $staticTypeMapper;
|
||||
|
||||
/**
|
||||
* @var RectorChangeCollector
|
||||
*/
|
||||
private $rectorChangeCollector;
|
||||
|
||||
/**
|
||||
* @var CurrentNodeProvider
|
||||
*/
|
||||
private $currentNodeProvider;
|
||||
|
||||
/**
|
||||
* @var ParamPhpDocNodeFactory
|
||||
*/
|
||||
@ -50,14 +36,10 @@ final class PhpDocTypeChanger
|
||||
public function __construct(
|
||||
StaticTypeMapper $staticTypeMapper,
|
||||
TypeComparator $typeComparator,
|
||||
RectorChangeCollector $rectorChangeCollector,
|
||||
CurrentNodeProvider $currentNodeProvider,
|
||||
ParamPhpDocNodeFactory $paramPhpDocNodeFactory
|
||||
) {
|
||||
$this->typeComparator = $typeComparator;
|
||||
$this->staticTypeMapper = $staticTypeMapper;
|
||||
$this->rectorChangeCollector = $rectorChangeCollector;
|
||||
$this->currentNodeProvider = $currentNodeProvider;
|
||||
$this->paramPhpDocNodeFactory = $paramPhpDocNodeFactory;
|
||||
}
|
||||
|
||||
@ -80,14 +62,12 @@ final class PhpDocTypeChanger
|
||||
if ($currentVarTagValueNode !== null) {
|
||||
// only change type
|
||||
$currentVarTagValueNode->type = $newPHPStanPhpDocType;
|
||||
$phpDocInfo->markAsChanged();
|
||||
} else {
|
||||
// add completely new one
|
||||
$attributeAwareVarTagValueNode = new AttributeAwareVarTagValueNode($newPHPStanPhpDocType, '', '');
|
||||
$phpDocInfo->addTagValueNode($attributeAwareVarTagValueNode);
|
||||
}
|
||||
|
||||
// notify about node change
|
||||
$this->notifyChange();
|
||||
}
|
||||
|
||||
public function changeReturnType(PhpDocInfo $phpDocInfo, Type $newType): void
|
||||
@ -104,14 +84,12 @@ final class PhpDocTypeChanger
|
||||
if ($currentReturnTagValueNode !== null) {
|
||||
// only change type
|
||||
$currentReturnTagValueNode->type = $newPHPStanPhpDocType;
|
||||
$phpDocInfo->markAsChanged();
|
||||
} else {
|
||||
// add completely new one
|
||||
$attributeAwareReturnTagValueNode = new AttributeAwareReturnTagValueNode($newPHPStanPhpDocType, '');
|
||||
$phpDocInfo->addTagValueNode($attributeAwareReturnTagValueNode);
|
||||
}
|
||||
|
||||
// notify about node change
|
||||
$this->notifyChange();
|
||||
}
|
||||
|
||||
public function changeParamType(PhpDocInfo $phpDocInfo, Type $newType, Param $param, string $paramName): void
|
||||
@ -132,22 +110,10 @@ final class PhpDocTypeChanger
|
||||
}
|
||||
|
||||
$paramTagValueNode->type = $phpDocType;
|
||||
$phpDocInfo->markAsChanged();
|
||||
} else {
|
||||
$paramTagValueNode = $this->paramPhpDocNodeFactory->create($phpDocType, $param);
|
||||
$phpDocInfo->addTagValueNode($paramTagValueNode);
|
||||
}
|
||||
|
||||
// notify about node change
|
||||
$this->notifyChange();
|
||||
}
|
||||
|
||||
private function notifyChange(): void
|
||||
{
|
||||
$node = $this->currentNodeProvider->getNode();
|
||||
if (! $node instanceof Node) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$this->rectorChangeCollector->notifyNodeFileInfo($node);
|
||||
}
|
||||
}
|
||||
|
@ -35,5 +35,7 @@ final class PropertyDocBlockManipulator
|
||||
}
|
||||
|
||||
$paramTagValueNode->parameterName = '$' . $renameValueObject->getExpectedName();
|
||||
|
||||
$phpDocInfo->markAsChanged();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\BetterPhpDocParser\Printer;
|
||||
|
||||
use Nette\Utils\Strings;
|
||||
|
||||
final class DocBlockInliner
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
* @see https://regex101.com/r/Mjb0qi/1
|
||||
*/
|
||||
private const NEWLINE_CLOSING_DOC_REGEX = "#\n \*\/$#";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @see https://regex101.com/r/U5OUV4/2
|
||||
*/
|
||||
private const NEWLINE_MIDDLE_DOC_REGEX = "#\n \* #";
|
||||
|
||||
public function inline(string $docContent): string
|
||||
{
|
||||
$docContent = Strings::replace($docContent, self::NEWLINE_MIDDLE_DOC_REGEX, ' ');
|
||||
return Strings::replace($docContent, self::NEWLINE_CLOSING_DOC_REGEX, ' */');
|
||||
}
|
||||
}
|
@ -111,16 +111,33 @@ final class PhpDocInfoPrinter
|
||||
*/
|
||||
private $emptyPhpDocDetector;
|
||||
|
||||
/**
|
||||
* @var DocBlockInliner
|
||||
*/
|
||||
private $docBlockInliner;
|
||||
|
||||
public function __construct(
|
||||
EmptyPhpDocDetector $emptyPhpDocDetector,
|
||||
MultilineSpaceFormatPreserver $multilineSpaceFormatPreserver,
|
||||
OriginalSpacingRestorer $originalSpacingRestorer,
|
||||
SpacePatternFactory $spacePatternFactory
|
||||
SpacePatternFactory $spacePatternFactory,
|
||||
DocBlockInliner $docBlockInliner
|
||||
) {
|
||||
$this->originalSpacingRestorer = $originalSpacingRestorer;
|
||||
$this->multilineSpaceFormatPreserver = $multilineSpaceFormatPreserver;
|
||||
$this->spacePatternFactory = $spacePatternFactory;
|
||||
$this->emptyPhpDocDetector = $emptyPhpDocDetector;
|
||||
$this->docBlockInliner = $docBlockInliner;
|
||||
}
|
||||
|
||||
public function printNew(PhpDocInfo $phpDocInfo): string
|
||||
{
|
||||
$docContent = (string) $phpDocInfo->getPhpDocNode();
|
||||
if (! $phpDocInfo->isSingleLine()) {
|
||||
return $docContent;
|
||||
}
|
||||
|
||||
return $this->docBlockInliner->inline($docContent);
|
||||
}
|
||||
|
||||
/**
|
||||
|
73
packages/comments/src/NodeDocBlock/DocBlockUpdater.php
Normal file
73
packages/comments/src/NodeDocBlock/DocBlockUpdater.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Comments\NodeDocBlock;
|
||||
|
||||
use PhpParser\Comment\Doc;
|
||||
use PhpParser\Node;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
||||
use Rector\BetterPhpDocParser\Printer\PhpDocInfoPrinter;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
final class DocBlockUpdater
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
* @see https://regex101.com/r/VdaVGL/1
|
||||
*/
|
||||
public const SPACE_OR_ASTERISK_REGEX = '#(\s|\*)+#';
|
||||
|
||||
/**
|
||||
* @var PhpDocInfoPrinter
|
||||
*/
|
||||
private $phpDocInfoPrinter;
|
||||
|
||||
public function __construct(PhpDocInfoPrinter $phpDocInfoPrinter)
|
||||
{
|
||||
$this->phpDocInfoPrinter = $phpDocInfoPrinter;
|
||||
}
|
||||
|
||||
public function updateNodeWithPhpDocInfo(Node $node): void
|
||||
{
|
||||
// nothing to change? don't save it
|
||||
$phpDocInfo = $node->getAttribute(AttributeKey::PHP_DOC_INFO);
|
||||
if (! $phpDocInfo instanceof PhpDocInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (! $phpDocInfo->hasChanged()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$phpDoc = $this->printPhpDocInfoToString($phpDocInfo);
|
||||
|
||||
// make sure, that many separated comments are not removed
|
||||
if ($phpDoc === '') {
|
||||
if (count($node->getComments()) > 1) {
|
||||
foreach ($node->getComments() as $comment) {
|
||||
$phpDoc .= $comment->getText() . PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
if ($phpDocInfo->getOriginalPhpDocNode()->children !== []) {
|
||||
// all comments were removed → null
|
||||
$node->setAttribute(AttributeKey::COMMENTS, null);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// this is needed to remove duplicated // commentsAsText
|
||||
$node->setDocComment(new Doc($phpDoc));
|
||||
}
|
||||
|
||||
private function printPhpDocInfoToString(PhpDocInfo $phpDocInfo): string
|
||||
{
|
||||
if ($phpDocInfo->isNewNode()) {
|
||||
return $this->phpDocInfoPrinter->printNew($phpDocInfo);
|
||||
}
|
||||
|
||||
return $this->phpDocInfoPrinter->printFormatPreserving($phpDocInfo);
|
||||
}
|
||||
}
|
@ -16,11 +16,6 @@ use Symplify\SimplePhpDocParser\PhpDocNodeTraverser;
|
||||
|
||||
final class DocBlockClassRenamer
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $hasNodeChanged = false;
|
||||
|
||||
/**
|
||||
* @var StaticTypeMapper
|
||||
*/
|
||||
@ -56,11 +51,11 @@ final class DocBlockClassRenamer
|
||||
Type $oldType,
|
||||
Type $newType,
|
||||
Node $phpParserNode
|
||||
): bool {
|
||||
): void {
|
||||
$this->phpDocNodeTraverser->traverseWithCallable(
|
||||
$phpDocInfo->getPhpDocNode(),
|
||||
'',
|
||||
function (PhpDocParserNode $node) use ($phpParserNode, $oldType, $newType): PhpDocParserNode {
|
||||
function (PhpDocParserNode $node) use ($phpDocInfo, $phpParserNode, $oldType, $newType): PhpDocParserNode {
|
||||
if (! $node instanceof IdentifierTypeNode) {
|
||||
return $node;
|
||||
}
|
||||
@ -76,12 +71,10 @@ final class DocBlockClassRenamer
|
||||
return $node;
|
||||
}
|
||||
|
||||
$this->hasNodeChanged = true;
|
||||
$phpDocInfo->markAsChanged();
|
||||
|
||||
return $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($newType);
|
||||
}
|
||||
);
|
||||
|
||||
return $this->hasNodeChanged;
|
||||
}
|
||||
}
|
||||
|
@ -1,163 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer;
|
||||
|
||||
use Nette\Utils\Strings;
|
||||
use PhpParser\Comment\Doc;
|
||||
use PhpParser\Node;
|
||||
use PHPStan\Type\Type;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
||||
use Rector\BetterPhpDocParser\Printer\PhpDocInfoPrinter;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
final class DocBlockManipulator
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
* @see https://regex101.com/r/VdaVGL/1
|
||||
*/
|
||||
public const SPACE_OR_ASTERISK_REGEX = '#(\s|\*)+#';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @see https://regex101.com/r/Mjb0qi/1
|
||||
*/
|
||||
private const NEWLINE_CLOSING_DOC_REGEX = "#\n \*\/$#";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @see https://regex101.com/r/U5OUV4/2
|
||||
*/
|
||||
private const NEWLINE_MIDDLE_DOC_REGEX = "#\n \* #";
|
||||
|
||||
/**
|
||||
* @var PhpDocInfoPrinter
|
||||
*/
|
||||
private $phpDocInfoPrinter;
|
||||
|
||||
/**
|
||||
* @var DocBlockClassRenamer
|
||||
*/
|
||||
private $docBlockClassRenamer;
|
||||
|
||||
public function __construct(DocBlockClassRenamer $docBlockClassRenamer, PhpDocInfoPrinter $phpDocInfoPrinter)
|
||||
{
|
||||
$this->phpDocInfoPrinter = $phpDocInfoPrinter;
|
||||
$this->docBlockClassRenamer = $docBlockClassRenamer;
|
||||
}
|
||||
|
||||
public function changeType(PhpDocInfo $phpDocInfo, Node $node, Type $oldType, Type $newType): void
|
||||
{
|
||||
$this->docBlockClassRenamer->renamePhpDocType($phpDocInfo, $oldType, $newType, $node);
|
||||
}
|
||||
|
||||
public function updateNodeWithPhpDocInfo(Node $node): void
|
||||
{
|
||||
// nothing to change
|
||||
$phpDocInfo = $node->getAttribute(AttributeKey::PHP_DOC_INFO);
|
||||
if (! $phpDocInfo instanceof PhpDocInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
$phpDoc = $this->printPhpDocInfoToString($phpDocInfo);
|
||||
|
||||
// make sure, that many separated comments are not removed
|
||||
if ($phpDoc === '' && count($node->getComments()) > 1) {
|
||||
foreach ($node->getComments() as $comment) {
|
||||
$phpDoc .= $comment->getText() . PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
if ($phpDoc === '') {
|
||||
if ($phpDocInfo->getOriginalPhpDocNode()->children !== []) {
|
||||
// all comments were removed → null
|
||||
$node->setAttribute(AttributeKey::COMMENTS, null);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// no change, don't save it
|
||||
// this is needed to prevent short classes override with FQN with same value → people don't like that for some reason
|
||||
if (! $this->haveDocCommentOrCommentsChanged($node, $phpDoc)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// this is needed to remove duplicated // commentsAsText
|
||||
$node->setDocComment(new Doc($phpDoc));
|
||||
}
|
||||
|
||||
private function printPhpDocInfoToString(PhpDocInfo $phpDocInfo): string
|
||||
{
|
||||
// new node, needs to be reparsed
|
||||
if ($phpDocInfo->isNewNode()) {
|
||||
$docContent = (string) $phpDocInfo->getPhpDocNode();
|
||||
if (! $phpDocInfo->isSingleLine()) {
|
||||
return $docContent;
|
||||
}
|
||||
|
||||
return $this->inlineDocContent($docContent);
|
||||
}
|
||||
|
||||
return $this->phpDocInfoPrinter->printFormatPreserving($phpDocInfo);
|
||||
}
|
||||
|
||||
private function haveDocCommentOrCommentsChanged(Node $node, string $phpDoc): bool
|
||||
{
|
||||
$docComment = $node->getDocComment();
|
||||
if ($docComment !== null && $docComment->getText() === $phpDoc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$phpDoc = $this->completeSimpleCommentsToPhpDoc($node, $phpDoc);
|
||||
|
||||
if ($node->getComments() !== []) {
|
||||
$commentsContent = implode(PHP_EOL, $node->getComments());
|
||||
if ($this->removeSpacesAndAsterisks($commentsContent) === $this->removeSpacesAndAsterisks($phpDoc)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function inlineDocContent(string $docContent): string
|
||||
{
|
||||
$docContent = Strings::replace($docContent, self::NEWLINE_MIDDLE_DOC_REGEX, ' ');
|
||||
|
||||
return Strings::replace($docContent, self::NEWLINE_CLOSING_DOC_REGEX, ' */');
|
||||
}
|
||||
|
||||
/**
|
||||
* add // comments to phpdoc (only has /**
|
||||
*/
|
||||
private function completeSimpleCommentsToPhpDoc(Node $node, string $phpDoc): string
|
||||
{
|
||||
$startComments = '';
|
||||
foreach ($node->getComments() as $comment) {
|
||||
// skip simple comments
|
||||
if (Strings::startsWith($comment->getText(), '//')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Strings::startsWith($comment->getText(), '#')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$startComments .= $comment->getText() . PHP_EOL;
|
||||
}
|
||||
|
||||
if ($startComments === '') {
|
||||
return $phpDoc;
|
||||
}
|
||||
|
||||
return $startComments . PHP_EOL . $phpDoc;
|
||||
}
|
||||
|
||||
private function removeSpacesAndAsterisks(string $content): string
|
||||
{
|
||||
return Strings::replace($content, self::SPACE_OR_ASTERISK_REGEX, '');
|
||||
}
|
||||
}
|
@ -18,11 +18,6 @@ use Symplify\SimplePhpDocParser\PhpDocNodeTraverser;
|
||||
|
||||
final class DocBlockNameImporter
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $hasPhpDocChanged = false;
|
||||
|
||||
/**
|
||||
* @var PhpDocNodeTraverser
|
||||
*/
|
||||
@ -62,15 +57,13 @@ final class DocBlockNameImporter
|
||||
$this->useNodesToAddCollector = $useNodesToAddCollector;
|
||||
}
|
||||
|
||||
public function importNames(PhpDocInfo $phpDocInfo, Node $phpParserNode): bool
|
||||
public function importNames(PhpDocInfo $phpDocInfo, Node $phpParserNode): void
|
||||
{
|
||||
$attributeAwarePhpDocNode = $phpDocInfo->getPhpDocNode();
|
||||
|
||||
$this->hasPhpDocChanged = false;
|
||||
|
||||
$this->phpDocNodeTraverser->traverseWithCallable($attributeAwarePhpDocNode, '', function (
|
||||
PhpDocParserNode $docNode
|
||||
) use ($phpParserNode): PhpDocParserNode {
|
||||
) use ($phpDocInfo, $phpParserNode): PhpDocParserNode {
|
||||
if (! $docNode instanceof IdentifierTypeNode) {
|
||||
return $docNode;
|
||||
}
|
||||
@ -87,13 +80,12 @@ final class DocBlockNameImporter
|
||||
return $docNode;
|
||||
}
|
||||
|
||||
return $this->processFqnNameImport($phpParserNode, $docNode, $staticType);
|
||||
return $this->processFqnNameImport($phpDocInfo, $phpParserNode, $docNode, $staticType);
|
||||
});
|
||||
|
||||
return $this->hasPhpDocChanged;
|
||||
}
|
||||
|
||||
private function processFqnNameImport(
|
||||
PhpDocInfo $phpDocInfo,
|
||||
Node $node,
|
||||
IdentifierTypeNode $identifierTypeNode,
|
||||
FullyQualifiedObjectType $fullyQualifiedObjectType
|
||||
@ -109,7 +101,7 @@ final class DocBlockNameImporter
|
||||
if ($this->useNodesToAddCollector->isShortImported($node, $fullyQualifiedObjectType)) {
|
||||
if ($this->useNodesToAddCollector->isImportShortable($node, $fullyQualifiedObjectType)) {
|
||||
$identifierTypeNode->name = $fullyQualifiedObjectType->getShortName();
|
||||
$this->hasPhpDocChanged = true;
|
||||
$phpDocInfo->markAsChanged();
|
||||
}
|
||||
|
||||
return $identifierTypeNode;
|
||||
@ -117,8 +109,8 @@ final class DocBlockNameImporter
|
||||
|
||||
$shortenedIdentifierTypeNode = new IdentifierTypeNode($fullyQualifiedObjectType->getShortName());
|
||||
|
||||
$this->hasPhpDocChanged = true;
|
||||
$this->useNodesToAddCollector->addUseImport($node, $fullyQualifiedObjectType);
|
||||
$phpDocInfo->markAsChanged();
|
||||
|
||||
return $shortenedIdentifierTypeNode;
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ final class PhpDocTypeRenamer
|
||||
|
||||
$this->phpDocNodeTraverser->traverseWithCallable($attributeAwarePhpDocNode, '', function (
|
||||
PhpDocParserNode $node
|
||||
) use ($pseudoNamespaceToNamespace, $phpParserNode): PhpDocParserNode {
|
||||
) use ($pseudoNamespaceToNamespace, $phpParserNode, $phpDocInfo): PhpDocParserNode {
|
||||
if (! $node instanceof TypeNode) {
|
||||
return $node;
|
||||
}
|
||||
@ -62,6 +62,8 @@ final class PhpDocTypeRenamer
|
||||
$slashedName = '\\' . Strings::replace($staticType->getClassName(), '#_#', '\\');
|
||||
$node->name = $slashedName;
|
||||
|
||||
$phpDocInfo->markAsChanged();
|
||||
|
||||
return $node;
|
||||
});
|
||||
}
|
||||
|
@ -210,7 +210,7 @@ trait NodeCommandersTrait
|
||||
}
|
||||
}
|
||||
|
||||
protected function notifyNodeFileInfo(Node $node): void
|
||||
private function notifyNodeFileInfo(Node $node): void
|
||||
{
|
||||
$this->rectorChangeCollector->notifyNodeFileInfo($node);
|
||||
}
|
||||
|
@ -73,11 +73,7 @@ final class NameImportingPostRector extends AbstractPostRector
|
||||
}
|
||||
|
||||
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
|
||||
|
||||
$hasChanged = $this->docBlockNameImporter->importNames($phpDocInfo, $node);
|
||||
if (! $hasChanged) {
|
||||
return null;
|
||||
}
|
||||
$this->docBlockNameImporter->importNames($phpDocInfo, $node);
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
@ -301,6 +301,7 @@ parameters:
|
||||
- packages/better-php-doc-parser/src/Comment/CommentsMerger.php
|
||||
- packages/node-type-resolver/src/PhpDoc/NodeAnalyzer/DocBlockManipulator.php
|
||||
- rules/coding-style/src/Node/DocAliasResolver.php
|
||||
- packages/comments/src/NodeDocBlock/DocBlockUpdater.php
|
||||
- packages/better-php-doc-parser/src/PhpDocInfo/PhpDocInfoFactory.php
|
||||
- packages/better-php-doc-parser/tests/PhpDocInfo/PhpDocInfoPrinter/AbstractPhpDocInfoPrinterTest.php
|
||||
|
||||
|
@ -9,6 +9,7 @@ use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use Rector\Core\PhpParser\Node\CustomNode\FileNode;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Doctrine\PhpDocParser\DoctrineDocBlockResolver;
|
||||
use Rector\FileSystemRector\ValueObject\MovedFileWithNodes;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
@ -28,6 +29,16 @@ final class MoveEntitiesToEntityDirectoryRector extends AbstractRector
|
||||
*/
|
||||
private const ENTITY_PATH_REGEX = '#\bEntity\b#';
|
||||
|
||||
/**
|
||||
* @var DoctrineDocBlockResolver
|
||||
*/
|
||||
private $doctrineDocBlockResolver;
|
||||
|
||||
public function __construct(DoctrineDocBlockResolver $doctrineDocBlockResolver)
|
||||
{
|
||||
$this->doctrineDocBlockResolver = $doctrineDocBlockResolver;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Move entities to Entity namespace', [
|
||||
@ -109,6 +120,6 @@ CODE_SAMPLE
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->isDoctrineEntityClass($class);
|
||||
return $this->doctrineDocBlockResolver->isDoctrineEntityClass($class);
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ use PHPStan\Type\ObjectType;
|
||||
use Rector\BetterPhpDocParser\Contract\Doctrine\DoctrineRelationTagValueNodeInterface;
|
||||
use Rector\BetterPhpDocParser\Contract\Doctrine\InversedByNodeInterface;
|
||||
use Rector\BetterPhpDocParser\Contract\Doctrine\MappedByNodeInterface;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Class_\EntityTagValueNode;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Class_\InheritanceTypeTagValueNode;
|
||||
@ -94,9 +95,8 @@ final class DoctrineEntityManipulator
|
||||
return $phpDocInfo->hasByTypes([InheritanceTypeTagValueNode::class, EntityTagValueNode::class]);
|
||||
}
|
||||
|
||||
public function removeMappedByOrInversedByFromProperty(Property $property): void
|
||||
public function removeMappedByOrInversedByFromProperty(PhpDocInfo $phpDocInfo): void
|
||||
{
|
||||
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
|
||||
$relationTagValueNode = $phpDocInfo->getByType(DoctrineRelationTagValueNodeInterface::class);
|
||||
|
||||
if ($relationTagValueNode instanceof MappedByNodeInterface && $relationTagValueNode->getMappedBy()) {
|
||||
@ -111,6 +111,7 @@ final class DoctrineEntityManipulator
|
||||
return;
|
||||
}
|
||||
|
||||
$phpDocInfo->markAsChanged();
|
||||
$relationTagValueNode->removeInversedBy();
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DeadCode\FlowControl;
|
||||
namespace Rector\DeadCode\NodeFinder;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\Assign;
|
@ -7,12 +7,16 @@ namespace Rector\DeadCode\Rector\Class_;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use Rector\Caching\Contract\Rector\ZeroCacheRectorInterface;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\DeadCode\UnusedNodeResolver\UnusedClassResolver;
|
||||
use Rector\Doctrine\PhpDocParser\DoctrineDocBlockResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\PhpAttribute\ValueObject\TagName;
|
||||
use Rector\Testing\PHPUnit\StaticPHPUnitEnvironment;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
/**
|
||||
* @see \Rector\DeadCode\Tests\Rector\Class_\RemoveUnusedClassesRector\RemoveUnusedClassesRectorTest
|
||||
@ -24,9 +28,17 @@ final class RemoveUnusedClassesRector extends AbstractRector implements ZeroCach
|
||||
*/
|
||||
private $unusedClassResolver;
|
||||
|
||||
public function __construct(UnusedClassResolver $unusedClassResolver)
|
||||
{
|
||||
/**
|
||||
* @var DoctrineDocBlockResolver
|
||||
*/
|
||||
private $doctrineDocBlockResolver;
|
||||
|
||||
public function __construct(
|
||||
UnusedClassResolver $unusedClassResolver,
|
||||
DoctrineDocBlockResolver $doctrineDocBlockResolver
|
||||
) {
|
||||
$this->unusedClassResolver = $unusedClassResolver;
|
||||
$this->doctrineDocBlockResolver = $doctrineDocBlockResolver;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
@ -92,7 +104,12 @@ CODE_SAMPLE
|
||||
if (StaticPHPUnitEnvironment::isPHPUnitRun()) {
|
||||
$this->removeNode($node);
|
||||
} else {
|
||||
$this->removeFile($this->getFileInfo());
|
||||
$smartFileInfo = $node->getAttribute(AttributeKey::FILE_INFO);
|
||||
if (! $smartFileInfo instanceof SmartFileInfo) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$this->removeFile($smartFileInfo);
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -104,7 +121,7 @@ CODE_SAMPLE
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->isDoctrineEntityClass($class)) {
|
||||
if ($this->doctrineDocBlockResolver->isDoctrineEntityClass($class)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@ use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use Rector\BetterPhpDocParser\Contract\Doctrine\DoctrineRelationTagValueNodeInterface;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Property_\IdTagValueNode;
|
||||
use Rector\Caching\Contract\Rector\ZeroCacheRectorInterface;
|
||||
use Rector\Core\PhpParser\Node\Manipulator\ClassManipulator;
|
||||
@ -187,7 +188,7 @@ CODE_SAMPLE
|
||||
$this->removeNode($this->collectionByPropertyName[$propertyName]);
|
||||
}
|
||||
|
||||
$this->removeInversedByOrMappedByOnRelatedProperty($property);
|
||||
$this->removeInversedByOrMappedByOnRelatedProperty($phpDocInfo, $property);
|
||||
}
|
||||
|
||||
return $class;
|
||||
@ -228,14 +229,15 @@ CODE_SAMPLE
|
||||
return $usedPropertyNames;
|
||||
}
|
||||
|
||||
private function removeInversedByOrMappedByOnRelatedProperty(Property $property): void
|
||||
private function removeInversedByOrMappedByOnRelatedProperty(PhpDocInfo $phpDocInfo, Property $property): void
|
||||
{
|
||||
$otherRelationProperty = $this->getOtherRelationProperty($property);
|
||||
$otherRelationProperty = $this->getOtherRelationProperty($phpDocInfo, $property);
|
||||
if (! $otherRelationProperty instanceof Property) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->doctrineEntityManipulator->removeMappedByOrInversedByFromProperty($otherRelationProperty);
|
||||
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($otherRelationProperty);
|
||||
$this->doctrineEntityManipulator->removeMappedByOrInversedByFromProperty($phpDocInfo);
|
||||
}
|
||||
|
||||
private function isPropertyFetchAssignOfArrayCollection(PropertyFetch $propertyFetch): bool
|
||||
@ -255,9 +257,8 @@ CODE_SAMPLE
|
||||
return $this->isName($new->class, ArrayCollection::class);
|
||||
}
|
||||
|
||||
private function getOtherRelationProperty(Property $property): ?Property
|
||||
private function getOtherRelationProperty(PhpDocInfo $phpDocInfo, Property $property): ?Property
|
||||
{
|
||||
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
|
||||
$doctrineRelationTagValueNode = $phpDocInfo->getByType(DoctrineRelationTagValueNodeInterface::class);
|
||||
if (! $doctrineRelationTagValueNode instanceof DoctrineRelationTagValueNodeInterface) {
|
||||
return null;
|
||||
|
@ -10,8 +10,8 @@ use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\FunctionLike;
|
||||
use Rector\Core\Context\ContextAnalyzer;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\DeadCode\FlowControl\VariableUseFinder;
|
||||
use Rector\DeadCode\NodeCollector\NodeByTypeAndPositionCollector;
|
||||
use Rector\DeadCode\NodeFinder\VariableUseFinder;
|
||||
use Rector\DeadCode\ValueObject\VariableNodeUse;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
|
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Defluent\NodeFactory;
|
||||
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
final class FluentMethodCallAsArgFactory
|
||||
{
|
||||
public function createFluentAsArg(MethodCall $methodCall, Variable $variable): MethodCall
|
||||
{
|
||||
/** @var Arg $parent */
|
||||
$parent = $methodCall->getAttribute(AttributeKey::PARENT_NODE);
|
||||
/** @var MethodCall $parentParent */
|
||||
$parentParent = $parent->getAttribute(AttributeKey::PARENT_NODE);
|
||||
|
||||
$lastMethodCall = new MethodCall($parentParent->var, $parentParent->name);
|
||||
$lastMethodCall->args[] = new Arg($variable);
|
||||
|
||||
return $lastMethodCall;
|
||||
}
|
||||
}
|
@ -12,6 +12,8 @@ use Rector\Defluent\Rector\AbstractFluentChainMethodCallRector;
|
||||
use Rector\Defluent\Rector\Return_\DefluentReturnMethodCallRector;
|
||||
use Rector\Defluent\ValueObject\AssignAndRootExprAndNodesToAdd;
|
||||
use Rector\Defluent\ValueObject\FluentCallsKind;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Symplify\PackageBuilder\Php\TypeChecker;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
@ -23,6 +25,16 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
*/
|
||||
final class FluentChainMethodCallToNormalMethodCallRector extends AbstractFluentChainMethodCallRector
|
||||
{
|
||||
/**
|
||||
* @var TypeChecker
|
||||
*/
|
||||
private $typeChecker;
|
||||
|
||||
public function __construct(TypeChecker $typeChecker)
|
||||
{
|
||||
$this->typeChecker = $typeChecker;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition(
|
||||
@ -88,6 +100,7 @@ CODE_SAMPLE
|
||||
*/
|
||||
private function isHandledByAnotherRule(MethodCall $methodCall): bool
|
||||
{
|
||||
return $this->hasParentTypes($methodCall, [Return_::class, Arg::class]);
|
||||
$parent = $methodCall->getAttribute(AttributeKey::PARENT_NODE);
|
||||
return $this->typeChecker->isInstanceOf($parent, [Return_::class, Arg::class]);
|
||||
}
|
||||
}
|
||||
|
@ -8,8 +8,8 @@ use PhpParser\Node;
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\New_;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use Rector\Defluent\NodeAnalyzer\NewFluentChainMethodCallNodeAnalyzer;
|
||||
use Rector\Defluent\NodeFactory\FluentMethodCallAsArgFactory;
|
||||
use Rector\Defluent\NodeFactory\VariableFromNewFactory;
|
||||
use Rector\Defluent\Rector\AbstractFluentChainMethodCallRector;
|
||||
use Rector\Defluent\ValueObject\AssignAndRootExprAndNodesToAdd;
|
||||
@ -35,12 +35,19 @@ final class InArgFluentChainMethodCallToStandaloneMethodCallRector extends Abstr
|
||||
*/
|
||||
private $variableFromNewFactory;
|
||||
|
||||
/**
|
||||
* @var FluentMethodCallAsArgFactory
|
||||
*/
|
||||
private $fluentMethodCallAsArgFactory;
|
||||
|
||||
public function __construct(
|
||||
NewFluentChainMethodCallNodeAnalyzer $newFluentChainMethodCallNodeAnalyzer,
|
||||
VariableFromNewFactory $variableFromNewFactory
|
||||
VariableFromNewFactory $variableFromNewFactory,
|
||||
FluentMethodCallAsArgFactory $fluentMethodCallAsArgFactory
|
||||
) {
|
||||
$this->newFluentChainMethodCallNodeAnalyzer = $newFluentChainMethodCallNodeAnalyzer;
|
||||
$this->variableFromNewFactory = $variableFromNewFactory;
|
||||
$this->fluentMethodCallAsArgFactory = $fluentMethodCallAsArgFactory;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
@ -95,14 +102,12 @@ CODE_SAMPLE
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if (! $this->hasParentType($node, Arg::class)) {
|
||||
$parent = $node->getAttribute(AttributeKey::PARENT_NODE);
|
||||
if (! $parent instanceof Arg) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var Arg $arg */
|
||||
$arg = $node->getAttribute(AttributeKey::PARENT_NODE);
|
||||
/** @var Node|null $parentMethodCall */
|
||||
$parentMethodCall = $arg->getAttribute(AttributeKey::PARENT_NODE);
|
||||
$parentMethodCall = $parent->getAttribute(AttributeKey::PARENT_NODE);
|
||||
if (! $parentMethodCall instanceof MethodCall) {
|
||||
return null;
|
||||
}
|
||||
@ -139,29 +144,12 @@ CODE_SAMPLE
|
||||
$nodesToAdd = $this->nonFluentChainMethodCallFactory->createFromNewAndRootMethodCall($new, $methodCall);
|
||||
|
||||
$newVariable = $this->variableFromNewFactory->create($new);
|
||||
$nodesToAdd[] = $this->createFluentAsArg($methodCall, $newVariable);
|
||||
$nodesToAdd[] = $this->fluentMethodCallAsArgFactory->createFluentAsArg($methodCall, $newVariable);
|
||||
|
||||
$this->addNodesBeforeNode($nodesToAdd, $methodCall);
|
||||
$this->removeParentParent($methodCall);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @todo extact to factory
|
||||
*/
|
||||
private function createFluentAsArg(MethodCall $methodCall, Variable $variable): MethodCall
|
||||
{
|
||||
/** @var Arg $parent */
|
||||
$parent = $methodCall->getAttribute(AttributeKey::PARENT_NODE);
|
||||
/** @var MethodCall $parentParent */
|
||||
$parentParent = $parent->getAttribute(AttributeKey::PARENT_NODE);
|
||||
|
||||
$lastMethodCall = new MethodCall($parentParent->var, $parentParent->name);
|
||||
$lastMethodCall->args[] = new Arg($variable);
|
||||
|
||||
return $lastMethodCall;
|
||||
}
|
||||
|
||||
private function removeParentParent(MethodCall $methodCall): void
|
||||
{
|
||||
/** @var Arg $parent */
|
||||
|
@ -11,6 +11,8 @@ use PhpParser\Node\Stmt\Return_;
|
||||
use Rector\Defluent\Rector\AbstractFluentChainMethodCallRector;
|
||||
use Rector\Defluent\ValueObject\AssignAndRootExprAndNodesToAdd;
|
||||
use Rector\Defluent\ValueObject\FluentCallsKind;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Symplify\PackageBuilder\Php\TypeChecker;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
@ -23,6 +25,16 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
*/
|
||||
final class NewFluentChainMethodCallToNonFluentRector extends AbstractFluentChainMethodCallRector
|
||||
{
|
||||
/**
|
||||
* @var TypeChecker
|
||||
*/
|
||||
private $typeChecker;
|
||||
|
||||
public function __construct(TypeChecker $typeChecker)
|
||||
{
|
||||
$this->typeChecker = $typeChecker;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition(
|
||||
@ -58,7 +70,8 @@ CODE_SAMPLE
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
// handled by another rule
|
||||
if ($this->hasParentTypes($node, [Return_::class, Arg::class])) {
|
||||
$parent = $node->getAttribute(AttributeKey::PARENT_NODE);
|
||||
if ($this->typeChecker->isInstanceOf($parent, [Return_::class, Arg::class])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -1,39 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DoctrineCodeQuality\NodeAnalyzer;
|
||||
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Property_\ColumnTagValueNode;
|
||||
|
||||
final class ColumnDatetimePropertyAnalyzer
|
||||
{
|
||||
/**
|
||||
* @var PhpDocInfoFactory
|
||||
*/
|
||||
private $phpDocInfoFactory;
|
||||
|
||||
public function __construct(PhpDocInfoFactory $phpDocInfoFactory)
|
||||
{
|
||||
$this->phpDocInfoFactory = $phpDocInfoFactory;
|
||||
}
|
||||
|
||||
public function matchDateTimeColumnTagValueNodeInProperty(Property $property): ?ColumnTagValueNode
|
||||
{
|
||||
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
|
||||
|
||||
$columnTagValueNode = $phpDocInfo->getByType(ColumnTagValueNode::class);
|
||||
if (! $columnTagValueNode instanceof ColumnTagValueNode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var ColumnTagValueNode $columnTagValueNode */
|
||||
if ($columnTagValueNode->getType() !== 'datetime') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $columnTagValueNode;
|
||||
}
|
||||
}
|
@ -4,36 +4,26 @@ declare(strict_types=1);
|
||||
|
||||
namespace Rector\DoctrineCodeQuality\NodeManipulator;
|
||||
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\AbstractDoctrineTagValueNode;
|
||||
|
||||
final class DoctrineItemDefaultValueManipulator
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $hasModifiedAnnotation = false;
|
||||
|
||||
/**
|
||||
* @param string|bool|int $defaultValue
|
||||
*/
|
||||
public function remove(AbstractDoctrineTagValueNode $doctrineTagValueNode, string $item, $defaultValue): void
|
||||
{
|
||||
public function remove(
|
||||
PhpDocInfo $phpDocInfo,
|
||||
AbstractDoctrineTagValueNode $doctrineTagValueNode,
|
||||
string $item,
|
||||
$defaultValue
|
||||
): void {
|
||||
if (! $this->hasItemWithDefaultValue($doctrineTagValueNode, $item, $defaultValue)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->hasModifiedAnnotation = true;
|
||||
$doctrineTagValueNode->removeItem($item);
|
||||
}
|
||||
|
||||
public function resetHasModifiedAnnotation(): void
|
||||
{
|
||||
$this->hasModifiedAnnotation = false;
|
||||
}
|
||||
|
||||
public function hasModifiedAnnotation(): bool
|
||||
{
|
||||
return $this->hasModifiedAnnotation;
|
||||
$phpDocInfo->markAsChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -10,6 +10,7 @@ use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Property_\ManyToOneTagValueNode;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Doctrine\PhpDocParser\DoctrineDocBlockResolver;
|
||||
use Rector\DoctrineCodeQuality\NodeAnalyzer\SetterClassMethodAnalyzer;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
@ -28,9 +29,17 @@ final class MakeEntitySetterNullabilityInSyncWithPropertyRector extends Abstract
|
||||
*/
|
||||
private $setterClassMethodAnalyzer;
|
||||
|
||||
public function __construct(SetterClassMethodAnalyzer $setterClassMethodAnalyzer)
|
||||
{
|
||||
/**
|
||||
* @var DoctrineDocBlockResolver
|
||||
*/
|
||||
private $doctrineDocBlockResolver;
|
||||
|
||||
public function __construct(
|
||||
SetterClassMethodAnalyzer $setterClassMethodAnalyzer,
|
||||
DoctrineDocBlockResolver $doctrineDocBlockResolver
|
||||
) {
|
||||
$this->setterClassMethodAnalyzer = $setterClassMethodAnalyzer;
|
||||
$this->doctrineDocBlockResolver = $doctrineDocBlockResolver;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
@ -98,7 +107,7 @@ CODE_SAMPLE
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
// is setter in doctrine?
|
||||
if (! $this->isInDoctrineEntityClass($node)) {
|
||||
if (! $this->doctrineDocBlockResolver->isInDoctrineEntityClass($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,6 @@ use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Property_\ColumnTagValueNode;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\DoctrineCodeQuality\NodeAnalyzer\ColumnDatetimePropertyAnalyzer;
|
||||
use Rector\DoctrineCodeQuality\NodeAnalyzer\ConstructorAssignPropertyAnalyzer;
|
||||
use Rector\DoctrineCodeQuality\NodeFactory\ValueAssignFactory;
|
||||
use Rector\DoctrineCodeQuality\NodeManipulator\ColumnDatetimePropertyManipulator;
|
||||
@ -27,11 +26,6 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
*/
|
||||
final class MoveCurrentDateTimeDefaultInEntityToConstructorRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var ColumnDatetimePropertyAnalyzer
|
||||
*/
|
||||
private $columnDatetimePropertyAnalyzer;
|
||||
|
||||
/**
|
||||
* @var ConstructorManipulator
|
||||
*/
|
||||
@ -53,13 +47,11 @@ final class MoveCurrentDateTimeDefaultInEntityToConstructorRector extends Abstra
|
||||
private $constructorAssignPropertyAnalyzer;
|
||||
|
||||
public function __construct(
|
||||
ColumnDatetimePropertyAnalyzer $columnDatetimePropertyAnalyzer,
|
||||
ConstructorManipulator $constructorManipulator,
|
||||
ValueAssignFactory $valueAssignFactory,
|
||||
ColumnDatetimePropertyManipulator $columnDatetimePropertyManipulator,
|
||||
ConstructorAssignPropertyAnalyzer $constructorAssignPropertyAnalyzer
|
||||
) {
|
||||
$this->columnDatetimePropertyAnalyzer = $columnDatetimePropertyAnalyzer;
|
||||
$this->constructorManipulator = $constructorManipulator;
|
||||
$this->valueAssignFactory = $valueAssignFactory;
|
||||
$this->columnDatetimePropertyManipulator = $columnDatetimePropertyManipulator;
|
||||
@ -138,14 +130,18 @@ CODE_SAMPLE
|
||||
|
||||
private function refactorProperty(Property $property, Class_ $class): ?Property
|
||||
{
|
||||
$columnTagValueNode = $this->columnDatetimePropertyAnalyzer->matchDateTimeColumnTagValueNodeInProperty(
|
||||
$property
|
||||
);
|
||||
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
|
||||
|
||||
$columnTagValueNode = $phpDocInfo->getByType(ColumnTagValueNode::class);
|
||||
if (! $columnTagValueNode instanceof ColumnTagValueNode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var ColumnTagValueNode $columnTagValueNode */
|
||||
if ($columnTagValueNode->getType() !== 'datetime') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$constructorAssign = $this->constructorAssignPropertyAnalyzer->resolveConstructorAssign($property);
|
||||
|
||||
// 0. already has default
|
||||
@ -155,6 +151,7 @@ CODE_SAMPLE
|
||||
|
||||
// 1. remove default options from database level
|
||||
$this->columnDatetimePropertyManipulator->removeDefaultOption($columnTagValueNode);
|
||||
$phpDocInfo->markAsChanged();
|
||||
|
||||
// 2. remove default value
|
||||
$this->refactorClass($class, $property);
|
||||
|
@ -72,15 +72,10 @@ CODE_SAMPLE
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
$this->doctrineItemDefaultValueManipulator->resetHasModifiedAnnotation();
|
||||
if ($node instanceof Class_) {
|
||||
$this->refactorClassAnnotations($node);
|
||||
}
|
||||
|
||||
if (! $this->doctrineItemDefaultValueManipulator->hasModifiedAnnotation()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
@ -98,6 +93,6 @@ CODE_SAMPLE
|
||||
return;
|
||||
}
|
||||
|
||||
$this->doctrineItemDefaultValueManipulator->remove($entityTagValueNode, 'readOnly', false);
|
||||
$this->doctrineItemDefaultValueManipulator->remove($phpDocInfo, $entityTagValueNode, 'readOnly', false);
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Property_\OneToManyTagValueNode;
|
||||
use Rector\Core\PhpParser\Node\Manipulator\AssignManipulator;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Doctrine\PhpDocParser\DoctrineDocBlockResolver;
|
||||
use Rector\DoctrineCodeQuality\PhpDoc\CollectionTypeFactory;
|
||||
use Rector\DoctrineCodeQuality\PhpDoc\CollectionTypeResolver;
|
||||
use Rector\DoctrineCodeQuality\PhpDoc\CollectionVarTagValueNodeResolver;
|
||||
@ -53,18 +54,25 @@ final class ImproveDoctrineCollectionDocTypeInEntityRector extends AbstractRecto
|
||||
*/
|
||||
private $phpDocTypeChanger;
|
||||
|
||||
/**
|
||||
* @var DoctrineDocBlockResolver
|
||||
*/
|
||||
private $doctrineDocBlockResolver;
|
||||
|
||||
public function __construct(
|
||||
CollectionTypeFactory $collectionTypeFactory,
|
||||
AssignManipulator $assignManipulator,
|
||||
CollectionTypeResolver $collectionTypeResolver,
|
||||
CollectionVarTagValueNodeResolver $collectionVarTagValueNodeResolver,
|
||||
PhpDocTypeChanger $phpDocTypeChanger
|
||||
PhpDocTypeChanger $phpDocTypeChanger,
|
||||
DoctrineDocBlockResolver $doctrineDocBlockResolver
|
||||
) {
|
||||
$this->collectionTypeFactory = $collectionTypeFactory;
|
||||
$this->assignManipulator = $assignManipulator;
|
||||
$this->collectionTypeResolver = $collectionTypeResolver;
|
||||
$this->collectionVarTagValueNodeResolver = $collectionVarTagValueNodeResolver;
|
||||
$this->phpDocTypeChanger = $phpDocTypeChanger;
|
||||
$this->doctrineDocBlockResolver = $doctrineDocBlockResolver;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
@ -166,7 +174,7 @@ CODE_SAMPLE
|
||||
|
||||
private function refactorClassMethod(ClassMethod $classMethod): ?ClassMethod
|
||||
{
|
||||
if (! $this->isInDoctrineEntityClass($classMethod)) {
|
||||
if (! $this->doctrineDocBlockResolver->isInDoctrineEntityClass($classMethod)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -104,15 +104,10 @@ CODE_SAMPLE
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
$this->doctrineItemDefaultValueManipulator->resetHasModifiedAnnotation();
|
||||
if ($node instanceof Property) {
|
||||
$this->refactorPropertyAnnotations($node);
|
||||
}
|
||||
|
||||
if (! $this->doctrineItemDefaultValueManipulator->hasModifiedAnnotation()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
@ -136,10 +131,10 @@ CODE_SAMPLE
|
||||
return;
|
||||
}
|
||||
|
||||
$this->doctrineItemDefaultValueManipulator->remove($columnTagValueNode, 'nullable', false);
|
||||
$this->doctrineItemDefaultValueManipulator->remove($columnTagValueNode, 'unique', false);
|
||||
$this->doctrineItemDefaultValueManipulator->remove($columnTagValueNode, 'precision', 0);
|
||||
$this->doctrineItemDefaultValueManipulator->remove($columnTagValueNode, 'scale', 0);
|
||||
$this->doctrineItemDefaultValueManipulator->remove($phpDocInfo, $columnTagValueNode, 'nullable', false);
|
||||
$this->doctrineItemDefaultValueManipulator->remove($phpDocInfo, $columnTagValueNode, 'unique', false);
|
||||
$this->doctrineItemDefaultValueManipulator->remove($phpDocInfo, $columnTagValueNode, 'precision', 0);
|
||||
$this->doctrineItemDefaultValueManipulator->remove($phpDocInfo, $columnTagValueNode, 'scale', 0);
|
||||
}
|
||||
|
||||
private function refactorGeneratedValueAnnotation(PhpDocInfo $phpDocInfo): void
|
||||
@ -149,7 +144,12 @@ CODE_SAMPLE
|
||||
return;
|
||||
}
|
||||
|
||||
$this->doctrineItemDefaultValueManipulator->remove($generatedValueTagValueNode, 'strategy', 'AUTO');
|
||||
$this->doctrineItemDefaultValueManipulator->remove(
|
||||
$phpDocInfo,
|
||||
$generatedValueTagValueNode,
|
||||
'strategy',
|
||||
'AUTO'
|
||||
);
|
||||
}
|
||||
|
||||
private function refactorJoinColumnAnnotation(PhpDocInfo $phpDocInfo): void
|
||||
@ -159,9 +159,14 @@ CODE_SAMPLE
|
||||
return;
|
||||
}
|
||||
|
||||
$this->doctrineItemDefaultValueManipulator->remove($joinColumnTagValueNode, 'nullable', true);
|
||||
$this->doctrineItemDefaultValueManipulator->remove($joinColumnTagValueNode, 'referencedColumnName', 'id');
|
||||
$this->doctrineItemDefaultValueManipulator->remove($joinColumnTagValueNode, 'unique', false);
|
||||
$this->doctrineItemDefaultValueManipulator->remove($phpDocInfo, $joinColumnTagValueNode, 'nullable', true);
|
||||
$this->doctrineItemDefaultValueManipulator->remove(
|
||||
$phpDocInfo,
|
||||
$joinColumnTagValueNode,
|
||||
'referencedColumnName',
|
||||
'id'
|
||||
);
|
||||
$this->doctrineItemDefaultValueManipulator->remove($phpDocInfo, $joinColumnTagValueNode, 'unique', false);
|
||||
}
|
||||
|
||||
private function refactorManyToManyAnnotation(PhpDocInfo $phpDocInfo): void
|
||||
@ -171,8 +176,18 @@ CODE_SAMPLE
|
||||
return;
|
||||
}
|
||||
|
||||
$this->doctrineItemDefaultValueManipulator->remove($manyToManyTagValueNode, self::ORPHAN_REMOVAL, false);
|
||||
$this->doctrineItemDefaultValueManipulator->remove($manyToManyTagValueNode, self::FETCH, self::LAZY);
|
||||
$this->doctrineItemDefaultValueManipulator->remove(
|
||||
$phpDocInfo,
|
||||
$manyToManyTagValueNode,
|
||||
self::ORPHAN_REMOVAL,
|
||||
false
|
||||
);
|
||||
$this->doctrineItemDefaultValueManipulator->remove(
|
||||
$phpDocInfo,
|
||||
$manyToManyTagValueNode,
|
||||
self::FETCH,
|
||||
self::LAZY
|
||||
);
|
||||
}
|
||||
|
||||
private function refactorManyToOneAnnotation(PhpDocInfo $phpDocInfo): void
|
||||
@ -182,7 +197,12 @@ CODE_SAMPLE
|
||||
return;
|
||||
}
|
||||
|
||||
$this->doctrineItemDefaultValueManipulator->remove($manyToOneTagValueNode, self::FETCH, self::LAZY);
|
||||
$this->doctrineItemDefaultValueManipulator->remove(
|
||||
$phpDocInfo,
|
||||
$manyToOneTagValueNode,
|
||||
self::FETCH,
|
||||
self::LAZY
|
||||
);
|
||||
}
|
||||
|
||||
private function refactorOneToManyAnnotation(PhpDocInfo $phpDocInfo): void
|
||||
@ -192,8 +212,18 @@ CODE_SAMPLE
|
||||
return;
|
||||
}
|
||||
|
||||
$this->doctrineItemDefaultValueManipulator->remove($oneToManyTagValueNode, self::ORPHAN_REMOVAL, false);
|
||||
$this->doctrineItemDefaultValueManipulator->remove($oneToManyTagValueNode, self::FETCH, self::LAZY);
|
||||
$this->doctrineItemDefaultValueManipulator->remove(
|
||||
$phpDocInfo,
|
||||
$oneToManyTagValueNode,
|
||||
self::ORPHAN_REMOVAL,
|
||||
false
|
||||
);
|
||||
$this->doctrineItemDefaultValueManipulator->remove(
|
||||
$phpDocInfo,
|
||||
$oneToManyTagValueNode,
|
||||
self::FETCH,
|
||||
self::LAZY
|
||||
);
|
||||
}
|
||||
|
||||
private function refactorOneToOneAnnotation(PhpDocInfo $phpDocInfo): void
|
||||
@ -203,7 +233,12 @@ CODE_SAMPLE
|
||||
return;
|
||||
}
|
||||
|
||||
$this->doctrineItemDefaultValueManipulator->remove($oneToOneTagValueNode, self::ORPHAN_REMOVAL, false);
|
||||
$this->doctrineItemDefaultValueManipulator->remove($oneToOneTagValueNode, self::FETCH, self::LAZY);
|
||||
$this->doctrineItemDefaultValueManipulator->remove(
|
||||
$phpDocInfo,
|
||||
$oneToOneTagValueNode,
|
||||
self::ORPHAN_REMOVAL,
|
||||
false
|
||||
);
|
||||
$this->doctrineItemDefaultValueManipulator->remove($phpDocInfo, $oneToOneTagValueNode, self::FETCH, self::LAZY);
|
||||
}
|
||||
}
|
||||
|
@ -1,49 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Doctrine\AbstractRector;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use Rector\Doctrine\PhpDocParser\DoctrineDocBlockResolver;
|
||||
|
||||
trait DoctrineTrait
|
||||
{
|
||||
/**
|
||||
* @var DoctrineDocBlockResolver
|
||||
*/
|
||||
private $doctrineDocBlockResolver;
|
||||
|
||||
/**
|
||||
* @required
|
||||
*/
|
||||
public function autowireDoctrineTrait(DoctrineDocBlockResolver $doctrineDocBlockResolver): void
|
||||
{
|
||||
$this->doctrineDocBlockResolver = $doctrineDocBlockResolver;
|
||||
}
|
||||
|
||||
protected function isDoctrineProperty(Property $property): bool
|
||||
{
|
||||
return $this->doctrineDocBlockResolver->isDoctrineProperty($property);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Class_|string $class
|
||||
*/
|
||||
protected function isDoctrineEntityClass($class): bool
|
||||
{
|
||||
return $this->doctrineDocBlockResolver->isDoctrineEntityClass($class);
|
||||
}
|
||||
|
||||
protected function isInDoctrineEntityClass(Node $node): bool
|
||||
{
|
||||
return $this->doctrineDocBlockResolver->isInDoctrineEntityClass($node);
|
||||
}
|
||||
|
||||
protected function getTargetEntity(Property $property): ?string
|
||||
{
|
||||
return $this->doctrineDocBlockResolver->getTargetEntity($property);
|
||||
}
|
||||
}
|
@ -10,7 +10,6 @@ use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use Rector\BetterPhpDocParser\Contract\Doctrine\DoctrineRelationTagValueNodeInterface;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\AbstractDoctrineTagValueNode;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Class_\EmbeddableTagValueNode;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Class_\EntityTagValueNode;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Property_\IdTagValueNode;
|
||||
@ -88,12 +87,6 @@ final class DoctrineDocBlockResolver
|
||||
return $doctrineRelationTagValueNode->getTargetEntity();
|
||||
}
|
||||
|
||||
public function isDoctrineProperty(Property $property): bool
|
||||
{
|
||||
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
|
||||
return $phpDocInfo->hasByType(AbstractDoctrineTagValueNode::class);
|
||||
}
|
||||
|
||||
public function isInDoctrineEntityClass(Node $node): bool
|
||||
{
|
||||
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
|
||||
|
@ -9,6 +9,7 @@ use PhpParser\Node\Name\FullyQualified;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Doctrine\PhpDocParser\DoctrineDocBlockResolver;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
@ -19,6 +20,16 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
*/
|
||||
final class ChangeGetIdTypeToUuidRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var DoctrineDocBlockResolver
|
||||
*/
|
||||
private $doctrineDocBlockResolver;
|
||||
|
||||
public function __construct(DoctrineDocBlockResolver $doctrineDocBlockResolver)
|
||||
{
|
||||
$this->doctrineDocBlockResolver = $doctrineDocBlockResolver;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition(
|
||||
@ -72,7 +83,7 @@ CODE_SAMPLE
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if (! $this->isInDoctrineEntityClass($node)) {
|
||||
if (! $this->doctrineDocBlockResolver->isInDoctrineEntityClass($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ use PhpParser\Node\Name\FullyQualified;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Doctrine\PhpDocParser\DoctrineDocBlockResolver;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
@ -20,6 +21,16 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
*/
|
||||
final class ChangeSetIdTypeToUuidRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var DoctrineDocBlockResolver
|
||||
*/
|
||||
private $doctrineDocBlockResolver;
|
||||
|
||||
public function __construct(DoctrineDocBlockResolver $doctrineDocBlockResolver)
|
||||
{
|
||||
$this->doctrineDocBlockResolver = $doctrineDocBlockResolver;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition(
|
||||
@ -77,7 +88,7 @@ CODE_SAMPLE
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if (! $this->isInDoctrineEntityClass($node)) {
|
||||
if (! $this->doctrineDocBlockResolver->isInDoctrineEntityClass($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Property_\OneToOne
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Doctrine\Collector\UuidMigrationDataCollector;
|
||||
use Rector\Doctrine\PhpDocParser\Ast\PhpDoc\PhpDocTagNodeFactory;
|
||||
use Rector\Doctrine\PhpDocParser\DoctrineDocBlockResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
@ -45,14 +46,21 @@ final class AddUuidMirrorForRelationPropertyRector extends AbstractRector
|
||||
*/
|
||||
private $phpDocTagRemover;
|
||||
|
||||
/**
|
||||
* @var DoctrineDocBlockResolver
|
||||
*/
|
||||
private $doctrineDocBlockResolver;
|
||||
|
||||
public function __construct(
|
||||
PhpDocTagNodeFactory $phpDocTagNodeFactory,
|
||||
UuidMigrationDataCollector $uuidMigrationDataCollector,
|
||||
PhpDocTagRemover $phpDocTagRemover
|
||||
PhpDocTagRemover $phpDocTagRemover,
|
||||
DoctrineDocBlockResolver $doctrineDocBlockResolver
|
||||
) {
|
||||
$this->phpDocTagNodeFactory = $phpDocTagNodeFactory;
|
||||
$this->uuidMigrationDataCollector = $uuidMigrationDataCollector;
|
||||
$this->phpDocTagRemover = $phpDocTagRemover;
|
||||
$this->doctrineDocBlockResolver = $doctrineDocBlockResolver;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
@ -148,7 +156,7 @@ CODE_SAMPLE
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if (! $this->isDoctrineEntityClass($node)) {
|
||||
if (! $this->doctrineDocBlockResolver->isDoctrineEntityClass($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -176,7 +184,7 @@ CODE_SAMPLE
|
||||
return true;
|
||||
}
|
||||
|
||||
$targetEntity = $this->getTargetEntity($property);
|
||||
$targetEntity = $this->doctrineDocBlockResolver->getTargetEntity($property);
|
||||
if ($targetEntity === null) {
|
||||
return true;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ use Rector\Core\PhpParser\Node\Manipulator\ClassDependencyManipulator;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\ValueObject\MethodName;
|
||||
use Rector\Doctrine\NodeFactory\EntityUuidNodeFactory;
|
||||
use Rector\Doctrine\PhpDocParser\DoctrineDocBlockResolver;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
@ -35,12 +36,19 @@ final class AlwaysInitializeUuidInEntityRector extends AbstractRector
|
||||
*/
|
||||
private $classDependencyManipulator;
|
||||
|
||||
/**
|
||||
* @var DoctrineDocBlockResolver
|
||||
*/
|
||||
private $doctrineDocBlockResolver;
|
||||
|
||||
public function __construct(
|
||||
ClassDependencyManipulator $classDependencyManipulator,
|
||||
EntityUuidNodeFactory $entityUuidNodeFactory
|
||||
EntityUuidNodeFactory $entityUuidNodeFactory,
|
||||
DoctrineDocBlockResolver $doctrineDocBlockResolver
|
||||
) {
|
||||
$this->entityUuidNodeFactory = $entityUuidNodeFactory;
|
||||
$this->classDependencyManipulator = $classDependencyManipulator;
|
||||
$this->doctrineDocBlockResolver = $doctrineDocBlockResolver;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
@ -102,7 +110,7 @@ CODE_SAMPLE
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if (! $this->isDoctrineEntityClass($node)) {
|
||||
if (! $this->doctrineDocBlockResolver->isDoctrineEntityClass($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -69,6 +69,7 @@ CODE_SAMPLE
|
||||
}
|
||||
|
||||
$entityTagValueNode->removeRepositoryClass();
|
||||
$phpDocInfo->markAsChanged();
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ use PhpParser\Node\Stmt\Property;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
||||
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\AbstractDoctrineTagValueNode;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Property_\ColumnTagValueNode;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Property_\GeneratedValueTagValueNode;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\JMS\SerializerTypeTagValueNode;
|
||||
@ -91,7 +92,8 @@ CODE_SAMPLE
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if (! $this->isDoctrineProperty($node)) {
|
||||
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
|
||||
if (! $phpDocInfo->hasByType(AbstractDoctrineTagValueNode::class)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,6 @@ use PhpParser\Node\Stmt\Interface_;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
|
||||
use Rector\ChangesReporting\Collector\RectorChangeCollector;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use ReflectionMethod;
|
||||
@ -29,19 +28,13 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
*/
|
||||
final class DowngradeParameterTypeWideningRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var RectorChangeCollector
|
||||
*/
|
||||
private $rectorChangeCollector;
|
||||
|
||||
/**
|
||||
* @var PhpDocTypeChanger
|
||||
*/
|
||||
private $phpDocTypeChanger;
|
||||
|
||||
public function __construct(RectorChangeCollector $rectorChangeCollector, PhpDocTypeChanger $phpDocTypeChanger)
|
||||
public function __construct(PhpDocTypeChanger $phpDocTypeChanger)
|
||||
{
|
||||
$this->rectorChangeCollector = $rectorChangeCollector;
|
||||
$this->phpDocTypeChanger = $phpDocTypeChanger;
|
||||
}
|
||||
|
||||
@ -256,8 +249,6 @@ CODE_SAMPLE
|
||||
|
||||
// Remove the type
|
||||
$param->type = null;
|
||||
|
||||
$this->rectorChangeCollector->notifyNodeFileInfo($param);
|
||||
}
|
||||
|
||||
private function removeParamTypeFromMethodForChildren(
|
||||
|
@ -24,5 +24,6 @@ final class VarTagValueNodeRenamer
|
||||
}
|
||||
|
||||
$varTagValueNode->variableName = '$' . $expectedName;
|
||||
$phpDocInfo->markAsChanged();
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,8 @@ use PhpParser\Node\Stmt\Unset_;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\NetteCodeQuality\NodeResolver\FormVariableInputNameTypeResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Symplify\PackageBuilder\Php\TypeChecker;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
@ -27,9 +29,17 @@ final class ChangeFormArrayAccessToAnnotatedControlVariableRector extends Abstra
|
||||
*/
|
||||
private $formVariableInputNameTypeResolver;
|
||||
|
||||
public function __construct(FormVariableInputNameTypeResolver $formVariableInputNameTypeResolver)
|
||||
{
|
||||
/**
|
||||
* @var TypeChecker
|
||||
*/
|
||||
private $typeChecker;
|
||||
|
||||
public function __construct(
|
||||
FormVariableInputNameTypeResolver $formVariableInputNameTypeResolver,
|
||||
TypeChecker $typeChecker
|
||||
) {
|
||||
$this->formVariableInputNameTypeResolver = $formVariableInputNameTypeResolver;
|
||||
$this->typeChecker = $typeChecker;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
@ -91,7 +101,8 @@ CODE_SAMPLE
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->hasParentTypes($node, [Isset_::class, Unset_::class])) {
|
||||
$parent = $node->getAttribute(AttributeKey::PARENT_NODE);
|
||||
if ($this->typeChecker->isInstanceOf($parent, [Isset_::class, Unset_::class])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -147,6 +147,8 @@ CODE_SAMPLE
|
||||
private function decorateParamWithPropertyPhpDocInfo(Property $property, Param $param): void
|
||||
{
|
||||
$propertyPhpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
|
||||
$propertyPhpDocInfo->markAsChanged();
|
||||
|
||||
$param->setAttribute(AttributeKey::PHP_DOC_INFO, $propertyPhpDocInfo);
|
||||
|
||||
// make sure the docblock is useful
|
||||
|
@ -11,7 +11,6 @@ use PhpParser\Node\Stmt\ClassMethod;
|
||||
use Rector\Core\Rector\AbstractPHPUnitRector;
|
||||
use Rector\Core\Reflection\ClassMethodReflectionFactory;
|
||||
use Rector\FileSystemRector\Parser\FileInfoParser;
|
||||
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockManipulator;
|
||||
use ReflectionMethod;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
@ -69,10 +68,8 @@ final class AddDoesNotPerformAssertionToNonAssertingTestRector extends AbstractP
|
||||
|
||||
public function __construct(
|
||||
ClassMethodReflectionFactory $classMethodReflectionFactory,
|
||||
DocBlockManipulator $docBlockManipulator,
|
||||
FileInfoParser $fileInfoParser
|
||||
) {
|
||||
$this->docBlockManipulator = $docBlockManipulator;
|
||||
$this->fileInfoParser = $fileInfoParser;
|
||||
$this->classMethodReflectionFactory = $classMethodReflectionFactory;
|
||||
}
|
||||
|
@ -94,8 +94,6 @@ CODE_SAMPLE
|
||||
$seeTagNode = $this->createSeePhpDocTagNode($testCaseClassName);
|
||||
$phpDocInfo->addPhpDocTagNode($seeTagNode);
|
||||
|
||||
$this->notifyNodeFileInfo($node);
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
|
@ -120,6 +120,8 @@ CODE_SAMPLE
|
||||
$newMethodName = trim($newMethodName, '()');
|
||||
|
||||
$this->providerMethodNamesToNewNames[$oldMethodName] = $newMethodName;
|
||||
|
||||
$phpDocInfo->markAsChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,8 @@ final class ClassConstantFactory
|
||||
$classConst->flags = $property->flags & ~ Class_::MODIFIER_STATIC;
|
||||
|
||||
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
|
||||
$phpDocInfo->markAsChanged();
|
||||
|
||||
$classConst->setAttribute(AttributeKey::PHP_DOC_INFO, $phpDocInfo);
|
||||
|
||||
return $classConst;
|
||||
|
@ -10,6 +10,7 @@ use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use Rector\Caching\Contract\Rector\ZeroCacheRectorInterface;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Doctrine\PhpDocParser\DoctrineDocBlockResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\PhpAttribute\ValueObject\TagName;
|
||||
use Rector\Privatization\NodeAnalyzer\ClassMethodExternalCallNodeAnalyzer;
|
||||
@ -44,12 +45,19 @@ final class PrivatizeLocalOnlyMethodRector extends AbstractRector implements Zer
|
||||
*/
|
||||
private $classMethodExternalCallNodeAnalyzer;
|
||||
|
||||
/**
|
||||
* @var DoctrineDocBlockResolver
|
||||
*/
|
||||
private $doctrineDocBlockResolver;
|
||||
|
||||
public function __construct(
|
||||
ClassMethodExternalCallNodeAnalyzer $classMethodExternalCallNodeAnalyzer,
|
||||
ClassMethodVisibilityVendorLockResolver $classMethodVisibilityVendorLockResolver
|
||||
ClassMethodVisibilityVendorLockResolver $classMethodVisibilityVendorLockResolver,
|
||||
DoctrineDocBlockResolver $doctrineDocBlockResolver
|
||||
) {
|
||||
$this->classMethodVisibilityVendorLockResolver = $classMethodVisibilityVendorLockResolver;
|
||||
$this->classMethodExternalCallNodeAnalyzer = $classMethodExternalCallNodeAnalyzer;
|
||||
$this->doctrineDocBlockResolver = $doctrineDocBlockResolver;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
@ -209,7 +217,7 @@ CODE_SAMPLE
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->isDoctrineEntityClass($class)) {
|
||||
if ($this->doctrineDocBlockResolver->isDoctrineEntityClass($class)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ namespace Rector\Privatization\Rector\Class_;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Doctrine\PhpDocParser\DoctrineDocBlockResolver;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
@ -15,6 +16,16 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
*/
|
||||
final class FinalizeClassesWithoutChildrenRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var DoctrineDocBlockResolver
|
||||
*/
|
||||
private $doctrineDocBlockResolver;
|
||||
|
||||
public function __construct(DoctrineDocBlockResolver $doctrineDocBlockResolver)
|
||||
{
|
||||
$this->doctrineDocBlockResolver = $doctrineDocBlockResolver;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Finalize every class that has no children', [
|
||||
@ -66,13 +77,16 @@ CODE_SAMPLE
|
||||
if ($node->isFinal()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($node->isAbstract()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->isAnonymousClass($node)) {
|
||||
return null;
|
||||
}
|
||||
if ($this->isDoctrineEntityClass($node)) {
|
||||
|
||||
if ($this->doctrineDocBlockResolver->isDoctrineEntityClass($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ use Rector\Core\PhpParser\Node\BetterNodeFinder;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use Rector\NodeTypeResolver\ClassExistenceStaticHelper;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockManipulator;
|
||||
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockClassRenamer;
|
||||
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
|
||||
use Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;
|
||||
|
||||
@ -34,11 +34,6 @@ final class ClassRenamer
|
||||
*/
|
||||
private $alreadyProcessedClasses = [];
|
||||
|
||||
/**
|
||||
* @var DocBlockManipulator
|
||||
*/
|
||||
private $docBlockManipulator;
|
||||
|
||||
/**
|
||||
* @var NodeNameResolver
|
||||
*/
|
||||
@ -69,22 +64,27 @@ final class ClassRenamer
|
||||
*/
|
||||
private $phpDocInfoFactory;
|
||||
|
||||
/**
|
||||
* @var DocBlockClassRenamer
|
||||
*/
|
||||
private $docBlockClassRenamer;
|
||||
|
||||
public function __construct(
|
||||
BetterNodeFinder $betterNodeFinder,
|
||||
SimpleCallableNodeTraverser $simpleCallableNodeTraverser,
|
||||
ClassNaming $classNaming,
|
||||
DocBlockManipulator $docBlockManipulator,
|
||||
NodeNameResolver $nodeNameResolver,
|
||||
PhpDocClassRenamer $phpDocClassRenamer,
|
||||
PhpDocInfoFactory $phpDocInfoFactory
|
||||
PhpDocInfoFactory $phpDocInfoFactory,
|
||||
DocBlockClassRenamer $docBlockClassRenamer
|
||||
) {
|
||||
$this->docBlockManipulator = $docBlockManipulator;
|
||||
$this->nodeNameResolver = $nodeNameResolver;
|
||||
$this->simpleCallableNodeTraverser = $simpleCallableNodeTraverser;
|
||||
$this->phpDocClassRenamer = $phpDocClassRenamer;
|
||||
$this->classNaming = $classNaming;
|
||||
$this->betterNodeFinder = $betterNodeFinder;
|
||||
$this->phpDocInfoFactory = $phpDocInfoFactory;
|
||||
$this->docBlockClassRenamer = $docBlockClassRenamer;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -126,7 +126,7 @@ final class ClassRenamer
|
||||
$oldClassType = new ObjectType($oldClass);
|
||||
$newClassType = new FullyQualifiedObjectType($newClass);
|
||||
|
||||
$this->docBlockManipulator->changeType($phpDocInfo, $node, $oldClassType, $newClassType);
|
||||
$this->docBlockClassRenamer->renamePhpDocType($phpDocInfo, $oldClassType, $newClassType, $node);
|
||||
}
|
||||
|
||||
$this->phpDocClassRenamer->changeTypeInAnnotationTypes($phpDocInfo, $oldToNewClasses);
|
||||
|
@ -7,6 +7,7 @@ namespace Rector\Restoration\Rector\Class_;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Doctrine\PhpDocParser\DoctrineDocBlockResolver;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
@ -15,6 +16,16 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
*/
|
||||
final class RemoveFinalFromEntityRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var DoctrineDocBlockResolver
|
||||
*/
|
||||
private $doctrineDocBlockResolver;
|
||||
|
||||
public function __construct(DoctrineDocBlockResolver $doctrineDocBlockResolver)
|
||||
{
|
||||
$this->doctrineDocBlockResolver = $doctrineDocBlockResolver;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Remove final from Doctrine entities', [
|
||||
@ -57,7 +68,7 @@ CODE_SAMPLE
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if (! $this->isDoctrineEntityClass($node)) {
|
||||
if (! $this->doctrineDocBlockResolver->isDoctrineEntityClass($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -153,6 +153,7 @@ CODE_SAMPLE
|
||||
if (! $attributeAwareReturnTagValueNode instanceof AttributeAwareReturnTagValueNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (! $phpDocInfo->getReturnType() instanceof MixedType) {
|
||||
return;
|
||||
}
|
||||
@ -166,6 +167,7 @@ CODE_SAMPLE
|
||||
}
|
||||
|
||||
$attributeAwareReturnTagValueNode->type = $fullyQualifiedTypeNode;
|
||||
$phpDocInfo->markAsChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,6 +75,7 @@ CODE_SAMPLE
|
||||
}
|
||||
|
||||
$sensioRouteTagValueNode->removeService();
|
||||
$phpDocInfo->markAsChanged();
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\AbstractDoctrineTa
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\JMS\SerializerTypeTagValueNode;
|
||||
use Rector\Core\PhpParser\Node\BetterNodeFinder;
|
||||
use Rector\Core\PhpParser\NodeFinder\PropertyFetchFinder;
|
||||
use Rector\Doctrine\AbstractRector\DoctrineTrait;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\ReadWrite\Guard\VariableToConstantGuard;
|
||||
use Rector\ReadWrite\NodeAnalyzer\ReadWritePropertyAnalyzer;
|
||||
@ -31,8 +30,6 @@ use Symplify\PackageBuilder\Php\TypeChecker;
|
||||
*/
|
||||
final class PropertyManipulator
|
||||
{
|
||||
use DoctrineTrait;
|
||||
|
||||
/**
|
||||
* @var BetterNodeFinder
|
||||
*/
|
||||
|
@ -23,11 +23,11 @@ use PhpParser\Node\Stmt\TraitUse;
|
||||
use PhpParser\Node\Stmt\Use_;
|
||||
use PhpParser\PrettyPrinter\Standard;
|
||||
use Rector\Comments\CommentRemover;
|
||||
use Rector\Comments\NodeDocBlock\DocBlockUpdater;
|
||||
use Rector\Core\PhpParser\Node\CustomNode\FileNode;
|
||||
use Rector\Core\PhpParser\Node\CustomNode\FileWithoutNamespace;
|
||||
use Rector\Core\PhpParser\Printer\Whitespace\IndentCharacterDetector;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockManipulator;
|
||||
|
||||
/**
|
||||
* @see \Rector\Core\Tests\PhpParser\Printer\BetterStandardPrinterTest
|
||||
@ -72,9 +72,9 @@ final class BetterStandardPrinter extends Standard
|
||||
private $tabOrSpaceIndentCharacter = ' ';
|
||||
|
||||
/**
|
||||
* @var DocBlockManipulator
|
||||
* @var DocBlockUpdater
|
||||
*/
|
||||
private $docBlockManipulator;
|
||||
private $docBlockUpdater;
|
||||
|
||||
/**
|
||||
* @var CommentRemover
|
||||
@ -98,7 +98,7 @@ final class BetterStandardPrinter extends Standard
|
||||
CommentRemover $commentRemover,
|
||||
AnnotationFormatRestorer $annotationFormatRestorer,
|
||||
IndentCharacterDetector $indentCharacterDetector,
|
||||
DocBlockManipulator $docBlockManipulator,
|
||||
DocBlockUpdater $docBlockUpdater,
|
||||
array $options = []
|
||||
) {
|
||||
parent::__construct($options);
|
||||
@ -112,7 +112,7 @@ final class BetterStandardPrinter extends Standard
|
||||
$this->commentRemover = $commentRemover;
|
||||
$this->annotationFormatRestorer = $annotationFormatRestorer;
|
||||
$this->indentCharacterDetector = $indentCharacterDetector;
|
||||
$this->docBlockManipulator = $docBlockManipulator;
|
||||
$this->docBlockUpdater = $docBlockUpdater;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -531,7 +531,7 @@ final class BetterStandardPrinter extends Standard
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->docBlockManipulator->updateNodeWithPhpDocInfo($node);
|
||||
$this->docBlockUpdater->updateNodeWithPhpDocInfo($node);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,6 @@ use PhpParser\NodeVisitorAbstract;
|
||||
use Rector\Core\Configuration\CurrentNodeProvider;
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Rector\Core\Contract\Rector\PhpRectorInterface;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\Exclusion\ExclusionManager;
|
||||
use Rector\Core\Logging\CurrentRectorProvider;
|
||||
use Rector\Core\NodeAnalyzer\ClassNodeAnalyzer;
|
||||
@ -29,7 +28,6 @@ use Rector\Core\Php\PhpVersionProvider;
|
||||
use Rector\Core\Rector\AbstractRector\AbstractRectorTrait;
|
||||
use Rector\Core\ValueObject\ProjectType;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockManipulator;
|
||||
use Rector\StaticTypeMapper\StaticTypeMapper;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
use Symplify\PackageBuilder\Parameter\ParameterProvider;
|
||||
@ -57,11 +55,6 @@ abstract class AbstractRector extends NodeVisitorAbstract implements PhpRectorIn
|
||||
AttributeKey::RESOLVED_NAME,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const COMMENTS = 'comments';
|
||||
|
||||
/**
|
||||
* @var BuilderFactory
|
||||
*/
|
||||
@ -77,21 +70,11 @@ abstract class AbstractRector extends NodeVisitorAbstract implements PhpRectorIn
|
||||
*/
|
||||
protected $phpVersionProvider;
|
||||
|
||||
/**
|
||||
* @var DocBlockManipulator
|
||||
*/
|
||||
protected $docBlockManipulator;
|
||||
|
||||
/**
|
||||
* @var StaticTypeMapper
|
||||
*/
|
||||
protected $staticTypeMapper;
|
||||
|
||||
/**
|
||||
* @var SmartFileInfo
|
||||
*/
|
||||
private $currentFileInfo;
|
||||
|
||||
/**
|
||||
* @var SymfonyStyle
|
||||
*/
|
||||
@ -135,7 +118,6 @@ abstract class AbstractRector extends NodeVisitorAbstract implements PhpRectorIn
|
||||
PhpVersionProvider $phpVersionProvider,
|
||||
BuilderFactory $builderFactory,
|
||||
ExclusionManager $exclusionManager,
|
||||
DocBlockManipulator $docBlockManipulator,
|
||||
StaticTypeMapper $staticTypeMapper,
|
||||
ParameterProvider $parameterProvider,
|
||||
CurrentRectorProvider $currentRectorProvider,
|
||||
@ -147,7 +129,6 @@ abstract class AbstractRector extends NodeVisitorAbstract implements PhpRectorIn
|
||||
$this->phpVersionProvider = $phpVersionProvider;
|
||||
$this->builderFactory = $builderFactory;
|
||||
$this->exclusionManager = $exclusionManager;
|
||||
$this->docBlockManipulator = $docBlockManipulator;
|
||||
$this->staticTypeMapper = $staticTypeMapper;
|
||||
$this->parameterProvider = $parameterProvider;
|
||||
$this->currentRectorProvider = $currentRectorProvider;
|
||||
@ -166,34 +147,6 @@ abstract class AbstractRector extends NodeVisitorAbstract implements PhpRectorIn
|
||||
return parent::beforeTraverse($nodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $types
|
||||
*/
|
||||
public function hasParentTypes(Node $node, array $types): bool
|
||||
{
|
||||
foreach ($types as $type) {
|
||||
if (! is_a($type, Node::class, true)) {
|
||||
throw new ShouldNotHappenException(__METHOD__);
|
||||
}
|
||||
|
||||
if ($this->hasParentType($node, $type)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function hasParentType(Node $node, string $type): bool
|
||||
{
|
||||
$parent = $node->getAttribute(AttributeKey::PARENT_NODE);
|
||||
if (! $parent instanceof Node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return is_a($parent, $type, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Expression|Node|null
|
||||
*/
|
||||
@ -204,24 +157,12 @@ abstract class AbstractRector extends NodeVisitorAbstract implements PhpRectorIn
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->currentFileInfo = $node->getAttribute(SmartFileInfo::class);
|
||||
|
||||
$this->currentRectorProvider->changeCurrentRector($this);
|
||||
|
||||
// mostly for PHP doc and change notifications
|
||||
// for PHP doc info factory and change notifier
|
||||
$this->currentNodeProvider->setNode($node);
|
||||
|
||||
// already removed
|
||||
if ($this->isNodeRemoved($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->exclusionManager->isNodeSkippedByRector($node, $this)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$fileInfo = $node->getAttribute(AttributeKey::FILE_INFO);
|
||||
if ($fileInfo instanceof SmartFileInfo && $this->skipper->shouldSkipElementAndFileInfo($this, $fileInfo)) {
|
||||
if ($this->shouldSkipCurrentNode($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -293,7 +234,7 @@ abstract class AbstractRector extends NodeVisitorAbstract implements PhpRectorIn
|
||||
protected function mirrorComments(Node $newNode, Node $oldNode): void
|
||||
{
|
||||
$newNode->setAttribute(AttributeKey::PHP_DOC_INFO, $oldNode->getAttribute(AttributeKey::PHP_DOC_INFO));
|
||||
$newNode->setAttribute(self::COMMENTS, $oldNode->getAttribute(self::COMMENTS));
|
||||
$newNode->setAttribute(AttributeKey::COMMENTS, $oldNode->getAttribute(AttributeKey::COMMENTS));
|
||||
}
|
||||
|
||||
protected function rollbackComments(Node $node, Comment $comment): void
|
||||
@ -315,7 +256,7 @@ abstract class AbstractRector extends NodeVisitorAbstract implements PhpRectorIn
|
||||
$ifStmt->setAttribute(AttributeKey::PHP_DOC_INFO, $currentPhpDocInfo);
|
||||
|
||||
// move // comments
|
||||
$ifStmt->setAttribute(self::COMMENTS, $node->getComments());
|
||||
$ifStmt->setAttribute(AttributeKey::COMMENTS, $node->getComments());
|
||||
}
|
||||
|
||||
$this->addNodeAfterNode($ifStmt, $node);
|
||||
@ -373,15 +314,6 @@ abstract class AbstractRector extends NodeVisitorAbstract implements PhpRectorIn
|
||||
return $newArgs;
|
||||
}
|
||||
|
||||
protected function getFileInfo(): SmartFileInfo
|
||||
{
|
||||
if ($this->currentFileInfo === null) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
return $this->currentFileInfo;
|
||||
}
|
||||
|
||||
protected function unwrapExpression(Stmt $stmt): Node
|
||||
{
|
||||
if ($stmt instanceof Expression) {
|
||||
@ -472,4 +404,22 @@ abstract class AbstractRector extends NodeVisitorAbstract implements PhpRectorIn
|
||||
// names are the same
|
||||
return $this->areNodesEqual($originalNode->getAttribute(AttributeKey::ORIGINAL_NAME), $node);
|
||||
}
|
||||
|
||||
private function shouldSkipCurrentNode(Node $node): bool
|
||||
{
|
||||
if ($this->isNodeRemoved($node)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->exclusionManager->isNodeSkippedByRector($node, $this)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$fileInfo = $node->getAttribute(AttributeKey::FILE_INFO);
|
||||
if (! $fileInfo instanceof SmartFileInfo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->skipper->shouldSkipElementAndFileInfo($this, $fileInfo);
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ use Nette\Utils\Strings;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use Rector\ChangesReporting\Rector\AbstractRector\NotifyingRemovingNodeTrait;
|
||||
use Rector\Doctrine\AbstractRector\DoctrineTrait;
|
||||
use Rector\FileSystemRector\Behavior\FileSystemRectorTrait;
|
||||
use Rector\PostRector\Rector\AbstractRector\NodeCommandersTrait;
|
||||
|
||||
@ -17,7 +16,6 @@ trait AbstractRectorTrait
|
||||
use FileSystemRectorTrait;
|
||||
use PhpDocTrait;
|
||||
use RemovedAndAddedFilesTrait;
|
||||
use DoctrineTrait;
|
||||
use NodeTypeResolverTrait;
|
||||
use NameResolverTrait;
|
||||
use ConstFetchAnalyzerTrait;
|
||||
|
@ -57,7 +57,7 @@ final class LogIdentifierAndResolverValueInConstantClassMethodRector extends Abs
|
||||
$node->stmts = array_merge([$firstStmt], [$assignExpression], (array) $node->stmts);
|
||||
|
||||
// 2. record value in each return
|
||||
$this->traverseNodesWithCallable((array) $node->stmts, function (Node $node): ?Return_ {
|
||||
$this->traverseNodesWithCallable($node->stmts, function (Node $node): ?Return_ {
|
||||
if (! $node instanceof Return_) {
|
||||
return null;
|
||||
}
|
||||
|
@ -42,7 +42,6 @@ final class SymfonyConfigRectorValueObjectResolver
|
||||
$parent = $parent->getAttribute(PHPStanAttributeKey::PARENT);
|
||||
}
|
||||
|
||||
/** @var StaticCall|null $inlineStaticCall */
|
||||
$inlineStaticCall = $this->nodeFinder->findFirst($parent, function (Node $node): bool {
|
||||
if (! $node instanceof StaticCall) {
|
||||
return false;
|
||||
@ -51,13 +50,12 @@ final class SymfonyConfigRectorValueObjectResolver
|
||||
return $this->simpleNameResolver->isName($node->class, self::INLINE_CLASS_NAME);
|
||||
});
|
||||
|
||||
if ($inlineStaticCall === null) {
|
||||
if (! $inlineStaticCall instanceof StaticCall) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var New_|null $new */
|
||||
$new = $this->nodeFinder->findFirstInstanceOf($inlineStaticCall, New_::class);
|
||||
if ($new === null) {
|
||||
if (! $new instanceof New_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ final class SupportedTypeMappersDataProvider
|
||||
/**
|
||||
* @var TypeMapperInterface[]
|
||||
*/
|
||||
private $typeMappers;
|
||||
private $typeMappers = [];
|
||||
|
||||
/**
|
||||
* @param TypeMapperInterface[] $typeMappers
|
||||
|
@ -14,7 +14,7 @@ final class MissingPHPStanTypeMappersResolver
|
||||
/**
|
||||
* @var SupportedTypeMappersDataProvider
|
||||
*/
|
||||
private $supportedTypeMappersResolver;
|
||||
private $supportedTypeMappersDataProvider;
|
||||
|
||||
/**
|
||||
* @var PHPStanTypeClassFinder
|
||||
@ -23,9 +23,9 @@ final class MissingPHPStanTypeMappersResolver
|
||||
|
||||
public function __construct(
|
||||
PHPStanTypeClassFinder $phpStanTypeClassFinder,
|
||||
SupportedTypeMappersDataProvider $supportedTypeMappersResolver
|
||||
SupportedTypeMappersDataProvider $supportedTypeMappersDataProvider
|
||||
) {
|
||||
$this->supportedTypeMappersResolver = $supportedTypeMappersResolver;
|
||||
$this->supportedTypeMappersDataProvider = $supportedTypeMappersDataProvider;
|
||||
$this->phpStanTypeClassFinder = $phpStanTypeClassFinder;
|
||||
}
|
||||
|
||||
@ -35,7 +35,7 @@ final class MissingPHPStanTypeMappersResolver
|
||||
public function resolve(): array
|
||||
{
|
||||
$typeClasses = $this->phpStanTypeClassFinder->find();
|
||||
$supportedTypeClasses = $this->supportedTypeMappersResolver->provide();
|
||||
$supportedTypeClasses = $this->supportedTypeMappersDataProvider->provide();
|
||||
|
||||
$unsupportedTypeClasses = [];
|
||||
foreach ($typeClasses as $phpStanTypeClass) {
|
||||
|
@ -15,7 +15,6 @@ use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
use Symplify\PackageBuilder\Console\ShellCode;
|
||||
use Symplify\SmartFileSystem\Finder\FinderSanitizer;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
use Symplify\SmartFileSystem\SmartFileSystem;
|
||||
|
||||
@ -74,11 +73,6 @@ final class ValidateFixtureClassnameCommand extends Command
|
||||
'property',
|
||||
];
|
||||
|
||||
/**
|
||||
* @var FinderSanitizer
|
||||
*/
|
||||
private $finderSanitizer;
|
||||
|
||||
/**
|
||||
* @var SymfonyStyle
|
||||
*/
|
||||
@ -102,7 +96,7 @@ final class ValidateFixtureClassnameCommand extends Command
|
||||
/**
|
||||
* @var NamespaceMatcher
|
||||
*/
|
||||
private $namespaceMather;
|
||||
private $namespaceMatcher;
|
||||
|
||||
/**
|
||||
* @var ExpectedNameResolver
|
||||
@ -110,22 +104,19 @@ final class ValidateFixtureClassnameCommand extends Command
|
||||
private $expectedNameResolver;
|
||||
|
||||
public function __construct(
|
||||
FinderSanitizer $finderSanitizer,
|
||||
SymfonyStyle $symfonyStyle,
|
||||
ExpectedNameResolver $expectedNameResolver,
|
||||
SmartFileSystem $smartFileSystem,
|
||||
FixtureFinder $fixtureFinder,
|
||||
NamespaceMatcher $namespaceMather
|
||||
NamespaceMatcher $namespaceMatcher
|
||||
) {
|
||||
$this->finderSanitizer = $finderSanitizer;
|
||||
parent::__construct();
|
||||
|
||||
$this->symfonyStyle = $symfonyStyle;
|
||||
$this->currentDirectory = getcwd();
|
||||
$this->smartFileSystem = $smartFileSystem;
|
||||
|
||||
parent::__construct();
|
||||
|
||||
$this->fixtureFinder = $fixtureFinder;
|
||||
$this->namespaceMather = $namespaceMather;
|
||||
$this->namespaceMatcher = $namespaceMatcher;
|
||||
$this->expectedNameResolver = $expectedNameResolver;
|
||||
}
|
||||
|
||||
@ -149,7 +140,7 @@ final class ValidateFixtureClassnameCommand extends Command
|
||||
continue;
|
||||
}
|
||||
|
||||
$path = ltrim(substr($paths[0], strlen($this->currentDirectory)) . '/tests', '/');
|
||||
$path = ltrim(Strings::substring($paths[0], strlen($this->currentDirectory)) . '/tests', '/');
|
||||
|
||||
$expectedNamespace = $this->expectedNameResolver->resolve($path, $paths[1]);
|
||||
if ($expectedNamespace === null) {
|
||||
@ -160,8 +151,12 @@ final class ValidateFixtureClassnameCommand extends Command
|
||||
$fileContent = $this->smartFileSystem->readFile((string) $fixtureFileInfo);
|
||||
|
||||
$matchAll = Strings::matchAll($fileContent, self::NAMESPACE_REGEX);
|
||||
$namespaceMatcherIsFoundCorrectNamespace = $this->namespaceMatcher->isFoundCorrectNamespace(
|
||||
$matchAll,
|
||||
$expectedNamespace
|
||||
);
|
||||
|
||||
if (! $this->namespaceMather->isFoundCorrectNamespace($matchAll, $expectedNamespace)) {
|
||||
if (! $namespaceMatcherIsFoundCorrectNamespace) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -206,12 +201,14 @@ final class ValidateFixtureClassnameCommand extends Command
|
||||
bool $optionFix
|
||||
): array {
|
||||
$matchAll = Strings::matchAll($fileContent, self::CLASS_REGEX);
|
||||
|
||||
if ($matchAll === [] || count($matchAll) > 2) {
|
||||
if ($matchAll === []) {
|
||||
return $incorrectClassNameFiles;
|
||||
}
|
||||
if (count($matchAll) > 2) {
|
||||
return $incorrectClassNameFiles;
|
||||
}
|
||||
|
||||
$fileName = substr($fixtureFile->getFileName(), 0, -8);
|
||||
$fileName = Strings::substring($fixtureFile->getFileName(), 0, -8);
|
||||
|
||||
if (in_array($fileName, self::EXCLUDE_NAMES, true)) {
|
||||
return $incorrectClassNameFiles;
|
||||
@ -250,7 +247,7 @@ final class ValidateFixtureClassnameCommand extends Command
|
||||
string $expectedClassName
|
||||
): void {
|
||||
$newContent = str_replace('class ' . $incorrectClassName, 'class ' . $expectedClassName, $incorrectFileContent);
|
||||
$this->smartFileSystem->dumpFile((string) $incorrectClassNameFile, $newContent);
|
||||
$this->smartFileSystem->dumpFile($incorrectClassNameFile, $newContent);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -14,7 +14,6 @@ use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
use Symplify\PackageBuilder\Console\ShellCode;
|
||||
use Symplify\SmartFileSystem\Finder\FinderSanitizer;
|
||||
use Symplify\SmartFileSystem\SmartFileSystem;
|
||||
|
||||
final class ValidateFixtureNamespaceCommand extends Command
|
||||
@ -25,11 +24,6 @@ final class ValidateFixtureNamespaceCommand extends Command
|
||||
*/
|
||||
private const NAMESPACE_REGEX = '#^namespace (.*);$#msU';
|
||||
|
||||
/**
|
||||
* @var FinderSanitizer
|
||||
*/
|
||||
private $finderSanitizer;
|
||||
|
||||
/**
|
||||
* @var SymfonyStyle
|
||||
*/
|
||||
@ -61,21 +55,18 @@ final class ValidateFixtureNamespaceCommand extends Command
|
||||
private $expectedNameResolver;
|
||||
|
||||
public function __construct(
|
||||
FinderSanitizer $finderSanitizer,
|
||||
SymfonyStyle $symfonyStyle,
|
||||
SmartFileSystem $smartFileSystem,
|
||||
FixtureFinder $fixtureFinder,
|
||||
NamespaceMatcher $namespaceMatcher,
|
||||
ExpectedNameResolver $expectedNameResolver
|
||||
) {
|
||||
$this->finderSanitizer = $finderSanitizer;
|
||||
parent::__construct();
|
||||
|
||||
$this->symfonyStyle = $symfonyStyle;
|
||||
$this->currentDirectory = getcwd();
|
||||
$this->smartFileSystem = $smartFileSystem;
|
||||
$this->fixtureFinder = $fixtureFinder;
|
||||
|
||||
parent::__construct();
|
||||
|
||||
$this->namespaceMatcher = $namespaceMatcher;
|
||||
$this->expectedNameResolver = $expectedNameResolver;
|
||||
}
|
||||
@ -100,7 +91,7 @@ final class ValidateFixtureNamespaceCommand extends Command
|
||||
continue;
|
||||
}
|
||||
|
||||
$path = ltrim(substr($paths[0], strlen($this->currentDirectory)) . '/tests', '/');
|
||||
$path = ltrim(Strings::substring($paths[0], strlen($this->currentDirectory)) . '/tests', '/');
|
||||
$expectedNamespace = $this->expectedNameResolver->resolve($path, $paths[1]);
|
||||
|
||||
if ($expectedNamespace === null) {
|
||||
@ -157,7 +148,7 @@ final class ValidateFixtureNamespaceCommand extends Command
|
||||
'namespace ' . $expectedNamespace,
|
||||
$incorrectFileContent
|
||||
);
|
||||
$this->smartFileSystem->dumpFile((string) $incorrectNamespaceFile, $newContent);
|
||||
$this->smartFileSystem->dumpFile($incorrectNamespaceFile, $newContent);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -19,7 +19,12 @@ final class NamespaceMatcher
|
||||
if ($countMatchAll === 1 && $matchAll[0][1] === $expectedNamespace) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $countMatchAll === 2 && $matchAll[0][1] === $expectedNamespace && $matchAll[1][1] === $expectedNamespace;
|
||||
if ($countMatchAll !== 2) {
|
||||
return false;
|
||||
}
|
||||
if ($matchAll[0][1] !== $expectedNamespace) {
|
||||
return false;
|
||||
}
|
||||
return $matchAll[1][1] === $expectedNamespace;
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ final class TooLongFilesResolver
|
||||
{
|
||||
/**
|
||||
* In windows the max-path length is 260 chars. we give a bit room for the path up to the rector project
|
||||
* @var int
|
||||
*/
|
||||
public const MAX_FILE_LENGTH = 200;
|
||||
|
||||
@ -19,7 +20,7 @@ final class TooLongFilesResolver
|
||||
*/
|
||||
public function resolve(array $fileInfos): array
|
||||
{
|
||||
return array_filter($fileInfos, function (SmartFileInfo $fileInfo) {
|
||||
return array_filter($fileInfos, function (SmartFileInfo $fileInfo): bool {
|
||||
$filePathLength = strlen($fileInfo->getRealPath());
|
||||
return $filePathLength > self::MAX_FILE_LENGTH;
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user