Skip to content

Commit

Permalink
[PropertyInfo] Handle collection in PhpStan same as PhpDoc
Browse files Browse the repository at this point in the history
  • Loading branch information
mtarld committed Jul 5, 2024
1 parent 4e57b84 commit f098683
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use PHPUnit\Framework\TestCase;
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
use Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy;
use Symfony\Component\PropertyInfo\Tests\Fixtures\DummyCollection;
use Symfony\Component\PropertyInfo\Tests\Fixtures\ParentDummy;
use Symfony\Component\PropertyInfo\Tests\Fixtures\PseudoTypeDummy;
use Symfony\Component\PropertyInfo\Tests\Fixtures\TraitUsage\DummyUsedInTrait;
Expand Down Expand Up @@ -160,6 +161,7 @@ public static function typesProvider()
null,
],
['self', [new Type(Type::BUILTIN_TYPE_OBJECT, false, Dummy::class)], null, null],
['collectionAsObject', [new Type(Type::BUILTIN_TYPE_OBJECT, false, DummyCollection::class, true, [new Type(Type::BUILTIN_TYPE_INT)], [new Type(Type::BUILTIN_TYPE_STRING)])], null, null],
];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use Symfony\Component\PropertyInfo\Tests\Fixtures\ConstructorDummyWithoutDocBlock;
use Symfony\Component\PropertyInfo\Tests\Fixtures\DefaultValue;
use Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy;
use Symfony\Component\PropertyInfo\Tests\Fixtures\DummyCollection;
use Symfony\Component\PropertyInfo\Tests\Fixtures\ParentDummy;
use Symfony\Component\PropertyInfo\Tests\Fixtures\RootDummy\RootDummyItem;
use Symfony\Component\PropertyInfo\Tests\Fixtures\TraitUsage\AnotherNamespace\DummyInAnotherNamespace;
Expand Down Expand Up @@ -130,6 +131,7 @@ public static function typesProvider()
['self', [new Type(Type::BUILTIN_TYPE_OBJECT, false, Dummy::class)]],
['rootDummyItems', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_OBJECT, false, RootDummyItem::class))]],
['rootDummyItem', [new Type(Type::BUILTIN_TYPE_OBJECT, false, RootDummyItem::class)]],
['collectionAsObject', [new Type(Type::BUILTIN_TYPE_OBJECT, false, DummyCollection::class, true, [new Type(Type::BUILTIN_TYPE_INT)], [new Type(Type::BUILTIN_TYPE_STRING)])]],
];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public function testGetProperties()
'bal',
'parent',
'collection',
'collectionAsObject',
'nestedCollection',
'mixedCollection',
'B',
Expand Down Expand Up @@ -118,6 +119,7 @@ public function testGetPropertiesWithCustomPrefixes()
'bal',
'parent',
'collection',
'collectionAsObject',
'nestedCollection',
'mixedCollection',
'B',
Expand Down Expand Up @@ -172,6 +174,7 @@ public function testGetPropertiesWithNoPrefixes()
'bal',
'parent',
'collection',
'collectionAsObject',
'nestedCollection',
'mixedCollection',
'B',
Expand Down
5 changes: 5 additions & 0 deletions src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ class Dummy extends ParentDummy
*/
public $collection;

/**
* @var DummyCollection<int, string>
*/
public $collectionAsObject;

/**
* @var string[][]
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\PropertyInfo\Tests\Fixtures;

final class DummyCollection implements \IteratorAggregate
{
public function getIterator(): \Traversable
{
return [];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ private function extractTypes(TypeNode $node, NameScope $nameScope): array
return [$mainType];
}

$collection = $mainType->isCollection() || \in_array($mainType->getClassName(), [\Traversable::class, \Iterator::class, \IteratorAggregate::class, \ArrayAccess::class, \Generator::class], true);
$collection = $mainType->isCollection() || \is_a($mainType->getClassName(), \Traversable::class, true) || \is_a($mainType->getClassName(), \ArrayAccess::class, true);

// it's safer to fall back to other extractors if the generic type is too abstract
if (!$collection && !class_exists($mainType->getClassName())) {
Expand Down

0 comments on commit f098683

Please sign in to comment.