Updated Rector to commit fe8e48de8cc6c962430abab1b1766c05dd12309e

fe8e48de8c [TypeDeclaration] Skip unset by trait on TypedPropertyFromStrictConstructorRector (#6664)
This commit is contained in:
Tomas Votruba 2025-01-10 11:36:09 +00:00
parent e936f2ae47
commit 348456e6b0
4 changed files with 50 additions and 23 deletions

View File

@ -19,12 +19,12 @@ final class VersionResolver
* @api
* @var string
*/
public const PACKAGE_VERSION = '8da1bfe2590771077da7ccd297f5df245d3e55c1';
public const PACKAGE_VERSION = 'fe8e48de8cc6c962430abab1b1766c05dd12309e';
/**
* @api
* @var string
*/
public const RELEASE_DATE = '2025-01-09 21:26:38';
public const RELEASE_DATE = '2025-01-10 18:33:46';
/**
* @var int
*/

View File

@ -20,8 +20,10 @@ use PhpParser\Node\Stmt\Trait_;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Type\ObjectType;
use PHPStan\Type\ThisType;
use Rector\DeadCode\NodeAnalyzer\PropertyWriteonlyAnalyzer;
use Rector\Enum\ObjectReference;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeNestingScope\ContextAnalyzer;
use Rector\NodeTypeResolver\NodeTypeResolver;
use Rector\PhpParser\AstResolver;
use Rector\PhpParser\Node\BetterNodeFinder;
@ -49,17 +51,27 @@ final class PropertyFetchAnalyzer
* @readonly
*/
private ReflectionResolver $reflectionResolver;
/**
* @readonly
*/
private ContextAnalyzer $contextAnalyzer;
/**
* @readonly
*/
private PropertyWriteonlyAnalyzer $propertyWriteonlyAnalyzer;
/**
* @var string
*/
private const THIS = 'this';
public function __construct(NodeNameResolver $nodeNameResolver, BetterNodeFinder $betterNodeFinder, AstResolver $astResolver, NodeTypeResolver $nodeTypeResolver, ReflectionResolver $reflectionResolver)
public function __construct(NodeNameResolver $nodeNameResolver, BetterNodeFinder $betterNodeFinder, AstResolver $astResolver, NodeTypeResolver $nodeTypeResolver, ReflectionResolver $reflectionResolver, ContextAnalyzer $contextAnalyzer, PropertyWriteonlyAnalyzer $propertyWriteonlyAnalyzer)
{
$this->nodeNameResolver = $nodeNameResolver;
$this->betterNodeFinder = $betterNodeFinder;
$this->astResolver = $astResolver;
$this->nodeTypeResolver = $nodeTypeResolver;
$this->reflectionResolver = $reflectionResolver;
$this->contextAnalyzer = $contextAnalyzer;
$this->propertyWriteonlyAnalyzer = $propertyWriteonlyAnalyzer;
}
public function isLocalPropertyFetch(Node $node) : bool
{
@ -102,10 +114,16 @@ final class PropertyFetchAnalyzer
return \true;
}
return (bool) $this->betterNodeFinder->findFirst($trait, function (Node $node) use($propertyName) : bool {
if (!$node instanceof Assign) {
if (!$this->isLocalPropertyFetchName($node, $propertyName)) {
return \false;
}
return $this->isLocalPropertyFetchName($node->var, $propertyName);
/**
* @var PropertyFetch|StaticPropertyFetch|NullsafePropertyFetch $node
*/
if ($this->contextAnalyzer->isChangeableContext($node)) {
return \true;
}
return $this->propertyWriteonlyAnalyzer->arePropertyFetchesExclusivelyBeingAssignedTo([$node]);
});
}
/**

View File

@ -19,6 +19,7 @@ use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\NodeAnalyzer\PropertyFetchAnalyzer;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeNestingScope\ContextAnalyzer;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
use Rector\Php80\NodeAnalyzer\PhpAttributeAnalyzer;
@ -78,11 +79,15 @@ final class PropertyManipulator
* @readonly
*/
private PropertyFetchAnalyzer $propertyFetchAnalyzer;
/**
* @readonly
*/
private ContextAnalyzer $contextAnalyzer;
/**
* @var string[]|class-string<Table>[]
*/
private const ALLOWED_NOT_READONLY_CLASS_ANNOTATIONS = ['ApiPlatform\\Core\\Annotation\\ApiResource', 'ApiPlatform\\Metadata\\ApiResource', 'Doctrine\\ORM\\Mapping\\Entity', 'Doctrine\\ORM\\Mapping\\Table', 'Doctrine\\ORM\\Mapping\\MappedSuperclass', 'Doctrine\\ORM\\Mapping\\Embeddable'];
public function __construct(\Rector\NodeManipulator\AssignManipulator $assignManipulator, BetterNodeFinder $betterNodeFinder, PhpDocInfoFactory $phpDocInfoFactory, PropertyFetchFinder $propertyFetchFinder, NodeNameResolver $nodeNameResolver, PhpAttributeAnalyzer $phpAttributeAnalyzer, NodeTypeResolver $nodeTypeResolver, PromotedPropertyResolver $promotedPropertyResolver, ConstructorAssignDetector $constructorAssignDetector, AstResolver $astResolver, PropertyFetchAnalyzer $propertyFetchAnalyzer)
public function __construct(\Rector\NodeManipulator\AssignManipulator $assignManipulator, BetterNodeFinder $betterNodeFinder, PhpDocInfoFactory $phpDocInfoFactory, PropertyFetchFinder $propertyFetchFinder, NodeNameResolver $nodeNameResolver, PhpAttributeAnalyzer $phpAttributeAnalyzer, NodeTypeResolver $nodeTypeResolver, PromotedPropertyResolver $promotedPropertyResolver, ConstructorAssignDetector $constructorAssignDetector, AstResolver $astResolver, PropertyFetchAnalyzer $propertyFetchAnalyzer, ContextAnalyzer $contextAnalyzer)
{
$this->assignManipulator = $assignManipulator;
$this->betterNodeFinder = $betterNodeFinder;
@ -95,6 +100,7 @@ final class PropertyManipulator
$this->constructorAssignDetector = $constructorAssignDetector;
$this->astResolver = $astResolver;
$this->propertyFetchAnalyzer = $propertyFetchAnalyzer;
$this->contextAnalyzer = $contextAnalyzer;
}
/**
* @param \PhpParser\Node\Stmt\Property|\PhpParser\Node\Param $propertyOrParam
@ -108,7 +114,7 @@ final class PropertyManipulator
$propertyFetches = $this->propertyFetchFinder->findPrivatePropertyFetches($class, $propertyOrParam, $scope);
$classMethod = $class->getMethod(MethodName::CONSTRUCT);
foreach ($propertyFetches as $propertyFetch) {
if ($this->isChangeableContext($propertyFetch)) {
if ($this->contextAnalyzer->isChangeableContext($propertyFetch)) {
return \true;
}
// skip for constructor? it is allowed to set value in constructor method
@ -192,22 +198,6 @@ final class PropertyManipulator
}
return $this->constructorAssignDetector->isPropertyAssigned($class, $propertyName);
}
/**
* @param \PhpParser\Node\Expr\PropertyFetch|\PhpParser\Node\Expr\StaticPropertyFetch $propertyFetch
*/
private function isChangeableContext($propertyFetch) : bool
{
if ($propertyFetch->getAttribute(AttributeKey::IS_UNSET_VAR, \false)) {
return \true;
}
if ($propertyFetch->getAttribute(AttributeKey::INSIDE_ARRAY_DIM_FETCH, \false)) {
return \true;
}
if ($propertyFetch->getAttribute(AttributeKey::IS_USED_AS_ARG_BY_REF_VALUE, \false) === \true) {
return \true;
}
return $propertyFetch->getAttribute(AttributeKey::IS_INCREMENT_OR_DECREMENT, \false) === \true;
}
private function hasAllowedNotReadonlyAnnotationOrAttribute(PhpDocInfo $phpDocInfo, Class_ $class) : bool
{
if ($phpDocInfo->hasByAnnotationClasses(self::ALLOWED_NOT_READONLY_CLASS_ANNOTATIONS)) {

View File

@ -4,6 +4,9 @@ declare (strict_types=1);
namespace Rector\NodeNestingScope;
use PhpParser\Node;
use PhpParser\Node\Expr\NullsafePropertyFetch;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\StaticPropertyFetch;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class ContextAnalyzer
{
@ -21,4 +24,20 @@ final class ContextAnalyzer
{
return $node->getAttribute(AttributeKey::IS_IN_IF) === \true;
}
/**
* @param \PhpParser\Node\Expr\PropertyFetch|\PhpParser\Node\Expr\StaticPropertyFetch|\PhpParser\Node\Expr\NullsafePropertyFetch $propertyFetch
*/
public function isChangeableContext($propertyFetch) : bool
{
if ($propertyFetch->getAttribute(AttributeKey::IS_UNSET_VAR, \false)) {
return \true;
}
if ($propertyFetch->getAttribute(AttributeKey::INSIDE_ARRAY_DIM_FETCH, \false)) {
return \true;
}
if ($propertyFetch->getAttribute(AttributeKey::IS_USED_AS_ARG_BY_REF_VALUE, \false) === \true) {
return \true;
}
return $propertyFetch->getAttribute(AttributeKey::IS_INCREMENT_OR_DECREMENT, \false) === \true;
}
}