diff --git a/extension.neon b/extension.neon index e49796c6..14d26486 100644 --- a/extension.neon +++ b/extension.neon @@ -313,6 +313,6 @@ services: # Doctrine Collection - - class: PHPStan\Type\Doctrine\Collection\FirstTypeSpecifyingExtension + class: PHPStan\Type\Doctrine\Collection\IsEmptyTypeSpecifyingExtension tags: - phpstan.typeSpecifier.methodTypeSpecifyingExtension diff --git a/src/Type/Doctrine/Collection/FirstTypeSpecifyingExtension.php b/src/Type/Doctrine/Collection/IsEmptyTypeSpecifyingExtension.php similarity index 80% rename from src/Type/Doctrine/Collection/FirstTypeSpecifyingExtension.php rename to src/Type/Doctrine/Collection/IsEmptyTypeSpecifyingExtension.php index e0ca8495..ca1e609a 100644 --- a/src/Type/Doctrine/Collection/FirstTypeSpecifyingExtension.php +++ b/src/Type/Doctrine/Collection/IsEmptyTypeSpecifyingExtension.php @@ -12,12 +12,13 @@ use PHPStan\Type\Constant\ConstantBooleanType; use PHPStan\Type\MethodTypeSpecifyingExtension; -final class FirstTypeSpecifyingExtension implements MethodTypeSpecifyingExtension, TypeSpecifierAwareExtension +final class IsEmptyTypeSpecifyingExtension implements MethodTypeSpecifyingExtension, TypeSpecifierAwareExtension { private const COLLECTION_CLASS = 'Doctrine\Common\Collections\Collection'; private const IS_EMPTY_METHOD_NAME = 'isEmpty'; private const FIRST_METHOD_NAME = 'first'; + private const LAST_METHOD_NAME = 'last'; /** @var TypeSpecifier */ private $typeSpecifier; @@ -47,11 +48,19 @@ public function specifyTypes( TypeSpecifierContext $context ): SpecifiedTypes { - return $this->typeSpecifier->create( + $first = $this->typeSpecifier->create( new MethodCall($node->var, self::FIRST_METHOD_NAME), new ConstantBooleanType(false), $context ); + + $last = $this->typeSpecifier->create( + new MethodCall($node->var, self::LAST_METHOD_NAME), + new ConstantBooleanType(false), + $context + ); + + return $first->unionWith($last); } public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void diff --git a/tests/Type/Doctrine/Collection/FirstTypeSpecifyingExtensionTest.php b/tests/Type/Doctrine/Collection/IsEmptyTypeSpecifyingExtensionTest.php similarity index 56% rename from tests/Type/Doctrine/Collection/FirstTypeSpecifyingExtensionTest.php rename to tests/Type/Doctrine/Collection/IsEmptyTypeSpecifyingExtensionTest.php index 8eeea9ae..2384b5b3 100644 --- a/tests/Type/Doctrine/Collection/FirstTypeSpecifyingExtensionTest.php +++ b/tests/Type/Doctrine/Collection/IsEmptyTypeSpecifyingExtensionTest.php @@ -7,7 +7,7 @@ /** * @extends \PHPStan\Testing\RuleTestCase */ -class FirstTypeSpecifyingExtensionTest extends \PHPStan\Testing\RuleTestCase +class IsEmptyTypeSpecifyingExtensionTest extends \PHPStan\Testing\RuleTestCase { protected function getRule(): Rule @@ -21,7 +21,7 @@ protected function getRule(): Rule protected function getMethodTypeSpecifyingExtensions(): array { return [ - new FirstTypeSpecifyingExtension(), + new IsEmptyTypeSpecifyingExtension(), ]; } @@ -29,16 +29,28 @@ public function testExtension(): void { $this->analyse([__DIR__ . '/data/collection.php'], [ [ - 'Variable $entityOrFalse is: MyEntity|false', + 'Variable $entityOrFalse1 is: MyEntity|false', 18, ], [ - 'Variable $false is: false', - 22, + 'Variable $entityOrFalse2 is: MyEntity|false', + 21, ], [ - 'Variable $entity is: MyEntity', - 27, + 'Variable $false1 is: false', + 25, + ], + [ + 'Variable $false2 is: false', + 28, + ], + [ + 'Variable $entity1 is: MyEntity', + 33, + ], + [ + 'Variable $entity2 is: MyEntity', + 36, ], ]); } diff --git a/tests/Type/Doctrine/Collection/data/collection.php b/tests/Type/Doctrine/Collection/data/collection.php index 4ced3056..249a8152 100644 --- a/tests/Type/Doctrine/Collection/data/collection.php +++ b/tests/Type/Doctrine/Collection/data/collection.php @@ -14,15 +14,24 @@ class MyEntity */ $collection = new ArrayCollection(); -$entityOrFalse = $collection->first(); -$entityOrFalse; +$entityOrFalse1 = $collection->first(); +$entityOrFalse1; + +$entityOrFalse2 = $collection->last(); +$entityOrFalse2; if ($collection->isEmpty()) { - $false = $collection->first(); - $false; + $false1 = $collection->first(); + $false1; + + $false2 = $collection->last(); + $false2; } if (!$collection->isEmpty()) { - $entity = $collection->first(); - $entity; + $entity1 = $collection->first(); + $entity1; + + $entity2 = $collection->last(); + $entity2; }

AltStyle によって変換されたページ (->オリジナル) /