Getting rid of attribute (#5246)

Co-authored-by: rector-bot <tomas@getrector.org>
This commit is contained in:
Tomas Votruba 2021-01-19 22:32:28 +01:00 committed by GitHub
parent 81eeb2771b
commit 05356b393a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 349 additions and 329 deletions

View File

@ -49,15 +49,15 @@ final class CommentsMerger
return;
}
$arrayPhpDocInfo = $parent->getAttribute(AttributeKey::PHP_DOC_INFO);
$arrayComments = $parent->getComments();
$phpDocInfo = $parent->getAttribute(AttributeKey::PHP_DOC_INFO);
$comments = $parent->getComments();
if ($arrayPhpDocInfo === null && $arrayComments === []) {
if ($phpDocInfo === null && $comments === []) {
return;
}
$newNode->setAttribute(AttributeKey::PHP_DOC_INFO, $arrayPhpDocInfo);
$newNode->setAttribute(AttributeKey::COMMENTS, $arrayComments);
$newNode->setAttribute(AttributeKey::PHP_DOC_INFO, $phpDocInfo);
$newNode->setAttribute(AttributeKey::COMMENTS, $comments);
}
public function keepChildren(Node $newNode, Node $oldNode): void

View File

@ -225,6 +225,21 @@ final class PhpDocInfo
return (bool) $this->getByType($type);
}
/**
* @template T as \PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode
* @param class-string<T>[] $types
*/
public function hasByTypes(array $types): bool
{
foreach ($types as $type) {
if ($this->getByType($type)) {
return true;
}
}
return false;
}
/**
* @param string[] $names
*/

View File

