diff --git a/rules/CodeQuality/Rector/Identical/FlipTypeControlToUseExclusiveTypeRector.php b/rules/CodeQuality/Rector/Identical/FlipTypeControlToUseExclusiveTypeRector.php index 847c235af92..430078db6f7 100644 --- a/rules/CodeQuality/Rector/Identical/FlipTypeControlToUseExclusiveTypeRector.php +++ b/rules/CodeQuality/Rector/Identical/FlipTypeControlToUseExclusiveTypeRector.php @@ -8,16 +8,12 @@ use PhpParser\Node\Expr; use PhpParser\Node\Expr\BinaryOp\Identical; use PhpParser\Node\Expr\BinaryOp\NotIdentical; -use PhpParser\Node\Expr\BooleanNot; -use PhpParser\Node\Expr\Instanceof_; -use PhpParser\Node\Name\FullyQualified; use PHPStan\Type\ObjectType; +use Rector\PhpParser\Node\NullableObjectToInstanceofFactory; use Rector\PhpParser\Node\Value\ValueResolver; use Rector\Rector\AbstractRector; use Rector\RuleDoc\CodeSample\CodeSample; use Rector\RuleDoc\RuleDefinition; -use Rector\StaticTypeMapper\ValueObject\Type\AliasedObjectType; -use Rector\StaticTypeMapper\ValueObject\Type\ShortenedObjectType; use Rector\TypeDeclaration\TypeAnalyzer\NullableTypeAnalyzer; /** @@ -28,6 +24,7 @@ final class FlipTypeControlToUseExclusiveTypeRector extends AbstractRector public function __construct( private readonly NullableTypeAnalyzer $nullableTypeAnalyzer, private readonly ValueResolver $valueResolver, + private readonly NullableObjectToInstanceofFactory $nullableObjectToInstanceofFactory, ) { } @@ -79,24 +76,7 @@ public function refactor(Node $node): ?Node return null; } - return $this->processConvertToExclusiveType($nullableObjectType, $expr, $node); - } - - private function processConvertToExclusiveType( - ObjectType $objectType, - Expr $expr, - Identical|NotIdentical $binaryOp - ): BooleanNot|Instanceof_ { - $fullyQualifiedType = $objectType instanceof ShortenedObjectType || $objectType instanceof AliasedObjectType - ? $objectType->getFullyQualifiedName() - : $objectType->getClassName(); - - $instanceof = new Instanceof_($expr, new FullyQualified($fullyQualifiedType)); - if ($binaryOp instanceof NotIdentical) { - return $instanceof; - } - - return new BooleanNot($instanceof); + return $this->nullableObjectToInstanceofFactory->create($expr, $nullableObjectType, $node instanceof Identical); } private function matchNullComparedExpr(Identical|NotIdentical $binaryOp): ?Expr diff --git a/rules/CodeQuality/Rector/If_/ObjectExplicitBoolCompareRector.php b/rules/CodeQuality/Rector/If_/ObjectExplicitBoolCompareRector.php index 46f7b350149..192e1e8232d 100644 --- a/rules/CodeQuality/Rector/If_/ObjectExplicitBoolCompareRector.php +++ b/rules/CodeQuality/Rector/If_/ObjectExplicitBoolCompareRector.php @@ -5,16 +5,13 @@ namespace Rector\CodeQuality\Rector\If_; use PhpParser\Node; -use PhpParser\Node\Expr; -use PhpParser\Node\Expr\BooleanNot; -use PhpParser\Node\Expr\Instanceof_; use PhpParser\Node\Expr\Ternary; -use PhpParser\Node\Name\FullyQualified; use PhpParser\Node\Stmt\ElseIf_; use PhpParser\Node\Stmt\If_; use PHPStan\Type\ObjectType; use Rector\CodeQuality\NodeAnalyzer\ExplicitBoolConditionResolver; use Rector\CodeQuality\ValueObject\ExplicitBoolCondition; +use Rector\PhpParser\Node\NullableObjectToInstanceofFactory; use Rector\Rector\AbstractRector; use Rector\RuleDoc\CodeSample\CodeSample; use Rector\RuleDoc\RuleDefinition; @@ -26,6 +23,7 @@ final class ObjectExplicitBoolCompareRector extends AbstractRector { public function __construct( private readonly ExplicitBoolConditionResolver $explicitBoolConditionResolver, + private readonly NullableObjectToInstanceofFactory $nullableObjectToInstanceofFactory, ) { } @@ -85,16 +83,12 @@ public function refactor(Node $node): ?Node return null; } - $node->cond = $this->resolveNullable($explicitBoolCondition->isNegated(), $expr, $objectType); + $node->cond = $this->nullableObjectToInstanceofFactory->create( + $expr, + $objectType, + $explicitBoolCondition->isNegated() + ); return $node; } - - private function resolveNullable(bool $isNegated, Expr $expr, ObjectType $objectType): BooleanNot|Instanceof_ - { - $fullyQualified = new FullyQualified($objectType->getClassName()); - $instanceof = new Instanceof_($expr, $fullyQualified); - - return $isNegated ? new BooleanNot($instanceof) : $instanceof; - } } diff --git a/rules/TypeDeclaration/Rector/BooleanAnd/BinaryOpNullableToInstanceofRector.php b/rules/TypeDeclaration/Rector/BooleanAnd/BinaryOpNullableToInstanceofRector.php index bbd61838e94..11ae83b7c4d 100644 --- a/rules/TypeDeclaration/Rector/BooleanAnd/BinaryOpNullableToInstanceofRector.php +++ b/rules/TypeDeclaration/Rector/BooleanAnd/BinaryOpNullableToInstanceofRector.php @@ -14,8 +14,8 @@ use PhpParser\Node\Expr\Empty_; use PhpParser\Node\Expr\Instanceof_; use PhpParser\Node\Expr\Isset_; -use PhpParser\Node\Name\FullyQualified; use PHPStan\Type\ObjectType; +use Rector\PhpParser\Node\NullableObjectToInstanceofFactory; use Rector\Rector\AbstractRector; use Rector\RuleDoc\CodeSample\CodeSample; use Rector\RuleDoc\RuleDefinition; @@ -28,6 +28,7 @@ final class BinaryOpNullableToInstanceofRector extends AbstractRector { public function __construct( private readonly NullableTypeAnalyzer $nullableTypeAnalyzer, + private readonly NullableObjectToInstanceofFactory $nullableObjectToInstanceofFactory, ) { } @@ -96,7 +97,7 @@ private function processNullableInstance(BooleanAnd|BooleanOr $node): null|Boole $hasChanged = false; if ($nullableObjectType instanceof ObjectType) { - $node->left = $this->createExprInstanceof($node->left, $nullableObjectType); + $node->left = $this->nullableObjectToInstanceofFactory->create($node->left, $nullableObjectType, false); $hasChanged = true; } @@ -104,7 +105,7 @@ private function processNullableInstance(BooleanAnd|BooleanOr $node): null|Boole $nullableObjectType = $this->resolveNullableObjectType($node->right); if ($nullableObjectType instanceof ObjectType) { - $node->right = $this->createExprInstanceof($node->right, $nullableObjectType); + $node->right = $this->nullableObjectToInstanceofFactory->create($node->right, $nullableObjectType, false); $hasChanged = true; } @@ -123,7 +124,7 @@ private function processNegationBooleanOr(BooleanOr $booleanOr): ?BooleanOr $nullableObjectType = $this->resolveNullableObjectType($booleanOr->left->expr); if ($nullableObjectType instanceof ObjectType) { - $booleanOr->left->expr = $this->createExprInstanceof($booleanOr->left->expr, $nullableObjectType); + $booleanOr->left->expr = $this->nullableObjectToInstanceofFactory->create($booleanOr->left->expr, $nullableObjectType, false); $hasChanged = true; } } @@ -132,7 +133,7 @@ private function processNegationBooleanOr(BooleanOr $booleanOr): ?BooleanOr $nullableObjectType = $this->resolveNullableObjectType($booleanOr->right->expr); if ($nullableObjectType instanceof ObjectType) { - $booleanOr->right->expr = $this->createExprInstanceof($booleanOr->right->expr, $nullableObjectType); + $booleanOr->right->expr = $this->nullableObjectToInstanceofFactory->create($booleanOr->right->expr, $nullableObjectType, false); $hasChanged = true; } @@ -164,10 +165,4 @@ private function isNeverNullableObject(Expr $expr): bool || $expr instanceof Empty_ || $expr instanceof Isset_; } - - private function createExprInstanceof(Expr $expr, ObjectType $objectType): Instanceof_ - { - $fullyQualified = new FullyQualified($objectType->getClassName()); - return new Instanceof_($expr, $fullyQualified); - } } diff --git a/rules/TypeDeclaration/Rector/While_/WhileNullableToInstanceofRector.php b/rules/TypeDeclaration/Rector/While_/WhileNullableToInstanceofRector.php index 791217c5816..234b7db998f 100644 --- a/rules/TypeDeclaration/Rector/While_/WhileNullableToInstanceofRector.php +++ b/rules/TypeDeclaration/Rector/While_/WhileNullableToInstanceofRector.php @@ -5,15 +5,13 @@ namespace Rector\TypeDeclaration\Rector\While_; use PhpParser\Node; -use PhpParser\Node\Expr; use PhpParser\Node\Expr\Assign; use PhpParser\Node\Expr\BinaryOp\NotIdentical; -use PhpParser\Node\Expr\Instanceof_; -use PhpParser\Node\Name\FullyQualified; use PhpParser\Node\Stmt\Do_; use PhpParser\Node\Stmt\While_; use PHPStan\Type\ObjectType; use PHPStan\Type\Type; +use Rector\PhpParser\Node\NullableObjectToInstanceofFactory; use Rector\PhpParser\Node\Value\ValueResolver; use Rector\Rector\AbstractRector; use Rector\RuleDoc\CodeSample\CodeSample; @@ -28,6 +26,7 @@ final class WhileNullableToInstanceofRector extends AbstractRector public function __construct( private readonly NullableTypeAnalyzer $nullableTypeAnalyzer, private readonly ValueResolver $valueResolver, + private readonly NullableObjectToInstanceofFactory $nullableObjectToInstanceofFactory, ) { } @@ -88,17 +87,11 @@ public function refactor(Node $node): ?Node return null; } - $node->cond = $this->createInstanceof($node->cond, $condNullableObjectType); + $node->cond = $this->nullableObjectToInstanceofFactory->create($node->cond, $condNullableObjectType, false); return $node; } - private function createInstanceof(Expr $expr, ObjectType $objectType): Instanceof_ - { - $fullyQualified = new FullyQualified($objectType->getClassName()); - return new Instanceof_($expr, $fullyQualified); - } - /** * @template TLoop of While_|Do_ * @param TLoop $while @@ -115,7 +108,7 @@ private function refactorNotIdentical(While_|Do_ $while, NotIdentical $notIdenti return null; } - $while->cond = $this->createInstanceof($notIdentical->left, $condNullableObjectType); + $while->cond = $this->nullableObjectToInstanceofFactory->create($notIdentical->left, $condNullableObjectType, false); return $while; } } diff --git a/src/PhpParser/Node/NullableObjectToInstanceofFactory.php b/src/PhpParser/Node/NullableObjectToInstanceofFactory.php new file mode 100644 index 00000000000..964f0fedd8d --- /dev/null +++ b/src/PhpParser/Node/NullableObjectToInstanceofFactory.php @@ -0,0 +1,27 @@ +getFullyQualifiedName() + : $objectType->getClassName(); + + $instanceof = new Instanceof_($expr, new FullyQualified($className)); + + return $isNegated ? new BooleanNot($instanceof) : $instanceof; + } +}