Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 4a8bbee

Browse files
Fix IsEmptyTypeSpecifyingExtension for ReadableCollection
1 parent ed600bf commit 4a8bbee

File tree

4 files changed

+58
-4
lines changed

4 files changed

+58
-4
lines changed

‎extension.neon

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,15 @@ services:
370370
# Doctrine Collection
371371
-
372372
class: PHPStan\Type\Doctrine\Collection\IsEmptyTypeSpecifyingExtension
373+
arguments:
374+
collectionClass: Doctrine\Common\Collections\Collection
375+
tags:
376+
- phpstan.typeSpecifier.methodTypeSpecifyingExtension
377+
378+
-
379+
class: PHPStan\Type\Doctrine\Collection\IsEmptyTypeSpecifyingExtension
380+
arguments:
381+
collectionClass: Doctrine\Common\Collections\ReadableCollection
373382
tags:
374383
- phpstan.typeSpecifier.methodTypeSpecifyingExtension
375384

‎src/Type/Doctrine/Collection/IsEmptyTypeSpecifyingExtension.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,27 @@
1515
final class IsEmptyTypeSpecifyingExtension implements MethodTypeSpecifyingExtension, TypeSpecifierAwareExtension
1616
{
1717

18-
private const COLLECTION_CLASS = 'Doctrine\Common\Collections\Collection';
1918
private const IS_EMPTY_METHOD_NAME = 'isEmpty';
2019
private const FIRST_METHOD_NAME = 'first';
2120
private const LAST_METHOD_NAME = 'last';
2221

2322
/** @var TypeSpecifier */
2423
private $typeSpecifier;
2524

25+
/** @var class-string */
26+
private $collectionClass;
27+
28+
/**
29+
* @param class-string $collectionClass
30+
*/
31+
public function __construct(string $collectionClass)
32+
{
33+
$this->collectionClass = $collectionClass;
34+
}
35+
2636
public function getClass(): string
2737
{
28-
return self::COLLECTION_CLASS;
38+
return $this->collectionClass;
2939
}
3040

3141
public function isMethodSupported(
@@ -35,8 +45,8 @@ public function isMethodSupported(
3545
): bool
3646
{
3747
return (
38-
$methodReflection->getDeclaringClass()->getName() === self::COLLECTION_CLASS
39-
|| $methodReflection->getDeclaringClass()->isSubclassOf(self::COLLECTION_CLASS)
48+
$methodReflection->getDeclaringClass()->getName() === $this->collectionClass
49+
|| $methodReflection->getDeclaringClass()->isSubclassOf($this->collectionClass)
4050
)
4151
&& $methodReflection->getName() === self::IS_EMPTY_METHOD_NAME;
4252
}

‎tests/DoctrineIntegration/TypeInferenceTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class TypeInferenceTest extends TypeInferenceTestCase
1313
public function dataFileAsserts(): iterable
1414
{
1515
yield from $this->gatherAssertTypes(__DIR__ . '/data/getRepository.php');
16+
yield from $this->gatherAssertTypes(__DIR__ . '/data/isEmpty.php');
1617
}
1718

1819
/**
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
namespace Bug375;
4+
5+
use Doctrine\Common\Collections\ArrayCollection;
6+
use Doctrine\Common\Collections\Collection;
7+
use function PHPStan\Testing\assertType;
8+
9+
class Foo
10+
{
11+
12+
/** @var Collection<int, Bar> */
13+
private Collection $shippingOptions;
14+
15+
public function __construct()
16+
{
17+
$this->shippingOptions = new ArrayCollection();
18+
}
19+
20+
public function doFoo(): void
21+
{
22+
if ($this->shippingOptions->isEmpty()) {
23+
return;
24+
}
25+
26+
assertType(Bar::class, $this->shippingOptions->first());
27+
}
28+
29+
}
30+
31+
class Bar
32+
{
33+
34+
}

0 commit comments

Comments
(0)

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