From 3ef06bdaf4278638edb4890462e5245fcc6f5bbd Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Sun, 3 Dec 2023 11:18:10 +0000 Subject: [PATCH] Updated Rector to commit be924be778eeceffa6105ab330ea7eb366ebb44b https://github.com/rectorphp/rector-src/commit/be924be778eeceffa6105ab330ea7eb366ebb44b [TypeDeclaration] Add If else assign support on TypedPropertyFromAssignsRector (#5314) --- .../PHPStan/Type/TypeFactory.php | 7 ++++ .../PhpDoc/DeadVarTagValueNodeAnalyzer.php | 6 +++- .../ConstructorAssignDetector.php | 32 +++++++++++++++++++ src/Application/VersionResolver.php | 4 +-- 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/packages/NodeTypeResolver/PHPStan/Type/TypeFactory.php b/packages/NodeTypeResolver/PHPStan/Type/TypeFactory.php index 4a84a154432..99b3461f706 100644 --- a/packages/NodeTypeResolver/PHPStan/Type/TypeFactory.php +++ b/packages/NodeTypeResolver/PHPStan/Type/TypeFactory.php @@ -3,6 +3,8 @@ declare (strict_types=1); namespace Rector\NodeTypeResolver\PHPStan\Type; +use Rector\NodeTypeResolver\PHPStan\ObjectWithoutClassTypeWithParentTypes; +use PHPStan\Type\ObjectType; use PHPStan\Type\ArrayType; use PHPStan\Type\BooleanType; use PHPStan\Type\Constant\ConstantArrayType; @@ -56,7 +58,12 @@ final class TypeFactory { $constantTypeHashes = []; $uniqueTypes = []; + $totalTypes = \count($types); foreach ($types as $type) { + if ($totalTypes > 1 && $type instanceof ObjectWithoutClassTypeWithParentTypes) { + $parents = $type->getParentTypes(); + $type = new ObjectType($parents[0]->getClassName()); + } $removedConstantType = $this->removeValueFromConstantType($type); $removedConstantTypeHash = $this->typeHasher->createTypeHash($removedConstantType); if ($keepConstant && $type !== $removedConstantType) { diff --git a/rules/DeadCode/PhpDoc/DeadVarTagValueNodeAnalyzer.php b/rules/DeadCode/PhpDoc/DeadVarTagValueNodeAnalyzer.php index f1c8917a39c..bf0ebc5a0e8 100644 --- a/rules/DeadCode/PhpDoc/DeadVarTagValueNodeAnalyzer.php +++ b/rules/DeadCode/PhpDoc/DeadVarTagValueNodeAnalyzer.php @@ -6,6 +6,7 @@ namespace Rector\DeadCode\PhpDoc; use PhpParser\Node\Stmt\Property; use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode; use PHPStan\Type\IntersectionType; +use PHPStan\Type\TypeCombinator; use PHPStan\Type\UnionType; use Rector\NodeTypeResolver\TypeComparator\TypeComparator; use Rector\StaticTypeMapper\StaticTypeMapper; @@ -40,6 +41,9 @@ final class DeadVarTagValueNodeAnalyzer if ($propertyType instanceof UnionType && !$docType instanceof UnionType) { return !$docType instanceof IntersectionType; } - return $this->typeComparator->arePhpParserAndPhpStanPhpDocTypesEqual($property->type, $varTagValueNode->type, $property); + if ($this->typeComparator->arePhpParserAndPhpStanPhpDocTypesEqual($property->type, $varTagValueNode->type, $property)) { + return \true; + } + return $docType instanceof UnionType && $this->typeComparator->areTypesEqual(TypeCombinator::removeNull($docType), $propertyType); } } diff --git a/rules/TypeDeclaration/AlreadyAssignDetector/ConstructorAssignDetector.php b/rules/TypeDeclaration/AlreadyAssignDetector/ConstructorAssignDetector.php index 2f85d3312dc..09c7a0f132d 100644 --- a/rules/TypeDeclaration/AlreadyAssignDetector/ConstructorAssignDetector.php +++ b/rules/TypeDeclaration/AlreadyAssignDetector/ConstructorAssignDetector.php @@ -6,9 +6,12 @@ namespace Rector\TypeDeclaration\AlreadyAssignDetector; use PhpParser\Node; use PhpParser\Node\Expr; use PhpParser\Node\Expr\Assign; +use PhpParser\Node\Stmt; use PhpParser\Node\Stmt\ClassLike; use PhpParser\Node\Stmt\ClassMethod; +use PhpParser\Node\Stmt\Else_; use PhpParser\Node\Stmt\Expression; +use PhpParser\Node\Stmt\If_; use PhpParser\NodeTraverser; use PHPStan\Type\ObjectType; use Rector\Core\NodeAnalyzer\PropertyFetchAnalyzer; @@ -66,6 +69,10 @@ final class ConstructorAssignDetector $this->decorateFirstLevelStatementAttribute($initializeClassMethods); foreach ($initializeClassMethods as $initializeClassMethod) { $this->simpleCallableNodeTraverser->traverseNodesWithCallable((array) $initializeClassMethod->stmts, function (Node $node) use($propertyName, &$isAssignedInConstructor) : ?int { + if ($this->isIfElseAssign($node, $propertyName)) { + $isAssignedInConstructor = \true; + return NodeTraverser::STOP_TRAVERSAL; + } $expr = $this->matchAssignExprToPropertyName($node, $propertyName); if (!$expr instanceof Expr) { return null; @@ -86,6 +93,31 @@ final class ConstructorAssignDetector } return $isAssignedInConstructor; } + /** + * @param Stmt[] $stmts + */ + private function isAssignedInStmts(array $stmts, string $propertyName) : bool + { + $isAssigned = \false; + foreach ($stmts as $stmt) { + // non Expression can be on next stmt + if (!$stmt instanceof Expression) { + $isAssigned = \false; + break; + } + if ($this->matchAssignExprToPropertyName($stmt->expr, $propertyName) instanceof Expr) { + $isAssigned = \true; + } + } + return $isAssigned; + } + private function isIfElseAssign(Node $node, string $propertyName) : bool + { + if (!$node instanceof If_ || $node->elseifs !== [] || !$node->else instanceof Else_) { + return \false; + } + return $this->isAssignedInStmts($node->stmts, $propertyName) && $this->isAssignedInStmts($node->else->stmts, $propertyName); + } private function matchAssignExprToPropertyName(Node $node, string $propertyName) : ?Expr { if (!$node instanceof Assign) { diff --git a/src/Application/VersionResolver.php b/src/Application/VersionResolver.php index 95b4063b616..4885f5acf62 100644 --- a/src/Application/VersionResolver.php +++ b/src/Application/VersionResolver.php @@ -19,12 +19,12 @@ final class VersionResolver * @api * @var string */ - public const PACKAGE_VERSION = '368075b95cf10dff9d0313abbe94d3c6d3b28f67'; + public const PACKAGE_VERSION = 'be924be778eeceffa6105ab330ea7eb366ebb44b'; /** * @api * @var string */ - public const RELEASE_DATE = '2023-12-03 10:48:52'; + public const RELEASE_DATE = '2023-12-03 12:16:07'; /** * @var int */