Skip to content

Commit

Permalink
Fix IsEmptyTypeSpecifyingExtension for ReadableCollection
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Oct 26, 2022
1 parent ed600bf commit 4a8bbee
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 4 deletions.
9 changes: 9 additions & 0 deletions extension.neon
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,15 @@ services:
# Doctrine Collection
-
class: PHPStan\Type\Doctrine\Collection\IsEmptyTypeSpecifyingExtension
arguments:
collectionClass: Doctrine\Common\Collections\Collection
tags:
- phpstan.typeSpecifier.methodTypeSpecifyingExtension

-
class: PHPStan\Type\Doctrine\Collection\IsEmptyTypeSpecifyingExtension
arguments:
collectionClass: Doctrine\Common\Collections\ReadableCollection
tags:
- phpstan.typeSpecifier.methodTypeSpecifyingExtension

Expand Down
18 changes: 14 additions & 4 deletions src/Type/Doctrine/Collection/IsEmptyTypeSpecifyingExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,27 @@
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;

/** @var class-string */
private $collectionClass;

/**
* @param class-string $collectionClass
*/
public function __construct(string $collectionClass)
{
$this->collectionClass = $collectionClass;
}

public function getClass(): string
{
return self::COLLECTION_CLASS;
return $this->collectionClass;
}

public function isMethodSupported(
Expand All @@ -35,8 +45,8 @@ public function isMethodSupported(
): bool
{
return (
$methodReflection->getDeclaringClass()->getName() === self::COLLECTION_CLASS
|| $methodReflection->getDeclaringClass()->isSubclassOf(self::COLLECTION_CLASS)
$methodReflection->getDeclaringClass()->getName() === $this->collectionClass
|| $methodReflection->getDeclaringClass()->isSubclassOf($this->collectionClass)
)
&& $methodReflection->getName() === self::IS_EMPTY_METHOD_NAME;
}
Expand Down
1 change: 1 addition & 0 deletions tests/DoctrineIntegration/TypeInferenceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class TypeInferenceTest extends TypeInferenceTestCase
public function dataFileAsserts(): iterable
{
yield from $this->gatherAssertTypes(__DIR__ . '/data/getRepository.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/isEmpty.php');
}

/**
Expand Down
34 changes: 34 additions & 0 deletions tests/DoctrineIntegration/data/isEmpty.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace Bug375;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use function PHPStan\Testing\assertType;

class Foo
{

/** @var Collection<int, Bar> */
private Collection $shippingOptions;

public function __construct()
{
$this->shippingOptions = new ArrayCollection();
}

public function doFoo(): void
{
if ($this->shippingOptions->isEmpty()) {
return;
}

assertType(Bar::class, $this->shippingOptions->first());
}

}

class Bar
{

}

0 comments on commit 4a8bbee

Please sign in to comment.