@ -6,10 +6,10 @@ namespace Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer;
use PhpParser\Node;
use PHPStan\PhpDocParser\Ast\Node as PhpDocParserNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocNode;
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\StaticTypeMapper\StaticTypeMapper;
use Rector\StaticTypeMapper\ValueObject\Type\ShortenedObjectType;
use Symplify\SimplePhpDocParser\PhpDocNodeTraverser;
@ -41,24 +41,24 @@ final class DocBlockClassRenamer
* @param Type[] $oldTypes
*/
public function renamePhpDocTypes(
PhpDocNode $phpDocNode,
PhpDocInfo $phpDocInfo,
array $oldTypes,
Type $newType,
Node $phpParserNode
): void {
foreach ($oldTypes as $oldType) {
$this->renamePhpDocType($phpDocNode, $oldType, $newType, $phpParserNode);
$this->renamePhpDocType($phpDocInfo, $oldType, $newType, $phpParserNode);
}
}
public function renamePhpDocType(
PhpDocNode $phpDocNode,
PhpDocInfo $phpDocInfo,
Type $oldType,
Type $newType,
Node $phpParserNode
): bool {
$this->phpDocNodeTraverser->traverseWithCallable(
$phpDocNode,
$phpDocInfo->getPhpDocNode(),
'',
function (PhpDocParserNode $node) use ($phpParserNode, $oldType, $newType): PhpDocParserNode {
if (! $node instanceof IdentifierTypeNode) {

View File

@ -50,7 +50,7 @@ final class DocBlockManipulator
public function changeType(PhpDocInfo $phpDocInfo, Node $node, Type $oldType, Type $newType): void
{
$this->docBlockClassRenamer->renamePhpDocType($phpDocInfo->getPhpDocNode(), $oldType, $newType, $node);
$this->docBlockClassRenamer->renamePhpDocType($phpDocInfo, $oldType, $newType, $node);
}
public function updateNodeWithPhpDocInfo(Node $node): void

View File

@ -10,9 +10,8 @@ use PHPStan\PhpDocParser\Ast\Node as PhpDocParserNode;
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
use PHPStan\Type\ObjectType;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\Generic\ValueObject\PseudoNamespaceToNamespace;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\StaticTypeMapper\StaticTypeMapper;
use Symplify\SimplePhpDocParser\PhpDocNodeTraverser;
@ -28,20 +27,26 @@ final class PhpDocTypeRenamer
*/
private $staticTypeMapper;
public function __construct(PhpDocNodeTraverser $phpDocNodeTraverser, StaticTypeMapper $staticTypeMapper)
{
/**
* @var PhpDocInfoFactory
*/
private $phpDocInfoFactory;
public function __construct(
PhpDocNodeTraverser $phpDocNodeTraverser,
StaticTypeMapper $staticTypeMapper,
PhpDocInfoFactory $phpDocInfoFactory
) {
$this->phpDocNodeTraverser = $phpDocNodeTraverser;
$this->staticTypeMapper = $staticTypeMapper;
$this->phpDocInfoFactory = $phpDocInfoFactory;
}
public function changeUnderscoreType(
Node $node,
PseudoNamespaceToNamespace $pseudoNamespaceToNamespace
): void {
$phpDocInfo = $node->getAttribute(AttributeKey::PHP_DOC_INFO);
if (! $phpDocInfo instanceof PhpDocInfo) {
return;
}
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
$attributeAwarePhpDocNode = $phpDocInfo->getPhpDocNode();
$phpParserNode = $node;

View File

@ -5,10 +5,9 @@ declare(strict_types=1);
namespace Rector\PostRector\NodeAnalyzer;
use PhpParser\Node\Stmt\Class_;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\Core\ValueObject\MethodName;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\PhpAttribute\ValueObject\TagName;
use ReflectionClass;
use ReflectionMethod;
@ -20,9 +19,15 @@ final class NetteInjectDetector
*/
private $nodeNameResolver;
public function __construct(NodeNameResolver $nodeNameResolver)
/**
* @var PhpDocInfoFactory
*/
private $phpDocInfoFactory;
public function __construct(NodeNameResolver $nodeNameResolver, PhpDocInfoFactory $phpDocInfoFactory)
{
$this->nodeNameResolver = $nodeNameResolver;
$this->phpDocInfoFactory = $phpDocInfoFactory;
}
public function isNetteInjectPreferred(Class_ $class): bool
@ -41,17 +46,10 @@ final class NetteInjectDetector
continue;
}
$phpDocInfo = $property->getAttribute(AttributeKey::PHP_DOC_INFO);
if (! $phpDocInfo instanceof PhpDocInfo) {
continue;
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
if ($phpDocInfo->hasByName(TagName::INJECT)) {
return true;
}
$injectPhpDocInfoTagsName = $phpDocInfo->getTagsByName(TagName::INJECT);
if ($injectPhpDocInfoTagsName === []) {
continue;
}
return true;
}
return false;

View File

@ -11,7 +11,7 @@ use PhpParser\Node\Stmt\UseUse;
use PHPStan\Analyser\NameScope;
use PHPStan\Type\Generic\TemplateTypeMap;
use PHPStan\Type\Type;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\StaticTypeMapper\StaticTypeMapper;
@ -26,6 +26,20 @@ final class NameScopeFactory
*/
private $staticTypeMapper;
/**
* @var PhpDocInfoFactory
*/
private $phpDocInfoFactory;
/**
* This is needed to avoid circular references
* @required
*/
public function autowireNameScopeFactory(PhpDocInfoFactory $phpDocInfoFactory): void
{
$this->phpDocInfoFactory = $phpDocInfoFactory;
}
public function createNameScopeFromNodeWithoutTemplateTypes(Node $node): NameScope
{
$namespace = $node->getAttribute(AttributeKey::NAMESPACE_NAME);
@ -106,10 +120,7 @@ final class NameScopeFactory
*/
private function resolveTemplateTypesFromNode(Node $node): array
{
$phpDocInfo = $node->getAttribute(AttributeKey::PHP_DOC_INFO);
if (! $phpDocInfo instanceof PhpDocInfo) {
return [];
}
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
$templateTypes = [];
foreach ($phpDocInfo->getTemplateTagValueNodes() as $templateTagValueNode) {

View File

@ -5,7 +5,6 @@ declare(strict_types=1);
namespace Rector\Autodiscovery\Analyzer;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Property;
use PHPStan\Type\ObjectType;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\JMS\SerializerTypeTagValueNode;
@ -113,12 +112,8 @@ final class ClassAnalyzer
private function hasAllPropertiesWithSerialize(Class_ $class): bool
{
foreach ($class->stmts as $stmt) {
if (! $stmt instanceof Property) {
continue;
}
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($stmt);
foreach ($class->getProperties() as $property) {
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
if ($phpDocInfo->hasByType(SerializerTypeTagValueNode::class)) {
continue;
}

View File

@ -9,11 +9,10 @@ use PhpParser\Node\Stmt\Property;
use PHPStan\Type\ArrayType;
use PHPStan\Type\MixedType;
use PHPStan\Type\Type;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
use Rector\Core\Php\PhpVersionProvider;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\StaticTypeMapper\StaticTypeMapper;
final class PropertyTypeDecorator
@ -33,14 +32,21 @@ final class PropertyTypeDecorator
*/
private $phpDocTypeChanger;
/**
* @var PhpDocInfoFactory
*/
private $phpDocInfoFactory;
public function __construct(
PhpVersionProvider $phpVersionProvider,
StaticTypeMapper $staticTypeMapper,
PhpDocTypeChanger $phpDocTypeChanger
PhpDocTypeChanger $phpDocTypeChanger,
PhpDocInfoFactory $phpDocInfoFactory
) {
$this->phpVersionProvider = $phpVersionProvider;
$this->staticTypeMapper = $staticTypeMapper;
$this->phpDocTypeChanger = $phpDocTypeChanger;
$this->phpDocInfoFactory = $phpDocInfoFactory;
}
public function decorateProperty(Property $property, Type $propertyType): void
@ -51,8 +57,7 @@ final class PropertyTypeDecorator
private function decoratePropertyWithVarDoc(Property $property, Type $propertyType): void
{
/** @var PhpDocInfo $phpDocInfo */
$phpDocInfo = $property->getAttribute(AttributeKey::PHP_DOC_INFO);
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
if ($this->isNonMixedArrayType($propertyType)) {
$this->phpDocTypeChanger->changeVarType($phpDocInfo, $propertyType);

View File

@ -18,7 +18,7 @@ use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\ThrowsTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\NodeTypeResolver\FileSystem\CurrentFileInfoProvider;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;
@ -47,12 +47,19 @@ final class ShortNameResolver
*/
private $currentFileInfoProvider;
/**
* @var PhpDocInfoFactory
*/
private $phpDocInfoFactory;
public function __construct(
SimpleCallableNodeTraverser $simpleCallableNodeTraverser,
CurrentFileInfoProvider $currentFileInfoProvider
CurrentFileInfoProvider $currentFileInfoProvider,
PhpDocInfoFactory $phpDocInfoFactory
) {
$this->simpleCallableNodeTraverser = $simpleCallableNodeTraverser;
$this->currentFileInfoProvider = $currentFileInfoProvider;
$this->phpDocInfoFactory = $phpDocInfoFactory;
}
/**
@ -170,11 +177,10 @@ final class ShortNameResolver
{
$shortNames = [];
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($stmts, function (Node $node) use (&$shortNames) {
$phpDocInfo = $node->getAttribute(AttributeKey::PHP_DOC_INFO);
if (! $phpDocInfo instanceof PhpDocInfo) {
return null;
}
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($stmts, function (Node $node) use (
&$shortNames
): void {
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
foreach ($phpDocInfo->getPhpDocNode()->children as $phpDocChildNode) {
$shortTagName = $this->resolveShortTagNameFromPhpDocChildNode($phpDocChildNode);

View File

@ -9,7 +9,7 @@ use PhpParser\Node;
use PHPStan\Type\Type;
use PHPStan\Type\UnionType;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\StaticTypeMapper\ValueObject\Type\AliasedObjectType;
use Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;
@ -26,9 +26,17 @@ final class DocAliasResolver
*/
private $simpleCallableNodeTraverser;
public function __construct(SimpleCallableNodeTraverser $simpleCallableNodeTraverser)
{
/**
* @var PhpDocInfoFactory
*/
private $phpDocInfoFactory;
public function __construct(
SimpleCallableNodeTraverser $simpleCallableNodeTraverser,
PhpDocInfoFactory $phpDocInfoFactory
) {
$this->simpleCallableNodeTraverser = $simpleCallableNodeTraverser;
$this->phpDocInfoFactory = $phpDocInfoFactory;
}
/**
@ -46,9 +54,7 @@ final class DocAliasResolver
return;
}
/** @var PhpDocInfo $phpDocInfo */
$phpDocInfo = $node->getAttribute(AttributeKey::PHP_DOC_INFO);
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
$possibleDocAliases = $this->collectVarType($phpDocInfo, $possibleDocAliases);
// e.g. "use Dotrine\ORM\Mapping as ORM" etc.

View File

@ -13,13 +13,11 @@ 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;
use Rector\Doctrine\PhpDocParser\DoctrineDocBlockResolver;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
final class DoctrineEntityManipulator
@ -91,39 +89,29 @@ final class DoctrineEntityManipulator
return false;
}
$phpDocInfo = $class->getAttribute(AttributeKey::PHP_DOC_INFO);
if (! $phpDocInfo instanceof PhpDocInfo) {
return false;
}
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($class);
// is parent entity
if ($phpDocInfo->hasByType(InheritanceTypeTagValueNode::class)) {
return false;
}
return $phpDocInfo->hasByType(EntityTagValueNode::class);
return $phpDocInfo->hasByTypes([InheritanceTypeTagValueNode::class, EntityTagValueNode::class]);
}
public function removeMappedByOrInversedByFromProperty(Property $property): void
{
/** @var PhpDocInfo $phpDocInfo */
$phpDocInfo = $property->getAttribute(AttributeKey::PHP_DOC_INFO);
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
$relationTagValueNode = $phpDocInfo->getByType(DoctrineRelationTagValueNodeInterface::class);
$shouldUpdate = false;
if ($relationTagValueNode instanceof MappedByNodeInterface && $relationTagValueNode->getMappedBy()) {
$shouldUpdate = true;
$relationTagValueNode->removeMappedBy();
}
if ($relationTagValueNode instanceof InversedByNodeInterface && $relationTagValueNode->getInversedBy()) {
$shouldUpdate = true;
$relationTagValueNode->removeInversedBy();
}
if (! $shouldUpdate) {
if (! $relationTagValueNode instanceof InversedByNodeInterface) {
return;
}
if (! $relationTagValueNode->getInversedBy()) {
return;
}
$relationTagValueNode->removeInversedBy();
}
public function isMethodCallOnDoctrineEntity(Node $node, string $methodName): bool

View File

@ -7,8 +7,7 @@ namespace Rector\DeadCode\NodeManipulator;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
@ -19,9 +18,15 @@ final class ControllerClassMethodManipulator
*/
private $nodeNameResolver;
public function __construct(NodeNameResolver $nodeNameResolver)
/**
* @var PhpDocInfoFactory
*/
private $phpDocInfoFactory;
public function __construct(NodeNameResolver $nodeNameResolver, PhpDocInfoFactory $phpDocInfoFactory)
{
$this->nodeNameResolver = $nodeNameResolver;
$this->phpDocInfoFactory = $phpDocInfoFactory;
}
public function isControllerClassMethodWithBehaviorAnnotation(ClassMethod $classMethod): bool
@ -30,22 +35,8 @@ final class ControllerClassMethodManipulator
return false;
}
$phpDocInfo = $classMethod->getAttribute(AttributeKey::PHP_DOC_INFO);
if (! $phpDocInfo instanceof PhpDocInfo) {
return false;
}
foreach ($phpDocInfo->getPhpDocNode()->children as $phpDocChildNode) {
if (! $phpDocChildNode instanceof PhpDocTagNode) {
continue;
}
if ($phpDocChildNode->value instanceof GenericTagValueNode) {
return true;
}
}
return false;
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($classMethod);
return $phpDocInfo->hasByType(GenericTagValueNode::class);
}
private function isControllerClassMethod(ClassMethod $classMethod): bool

View File

@ -8,7 +8,6 @@ use PhpParser\Node\FunctionLike;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTagRemover;
use Rector\DeadDocBlock\DeadParamTagValueNodeAnalyzer;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class ParamTagRemover
{
@ -30,13 +29,8 @@ final class ParamTagRemover
$this->phpDocTagRemover = $phpDocTagRemover;
}
public function removeParamTagsIfUseless(FunctionLike $functionLike): void
public function removeParamTagsIfUseless(PhpDocInfo $phpDocInfo, FunctionLike $functionLike): void
{
$phpDocInfo = $functionLike->getAttribute(AttributeKey::PHP_DOC_INFO);
if (! $phpDocInfo instanceof PhpDocInfo) {
return;
}
foreach ($phpDocInfo->getParamTagValueNodes() as $paramTagValueNode) {
$paramName = $paramTagValueNode->parameterName;

View File

@ -9,7 +9,6 @@ use PHPStan\Type\Type;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTagRemover;
use Rector\DeadDocBlock\DeadReturnTagValueNodeAnalyzer;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class ReturnTagRemover
{
@ -31,13 +30,8 @@ final class ReturnTagRemover
$this->phpDocTagRemover = $phpDocTagRemover;
}
public function removeReturnTagIfUseless(FunctionLike $functionLike): void
public function removeReturnTagIfUseless(PhpDocInfo $phpDocInfo, FunctionLike $functionLike): void
{
$phpDocInfo = $functionLike->getAttribute(AttributeKey::PHP_DOC_INFO);
if (! $phpDocInfo instanceof PhpDocInfo) {
return;
}
// remove existing type
$attributeAwareReturnTagValueNode = $phpDocInfo->getReturnTagValue();
if ($attributeAwareReturnTagValueNode === null) {

View File

@ -13,7 +13,7 @@ use PHPStan\PhpDocParser\Ast\Type\GenericTypeNode;
use PHPStan\Type\Type;
use Rector\AttributeAwarePhpDoc\Ast\Type\AttributeAwareArrayTypeNode;
use Rector\AttributeAwarePhpDoc\Ast\Type\AttributeAwareUnionTypeNode;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\PHPStanStaticTypeMapper\DoctrineTypeAnalyzer;
use Rector\StaticTypeMapper\StaticTypeMapper;
@ -29,10 +29,19 @@ final class VarTagRemover
*/
private $staticTypeMapper;
public function __construct(DoctrineTypeAnalyzer $doctrineTypeAnalyzer, StaticTypeMapper $staticTypeMapper)
{
/**
* @var PhpDocInfoFactory
*/
private $phpDocInfoFactory;
public function __construct(
DoctrineTypeAnalyzer $doctrineTypeAnalyzer,
StaticTypeMapper $staticTypeMapper,
PhpDocInfoFactory $phpDocInfoFactory
) {
$this->doctrineTypeAnalyzer = $doctrineTypeAnalyzer;
$this->staticTypeMapper = $staticTypeMapper;
$this->phpDocInfoFactory = $phpDocInfoFactory;
}
/**
@ -45,14 +54,10 @@ final class VarTagRemover
return;
}
$propertyPhpDocInfo = $node->getAttribute(AttributeKey::PHP_DOC_INFO);
// nothing to remove
if ($propertyPhpDocInfo === null) {
return;
}
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
$varTagValueNode = $propertyPhpDocInfo->getByType(VarTagValueNode::class);
if ($varTagValueNode === null) {
$varTagValueNode = $phpDocInfo->getVarTagValueNode();
if (! $varTagValueNode instanceof VarTagValueNode) {
return;
}
@ -71,7 +76,7 @@ final class VarTagRemover
return;
}
$propertyPhpDocInfo->removeByType(VarTagValueNode::class);
$phpDocInfo->removeByType(VarTagValueNode::class);
}
/**

View File

@ -5,17 +5,27 @@ 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;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class ColumnDatetimePropertyAnalyzer
{
/**
* @var PhpDocInfoFactory
*/
private $phpDocInfoFactory;
public function __construct(PhpDocInfoFactory $phpDocInfoFactory)
{
$this->phpDocInfoFactory = $phpDocInfoFactory;
}
public function matchDateTimeColumnTagValueNodeInProperty(Property $property): ?ColumnTagValueNode
{
$phpDocInfo = $property->getAttribute(AttributeKey::PHP_DOC_INFO);
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
$columnTagValueNode = $phpDocInfo->getByType(ColumnTagValueNode::class);
if ($columnTagValueNode === null) {
if (! $columnTagValueNode instanceof ColumnTagValueNode) {
return null;
}

View File

@ -1,23 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\DoctrineCodeQuality\NodeAnalyzer;
use PhpParser\Node\Stmt\Class_;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Class_\EntityTagValueNode;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class DoctrineClassAnalyzer
{
public function matchDoctrineEntityTagValueNode(Class_ $class): ?EntityTagValueNode
{
$phpDocInfo = $class->getAttribute(AttributeKey::PHP_DOC_INFO);
if (! $phpDocInfo instanceof PhpDocInfo) {
return null;
}
return $phpDocInfo->getByType(EntityTagValueNode::class);
}
}

View File

@ -5,9 +5,8 @@ declare(strict_types=1);
namespace Rector\DoctrineCodeQuality\NodeManipulator;
use PhpParser\Node\Stmt\Property;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\Core\Exception\NotImplementedYetException;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockClassRenamer;
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
@ -18,9 +17,15 @@ final class PropertyTypeManipulator
*/
private $docBlockClassRenamer;
public function __construct(DocBlockClassRenamer $docBlockClassRenamer)
/**
* @var PhpDocInfoFactory
*/
private $phpDocInfoFactory;
public function __construct(DocBlockClassRenamer $docBlockClassRenamer, PhpDocInfoFactory $phpDocInfoFactory)
{
$this->docBlockClassRenamer = $docBlockClassRenamer;
$this->phpDocInfoFactory = $phpDocInfoFactory;
}
public function changePropertyType(Property $property, string $oldClass, string $newClass): void
@ -30,13 +35,10 @@ final class PropertyTypeManipulator
throw new NotImplementedYetException();
}
$phpDocInfo = $property->getAttribute(AttributeKey::PHP_DOC_INFO);
if (! $phpDocInfo instanceof PhpDocInfo) {
return;
}
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
$this->docBlockClassRenamer->renamePhpDocType(
$phpDocInfo->getPhpDocNode(),
$phpDocInfo,
new FullyQualifiedObjectType($oldClass),
new FullyQualifiedObjectType($newClass),
$property

View File

@ -6,8 +6,8 @@ namespace Rector\DoctrineCodeQuality\Rector\Class_;
use PhpParser\Node;
use PhpParser\Node\Stmt\Class_;
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Class_\EntityTagValueNode;
use Rector\Core\Rector\AbstractRector;
use Rector\DoctrineCodeQuality\NodeAnalyzer\DoctrineClassAnalyzer;
use Rector\DoctrineCodeQuality\NodeManipulator\DoctrineItemDefaultValueManipulator;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -17,21 +17,13 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
*/
final class RemoveRedundantDefaultClassAnnotationValuesRector extends AbstractRector
{
/**
* @var DoctrineClassAnalyzer
*/
private $doctrineClassAnalyzer;
/**
* @var DoctrineItemDefaultValueManipulator
*/
private $doctrineItemDefaultValueManipulator;
public function __construct(
DoctrineClassAnalyzer $doctrineClassAnalyzer,
DoctrineItemDefaultValueManipulator $doctrineItemDefaultValueManipulator
) {
$this->doctrineClassAnalyzer = $doctrineClassAnalyzer;
public function __construct(DoctrineItemDefaultValueManipulator $doctrineItemDefaultValueManipulator)
{
$this->doctrineItemDefaultValueManipulator = $doctrineItemDefaultValueManipulator;
}
@ -99,8 +91,10 @@ CODE_SAMPLE
private function refactorEntityAnnotation(Class_ $class): void
{
$entityTagValueNode = $this->doctrineClassAnalyzer->matchDoctrineEntityTagValueNode($class);
if ($entityTagValueNode === null) {
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($class);
$entityTagValueNode = $phpDocInfo->getByType(EntityTagValueNode::class);
if (! $entityTagValueNode instanceof EntityTagValueNode) {
return;
}

View File

@ -107,7 +107,7 @@ CODE_SAMPLE
}
$this->docBlockClassRenamer->renamePhpDocTypes(
$phpDocInfo->getPhpDocNode(),
$phpDocInfo,
[new IntegerType(), new FloatType(), new BooleanType()],
new StringType(),
$node

View File

@ -7,7 +7,6 @@ namespace Rector\Doctrine\AbstractRector;
use PhpParser\Node;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Property;
use Rector\BetterPhpDocParser\Contract\Doctrine\DoctrineRelationTagValueNodeInterface;
use Rector\Doctrine\PhpDocParser\DoctrineDocBlockResolver;
trait DoctrineTrait
@ -47,9 +46,4 @@ trait DoctrineTrait
{
return $this->doctrineDocBlockResolver->getTargetEntity($property);
}
protected function getDoctrineRelationTagValueNode(Property $property): ?DoctrineRelationTagValueNodeInterface
{
return $this->doctrineDocBlockResolver->getDoctrineRelationTagValueNode($property);
}
}

View File

@ -5,12 +5,11 @@ declare(strict_types=1);
namespace Rector\Doctrine\NodeFactory;
use PhpParser\Node\Stmt\Property;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Property_\GeneratedValueTagValueNode;
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Property_\IdTagValueNode;
use Rector\Core\PhpParser\Node\NodeFactory;
use Rector\Doctrine\PhpDocParser\Ast\PhpDoc\PhpDocTagNodeFactory;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class EntityIdNodeFactory
{
@ -24,10 +23,19 @@ final class EntityIdNodeFactory
*/
private $nodeFactory;
public function __construct(NodeFactory $nodeFactory, PhpDocTagNodeFactory $phpDocTagNodeFactory)
{
/**
* @var PhpDocInfoFactory
*/
private $phpDocInfoFactory;
public function __construct(
NodeFactory $nodeFactory,
PhpDocTagNodeFactory $phpDocTagNodeFactory,
PhpDocInfoFactory $phpDocInfoFactory
) {
$this->phpDocTagNodeFactory = $phpDocTagNodeFactory;
$this->nodeFactory = $nodeFactory;
$this->phpDocInfoFactory = $phpDocInfoFactory;
}
public function createIdProperty(): Property
@ -41,8 +49,7 @@ final class EntityIdNodeFactory
private function decoratePropertyWithIdAnnotations(Property $property): void
{
/** @var PhpDocInfo $phpDocInfo */
$phpDocInfo = $property->getAttribute(AttributeKey::PHP_DOC_INFO);
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
// add @var int
$attributeAwareVarTagValueNode = $this->phpDocTagNodeFactory->createVarTagIntValueNode();

View File

@ -12,13 +12,12 @@ use PhpParser\Node\Stmt\Property;
use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
use Ramsey\Uuid\Uuid;
use Rector\BetterPhpDocParser\Contract\Doctrine\DoctrineTagNodeInterface;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Property_\GeneratedValueTagValueNode;
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Property_\IdTagValueNode;
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\JMS\SerializerTypeTagValueNode;
use Rector\Core\PhpParser\Node\NodeFactory;
use Rector\Doctrine\PhpDocParser\Ast\PhpDoc\PhpDocTagNodeFactory;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class EntityUuidNodeFactory
{
@ -32,10 +31,19 @@ final class EntityUuidNodeFactory
*/
private $nodeFactory;
public function __construct(NodeFactory $nodeFactory, PhpDocTagNodeFactory $phpDocTagNodeFactory)
{
/**
* @var PhpDocInfoFactory
*/
private $phpDocInfoFactory;
public function __construct(
NodeFactory $nodeFactory,
PhpDocTagNodeFactory $phpDocTagNodeFactory,
PhpDocInfoFactory $phpDocInfoFactory
) {
$this->phpDocTagNodeFactory = $phpDocTagNodeFactory;
$this->nodeFactory = $nodeFactory;
$this->phpDocInfoFactory = $phpDocInfoFactory;
}
public function createTemporaryUuidProperty(): Property
@ -66,8 +74,7 @@ final class EntityUuidNodeFactory
$this->clearVarAndOrmAnnotations($property);
$this->replaceIntSerializerTypeWithString($property);
/** @var PhpDocInfo $phpDocInfo */
$phpDocInfo = $property->getAttribute(AttributeKey::PHP_DOC_INFO);
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
// add @var
$attributeAwareVarTagValueNode = $this->phpDocTagNodeFactory->createUuidInterfaceVarTagValueNode();
@ -94,10 +101,7 @@ final class EntityUuidNodeFactory
private function clearVarAndOrmAnnotations(Property $property): void
{
$phpDocInfo = $property->getAttribute(AttributeKey::PHP_DOC_INFO);
if (! $phpDocInfo instanceof PhpDocInfo) {
return;
}
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
$phpDocInfo->removeByType(VarTagValueNode::class);
$phpDocInfo->removeByType(DoctrineTagNodeInterface::class);
@ -108,10 +112,7 @@ final class EntityUuidNodeFactory
*/
private function replaceIntSerializerTypeWithString(Property $property): void
{
$phpDocInfo = $property->getAttribute(AttributeKey::PHP_DOC_INFO);
if (! $phpDocInfo instanceof PhpDocInfo) {
return;
}
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
$serializerTypeTagValueNode = $phpDocInfo->getByType(SerializerTypeTagValueNode::class);
if (! $serializerTypeTagValueNode instanceof SerializerTypeTagValueNode) {

View File

@ -66,12 +66,9 @@ final class DoctrineDocBlockResolver
return false;
}
foreach ($class->stmts as $classStmt) {
if (! $classStmt instanceof Property) {
continue;
}
if ($this->hasPropertyDoctrineIdTag($classStmt)) {
foreach ($class->getProperties() as $property) {
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
if ($phpDocInfo->hasByType(IdTagValueNode::class)) {
return true;
}
}
@ -81,24 +78,16 @@ final class DoctrineDocBlockResolver
public function getTargetEntity(Property $property): ?string
{
$doctrineRelationTagValueNode = $this->getDoctrineRelationTagValueNode($property);
if ($doctrineRelationTagValueNode === null) {
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
$doctrineRelationTagValueNode = $phpDocInfo->getByType(DoctrineRelationTagValueNodeInterface::class);
if (! $doctrineRelationTagValueNode instanceof DoctrineRelationTagValueNodeInterface) {
return null;
}
return $doctrineRelationTagValueNode->getTargetEntity();
}
public function getDoctrineRelationTagValueNode(Property $property): ?DoctrineRelationTagValueNodeInterface
{
$phpDocInfo = $property->getAttribute(AttributeKey::PHP_DOC_INFO);
if ($phpDocInfo === null) {
return null;
}
return $phpDocInfo->getByType(DoctrineRelationTagValueNodeInterface::class);
}
public function isDoctrineProperty(Property $property): bool
{
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
@ -118,12 +107,7 @@ final class DoctrineDocBlockResolver
private function isDoctrineEntityClassNode(Class_ $class): bool
{
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($class);
if ($phpDocInfo->hasByType(EntityTagValueNode::class)) {
return true;
}
return $phpDocInfo->hasByType(EmbeddableTagValueNode::class);
return $phpDocInfo->hasByTypes([EntityTagValueNode::class, EmbeddableTagValueNode::class]);
}
private function isStringClassEntity(string $class): bool
@ -144,11 +128,4 @@ final class DoctrineDocBlockResolver
return (bool) Strings::match($docCommentContent, self::ORM_ENTITY_EMBEDDABLE_SHORT_ANNOTATION_REGEX);
}
private function hasPropertyDoctrineIdTag(Property $property): bool
{
$phpDocInfo = $property->getAttribute(AttributeKey::PHP_DOC_INFO);
return $phpDocInfo ? $phpDocInfo->hasByType(IdTagValueNode::class) : false;
}
}

View File

@ -7,13 +7,12 @@ namespace Rector\Doctrine\Provider;
use Nette\Utils\Strings;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Property;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Property_\ColumnTagValueNode;
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Property_\IdTagValueNode;
use Rector\Doctrine\PhpDocParser\DoctrineDocBlockResolver;
use Rector\NodeCollector\NodeCollector\ParsedNodeCollector;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class EntityWithMissingUuidProvider
{
@ -43,14 +42,21 @@ final class EntityWithMissingUuidProvider
*/
private $nodeNameResolver;
/**
* @var PhpDocInfoFactory
*/
private $phpDocInfoFactory;
public function __construct(
DoctrineDocBlockResolver $doctrineDocBlockResolver,
NodeNameResolver $nodeNameResolver,
ParsedNodeCollector $parsedNodeCollector
ParsedNodeCollector $parsedNodeCollector,
PhpDocInfoFactory $phpDocInfoFactory
) {
$this->parsedNodeCollector = $parsedNodeCollector;
$this->doctrineDocBlockResolver = $doctrineDocBlockResolver;
$this->nodeNameResolver = $nodeNameResolver;
$this->phpDocInfoFactory = $phpDocInfoFactory;
}
/**
@ -88,16 +94,12 @@ final class EntityWithMissingUuidProvider
private function hasClassIdPropertyWithUuidType(Class_ $class): bool
{
foreach ($class->stmts as $classStmt) {
if (! $classStmt instanceof Property) {
foreach ($class->getProperties() as $property) {
if (! $this->nodeNameResolver->isName($property, 'id')) {
continue;
}
if (! $this->nodeNameResolver->isName($classStmt, 'id')) {
continue;
}
return $this->isPropertyClassIdWithUuidType($classStmt);
return $this->isPropertyClassIdWithUuidType($property);
}
return false;
@ -105,14 +107,13 @@ final class EntityWithMissingUuidProvider
private function isPropertyClassIdWithUuidType(Property $property): bool
{
/** @var PhpDocInfo $propertyPhpDocInfo */
$propertyPhpDocInfo = $property->getAttribute(AttributeKey::PHP_DOC_INFO);
if (! $propertyPhpDocInfo->hasByType(IdTagValueNode::class)) {
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
if (! $phpDocInfo->hasByType(IdTagValueNode::class)) {
return false;
}
$columnTagValueNode = $propertyPhpDocInfo->getByType(ColumnTagValueNode::class);
if ($columnTagValueNode === null) {
$columnTagValueNode = $phpDocInfo->getByType(ColumnTagValueNode::class);
if (! $columnTagValueNode instanceof ColumnTagValueNode) {
return false;
}

View File

@ -234,11 +234,10 @@ CODE_SAMPLE
private function mirrorPhpDocInfoToUuid(Property $property): void
{
$propertyPhpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
$newPropertyPhpDocInfo = clone $propertyPhpDocInfo;
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
$newPropertyPhpDocInfo = clone $phpDocInfo;
/** @var DoctrineRelationTagValueNodeInterface $doctrineRelationTagValueNode */
$doctrineRelationTagValueNode = $this->getDoctrineRelationTagValueNode($property);
$doctrineRelationTagValueNode = $phpDocInfo->getByType(DoctrineRelationTagValueNodeInterface::class);
if ($doctrineRelationTagValueNode instanceof ToManyTagNodeInterface) {
$this->refactorToManyPropertyPhpDocInfo($newPropertyPhpDocInfo, $property);
@ -252,12 +251,16 @@ CODE_SAMPLE
string $oldPropertyName,
string $uuidPropertyName
): void {
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
$doctrineRelationTagValueNode = $phpDocInfo->getByType(DoctrineRelationTagValueNodeInterface::class);
if (! $doctrineRelationTagValueNode instanceof DoctrineRelationTagValueNodeInterface) {
return;
}
/** @var string $className */
$className = $property->getAttribute(AttributeKey::CLASS_NAME);
/** @var DoctrineRelationTagValueNodeInterface $doctrineRelationTagValueNode */
$doctrineRelationTagValueNode = $this->getDoctrineRelationTagValueNode($property);
$this->uuidMigrationDataCollector->addClassToManyRelationProperty(
$className,
$oldPropertyName,

View File

@ -23,8 +23,13 @@ abstract class AbstractExpectedNameResolver implements ExpectedNameResolverInter
*/
protected $nodeNameResolver;
public function __construct(NodeNameResolver $nodeNameResolver, NodeTypeResolver $nodeTypeResolver)
{
/**
* @required
*/
public function autowireAbstractExpectedNameResolver(
NodeNameResolver $nodeNameResolver,
NodeTypeResolver $nodeTypeResolver
): void {
$this->nodeNameResolver = $nodeNameResolver;
$this->nodeTypeResolver = $nodeTypeResolver;
}

View File

@ -6,9 +6,8 @@ namespace Rector\Naming\ExpectedNameResolver;
use PhpParser\Node;
use PhpParser\Node\Stmt\Property;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\Naming\Naming\PropertyNaming;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class MatchPropertyTypeExpectedNameResolver extends AbstractExpectedNameResolver
{
@ -18,11 +17,14 @@ final class MatchPropertyTypeExpectedNameResolver extends AbstractExpectedNameRe
private $propertyNaming;
/**
* @required
* @var PhpDocInfoFactory
*/
public function autowireMatchPropertyTypeExpectedNameResolver(PropertyNaming $propertyNaming): void
private $phpDocInfoFactory;
public function __construct(PropertyNaming $propertyNaming, PhpDocInfoFactory $phpDocInfoFactory)
{
$this->propertyNaming = $propertyNaming;
$this->phpDocInfoFactory = $phpDocInfoFactory;
}
/**
@ -30,10 +32,7 @@ final class MatchPropertyTypeExpectedNameResolver extends AbstractExpectedNameRe
*/
public function resolve(Node $node): ?string
{
$phpDocInfo = $node->getAttribute(AttributeKey::PHP_DOC_INFO);
if (! $phpDocInfo instanceof PhpDocInfo) {
return null;
}
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
$expectedName = $this->propertyNaming->getExpectedNameFromType($phpDocInfo->getVarType());
if ($expectedName === null) {

View File

@ -19,8 +19,8 @@ final class VarTagValueNodeRenamer
return;
}
$varTagValueNode = $phpDocInfo->getByType(VarTagValueNode::class);
if ($varTagValueNode === null) {
$varTagValueNode = $phpDocInfo->getVarTagValueNode();
if (! $varTagValueNode instanceof VarTagValueNode) {
return;
}

View File

@ -5,9 +5,8 @@ declare(strict_types=1);
namespace Rector\NetteToSymfony\Routing;
use PhpParser\Node\Stmt\ClassMethod;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Symfony\SymfonyRouteTagValueNode;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\PostRector\Collector\UseNodesToAddCollector;
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
@ -23,17 +22,22 @@ final class ExplicitRouteAnnotationDecorator
*/
private $useNodesToAddCollector;
public function __construct(UseNodesToAddCollector $useNodesToAddCollector)
/**
* @var PhpDocInfoFactory
*/
private $phpDocInfoFactory;
public function __construct(UseNodesToAddCollector $useNodesToAddCollector, PhpDocInfoFactory $phpDocInfoFactory)
{
$this->useNodesToAddCollector = $useNodesToAddCollector;
$this->phpDocInfoFactory = $phpDocInfoFactory;
}
public function decorateClassMethodWithRouteAnnotation(
ClassMethod $classMethod,
SymfonyRouteTagValueNode $symfonyRouteTagValueNode
): void {
/** @var PhpDocInfo $phpDocInfo */
$phpDocInfo = $classMethod->getAttribute(AttributeKey::PHP_DOC_INFO);
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($classMethod);
$phpDocInfo->addTagValueNodeWithShortName($symfonyRouteTagValueNode);
$fullyQualifiedObjectType = new FullyQualifiedObjectType(SymfonyRouteTagValueNode::CLASS_NAME);

View File

@ -90,8 +90,8 @@ CODE_SAMPLE
$this->refactorParamTypes($node, $phpDocInfo);
$this->refactorReturnType($node, $phpDocInfo);
$this->paramTagRemover->removeParamTagsIfUseless($node);
$this->returnTagRemover->removeReturnTagIfUseless($node);
$this->paramTagRemover->removeParamTagsIfUseless($phpDocInfo, $node);
$this->returnTagRemover->removeReturnTagIfUseless($phpDocInfo, $node);
return $node;
}

View File

@ -9,6 +9,7 @@ use PhpParser\Node\Expr;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassConst;
use PhpParser\Node\Stmt\Property;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Privatization\Naming\ConstantNaming;
@ -19,9 +20,15 @@ final class ClassConstantFactory
*/
private $constantNaming;
public function __construct(ConstantNaming $constantNaming)
/**
* @var PhpDocInfoFactory
*/
private $phpDocInfoFactory;
public function __construct(ConstantNaming $constantNaming, PhpDocInfoFactory $phpDocInfoFactory)
{
$this->constantNaming = $constantNaming;
$this->phpDocInfoFactory = $phpDocInfoFactory;
}
public function createFromProperty(Property $property): ClassConst
@ -37,8 +44,8 @@ final class ClassConstantFactory
$classConst = new ClassConst([$const]);
$classConst->flags = $property->flags & ~ Class_::MODIFIER_STATIC;
$propertyPhpDocInfo = $property->getAttribute(AttributeKey::PHP_DOC_INFO);
$classConst->setAttribute(AttributeKey::PHP_DOC_INFO, $propertyPhpDocInfo);
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
$classConst->setAttribute(AttributeKey::PHP_DOC_INFO, $phpDocInfo);
return $classConst;
}

View File

@ -17,14 +17,13 @@ use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Property;
use PhpParser\Node\Stmt\Return_;
use PHPStan\Type\ObjectType;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\PhpParser\Node\NodeFactory;
use Rector\Core\ValueObject\MethodName;
use Rector\Naming\Naming\PropertyNaming;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\StaticTypeMapper\StaticTypeMapper;
use Symplify\Astral\ValueObject\NodeBuilder\ClassBuilder;
use Symplify\Astral\ValueObject\NodeBuilder\MethodBuilder;
@ -57,18 +56,25 @@ final class UniqueObjectFactoryFactory
*/
private $phpDocTypeChanger;
/**
* @var PhpDocInfoFactory
*/
private $phpDocInfoFactory;
public function __construct(
NodeFactory $nodeFactory,
NodeNameResolver $nodeNameResolver,
PropertyNaming $propertyNaming,
StaticTypeMapper $staticTypeMapper,
PhpDocTypeChanger $phpDocTypeChanger
PhpDocTypeChanger $phpDocTypeChanger,
PhpDocInfoFactory $phpDocInfoFactory
) {
$this->nodeNameResolver = $nodeNameResolver;
$this->propertyNaming = $propertyNaming;
$this->staticTypeMapper = $staticTypeMapper;
$this->nodeFactory = $nodeFactory;
$this->phpDocTypeChanger = $phpDocTypeChanger;
$this->phpDocInfoFactory = $phpDocInfoFactory;
}
public function createFactoryClass(Class_ $class, ObjectType $objectType): Class_
@ -114,16 +120,7 @@ final class UniqueObjectFactoryFactory
private function createPropertiesFromTypes(ObjectType $objectType): array
{
$properties = [];
$propertyName = $this->propertyNaming->fqnToVariableName($objectType);
$property = $this->nodeFactory->createPrivateProperty($propertyName);
/** @var PhpDocInfo $phpDocInfo */
$phpDocInfo = $property->getAttribute(AttributeKey::PHP_DOC_INFO);
$this->phpDocTypeChanger->changeVarType($phpDocInfo, $objectType);
$properties[] = $property;
$properties[] = $this->createPropertyFromObjectType($objectType);
return $properties;
}
@ -200,4 +197,15 @@ final class UniqueObjectFactoryFactory
return $assigns;
}
private function createPropertyFromObjectType(ObjectType $objectType): Property
{
$propertyName = $this->propertyNaming->fqnToVariableName($objectType);
$property = $this->nodeFactory->createPrivateProperty($propertyName);
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
$this->phpDocTypeChanger->changeVarType($phpDocInfo, $objectType);
return $property;
}
}

View File

@ -129,7 +129,7 @@ final class ClassRenamer
$this->docBlockManipulator->changeType($phpDocInfo, $node, $oldClassType, $newClassType);
}
$this->phpDocClassRenamer->changeTypeInAnnotationTypes($node, $oldToNewClasses);
$this->phpDocClassRenamer->changeTypeInAnnotationTypes($phpDocInfo, $oldToNewClasses);
}
/**

View File

@ -24,12 +24,14 @@ use PHPStan\Type\StringType;
use PHPStan\Type\Type;
use PHPStan\Type\UnionType;
use PHPStan\Type\VoidType;
use Rector\AttributeAwarePhpDoc\Ast\PhpDoc\AttributeAwareReturnTagValueNode;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
use Rector\StaticTypeMapper\ValueObject\Type\ParentStaticType;
use Rector\StaticTypeMapper\ValueObject\Type\SelfObjectType;
use Rector\StaticTypeMapper\ValueObject\Type\ShortenedObjectType;
use Symplify\PackageBuilder\Php\TypeChecker;
final class NonInformativeReturnTagRemover
{
@ -47,43 +49,56 @@ final class NonInformativeReturnTagRemover
ObjectWithoutClassType::class => ['object'],
];
/**
* @var PhpDocInfoFactory
*/
private $phpDocInfoFactory;
/**
* @var TypeChecker
*/
private $typeChecker;
public function __construct(PhpDocInfoFactory $phpDocInfoFactory, TypeChecker $typeChecker)
{
$this->phpDocInfoFactory = $phpDocInfoFactory;
$this->typeChecker = $typeChecker;
}
/**
* @param ClassMethod|Function_ $functionLike
*/
public function removeReturnTagIfNotUseful(FunctionLike $functionLike): void
{
$phpDocInfo = $functionLike->getAttribute(AttributeKey::PHP_DOC_INFO);
if (! $phpDocInfo instanceof PhpDocInfo) {
return;
}
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($functionLike);
$returnTagValueNode = $phpDocInfo->getByType(ReturnTagValueNode::class);
if ($returnTagValueNode === null) {
$attributeAwareReturnTagValueNode = $phpDocInfo->getReturnTagValue();
if (! $attributeAwareReturnTagValueNode instanceof ReturnTagValueNode) {
return;
}
// useful
if ($returnTagValueNode->description !== '') {
if ($attributeAwareReturnTagValueNode->description !== '') {
return;
}
$returnType = $phpDocInfo->getReturnType();
// is bare type
if ($returnType instanceof FloatType || $returnType instanceof StringType || $returnType instanceof IntegerType) {
if ($this->typeChecker->isInstanceOf($returnType, [FloatType::class, StringType::class, IntegerType::class])) {
$phpDocInfo->removeByType(ReturnTagValueNode::class);
return;
}
$this->removeNonUniqueUselessDocNames($returnType, $returnTagValueNode, $phpDocInfo);
$this->removeShortObjectType($returnType, $returnTagValueNode, $phpDocInfo);
$this->removeNullableType($returnType, $returnTagValueNode, $phpDocInfo);
$this->removeFullyQualifiedObjectType($returnType, $returnTagValueNode, $phpDocInfo);
$this->removeNonUniqueUselessDocNames($returnType, $attributeAwareReturnTagValueNode, $phpDocInfo);
$this->removeShortObjectType($returnType, $attributeAwareReturnTagValueNode, $phpDocInfo);
$this->removeNullableType($returnType, $attributeAwareReturnTagValueNode, $phpDocInfo);
$this->removeFullyQualifiedObjectType($returnType, $attributeAwareReturnTagValueNode, $phpDocInfo);
}
private function removeNonUniqueUselessDocNames(
Type $returnType,
ReturnTagValueNode $returnTagValueNode,
AttributeAwareReturnTagValueNode $attributeAwareReturnTagValueNode,
PhpDocInfo $phpDocInfo
): void {
foreach (self::USELESS_DOC_NAMES_BY_TYPE_CLASS as $typeClass => $uselessDocNames) {
@ -91,7 +106,7 @@ final class NonInformativeReturnTagRemover
continue;
}
if (! $this->isIdentifierWithValues($returnTagValueNode->type, $uselessDocNames)) {
if (! $this->isIdentifierWithValues($attributeAwareReturnTagValueNode->type, $uselessDocNames)) {
continue;
}
@ -102,14 +117,14 @@ final class NonInformativeReturnTagRemover
private function removeShortObjectType(
Type $returnType,
ReturnTagValueNode $returnTagValueNode,
AttributeAwareReturnTagValueNode $attributeAwareReturnTagValueNode,
PhpDocInfo $phpDocInfo
): void {
if (! $returnType instanceof ShortenedObjectType) {
return;
}
if (! $this->isIdentifierWithValues($returnTagValueNode->type, [$returnType->getShortName()])) {
if (! $this->isIdentifierWithValues($attributeAwareReturnTagValueNode->type, [$returnType->getShortName()])) {
return;
}
@ -118,7 +133,7 @@ final class NonInformativeReturnTagRemover
private function removeNullableType(
Type $returnType,
ReturnTagValueNode $returnTagValueNode,
AttributeAwareReturnTagValueNode $attributeAwareReturnTagValueNode,
PhpDocInfo $phpDocInfo
): void {
$nullabledReturnType = $this->matchNullabledType($returnType);
@ -126,7 +141,7 @@ final class NonInformativeReturnTagRemover
return;
}
$nullabledReturnTagValueNode = $this->matchNullabledReturnTagValueNode($returnTagValueNode);
$nullabledReturnTagValueNode = $this->matchNullabledReturnTagValueNode($attributeAwareReturnTagValueNode);
if ($nullabledReturnTagValueNode === null) {
return;
}
@ -148,19 +163,19 @@ final class NonInformativeReturnTagRemover
private function removeFullyQualifiedObjectType(
Type $returnType,
ReturnTagValueNode $returnTagValueNode,
AttributeAwareReturnTagValueNode $attributeAwareReturnTagValueNode,
PhpDocInfo $phpDocInfo
): void {
if (! $returnType instanceof FullyQualifiedObjectType) {
return;
}
if (! $returnTagValueNode->type instanceof IdentifierTypeNode) {
if (! $attributeAwareReturnTagValueNode->type instanceof IdentifierTypeNode) {
return;
}
$className = $returnType->getClassName();
$returnTagValueNodeType = (string) $returnTagValueNode->type;
$returnTagValueNodeType = (string) $attributeAwareReturnTagValueNode->type;
if ($this->isClassNameAndPartMatch($className, $returnTagValueNodeType)) {
$phpDocInfo->removeByType(ReturnTagValueNode::class);
@ -204,17 +219,18 @@ final class NonInformativeReturnTagRemover
return null;
}
private function matchNullabledReturnTagValueNode(ReturnTagValueNode $returnTagValueNode): ?TypeNode
{
if (! $returnTagValueNode->type instanceof UnionTypeNode) {
private function matchNullabledReturnTagValueNode(
AttributeAwareReturnTagValueNode $attributeAwareReturnTagValueNode
): ?TypeNode {
if (! $attributeAwareReturnTagValueNode->type instanceof UnionTypeNode) {
return null;
}
if (count($returnTagValueNode->type->types) !== 2) {
if (count($attributeAwareReturnTagValueNode->type->types) !== 2) {
return null;
}
foreach ($returnTagValueNode->type->types as $unionedReturnTagValueNode) {
foreach ($attributeAwareReturnTagValueNode->type->types as $unionedReturnTagValueNode) {
if ($this->isIdentifierWithValues($unionedReturnTagValueNode, ['null'])) {
continue;
}

View File

@ -10,7 +10,7 @@ use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\PropertyProperty;
use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\Core\Contract\Rector\PhpRectorInterface;
use Rector\Core\Contract\Rector\RectorInterface;
use Rector\Core\Exception\ShouldNotHappenException;
@ -22,6 +22,16 @@ use Rector\NodeTypeResolver\Node\AttributeKey;
*/
final class ExclusionManager
{
/**
* @var PhpDocInfoFactory
*/
private $phpDocInfoFactory;
public function __construct(PhpDocInfoFactory $phpDocInfoFactory)
{
$this->phpDocInfoFactory = $phpDocInfoFactory;
}
public function isNodeSkippedByRector(Node $node, PhpRectorInterface $phpRector): bool
{
if ($node instanceof PropertyProperty || $node instanceof Const_) {
@ -46,10 +56,7 @@ final class ExclusionManager
private function hasNoRectorPhpDocTagMatch(Node $node, PhpRectorInterface $phpRector): bool
{
$phpDocInfo = $node->getAttribute(AttributeKey::PHP_DOC_INFO);
if (! $phpDocInfo instanceof PhpDocInfo) {
return false;
}
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
/** @var PhpDocTagNode[] $noRectorTags */
$noRectorTags = array_merge($phpDocInfo->getTagsByName('noRector'), $phpDocInfo->getTagsByName('norector'));

View File

@ -4,12 +4,10 @@ declare(strict_types=1);
namespace Rector\Core\PhpDoc;
use PhpParser\Node;
use Rector\BetterPhpDocParser\Contract\Doctrine\DoctrineRelationTagValueNodeInterface;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\JMS\SerializerTypeTagValueNode;
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Symfony\Validator\Constraints\AssertChoiceTagValueNode;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class PhpDocClassRenamer
{
@ -19,11 +17,8 @@ final class PhpDocClassRenamer
*
* @param string[] $oldToNewClasses
*/
public function changeTypeInAnnotationTypes(Node $node, array $oldToNewClasses): void
public function changeTypeInAnnotationTypes(PhpDocInfo $phpDocInfo, array $oldToNewClasses): void
{
/** @var PhpDocInfo $phpDocInfo */
$phpDocInfo = $node->getAttribute(AttributeKey::PHP_DOC_INFO);
$this->processAssertChoiceTagValueNode($oldToNewClasses, $phpDocInfo);
$this->processDoctrineRelationTagValueNode($oldToNewClasses, $phpDocInfo);
$this->processSerializerTypeTagValueNode($oldToNewClasses, $phpDocInfo);