Skip to content

Commit

Permalink
feature #54661 [TypeInfo] Handle custom collection objects properly (…
Browse files Browse the repository at this point in the history
…mtarld)

This PR was merged into the 7.1 branch.

Discussion
----------

[TypeInfo] Handle custom collection objects properly

| Q             | A
| ------------- | ---
| Branch?       | 7.1
| Bug fix?      | no
| New feature?  | no <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Issues        |
| License       | MIT

Understand custom collection objects.

Commits
-------

b2a7627 [TypeInfo] Handle collection types properly
  • Loading branch information
chalasr committed Apr 30, 2024
2 parents 3d81565 + b2a7627 commit 95e8168
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 4 deletions.
11 changes: 11 additions & 0 deletions src/Symfony/Component/TypeInfo/Tests/Fixtures/DummyCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Symfony\Component\TypeInfo\Tests\Fixtures;

final class DummyCollection implements \IteratorAggregate
{
public function getIterator(): \Traversable
{
return [];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Symfony\Component\TypeInfo\Exception\UnsupportedException;
use Symfony\Component\TypeInfo\Tests\Fixtures\AbstractDummy;
use Symfony\Component\TypeInfo\Tests\Fixtures\Dummy;
use Symfony\Component\TypeInfo\Tests\Fixtures\DummyCollection;
use Symfony\Component\TypeInfo\Tests\Fixtures\DummyWithTemplates;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\TypeContext\TypeContext;
Expand Down Expand Up @@ -167,6 +168,7 @@ public function resolveDataProvider(): iterable
yield [Type::collection(Type::object(\IteratorAggregate::class)), \IteratorAggregate::class];
yield [Type::collection(Type::object(\IteratorAggregate::class), Type::string()), \IteratorAggregate::class.'<string>'];
yield [Type::collection(Type::object(\IteratorAggregate::class), Type::bool(), Type::string()), \IteratorAggregate::class.'<string, bool>'];
yield [Type::collection(Type::object(DummyCollection::class), Type::bool(), Type::string()), DummyCollection::class.'<string, bool>'];
}

public function testCannotResolveNonStringType()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@
*/
final class StringTypeResolver implements TypeResolverInterface
{
private const COLLECTION_CLASS_NAMES = [\Traversable::class, \Iterator::class, \IteratorAggregate::class, \ArrayAccess::class, \Generator::class];

/**
* @var array<string, bool>
*/
Expand Down Expand Up @@ -166,7 +164,7 @@ private function getTypeFromNode(TypeNode $node, ?TypeContext $typeContext): Typ
default => $this->resolveCustomIdentifier($node->name, $typeContext),
};

if ($type instanceof ObjectType && \in_array($type->getClassName(), self::COLLECTION_CLASS_NAMES, true)) {
if ($type instanceof ObjectType && (is_a($type->getClassName(), \Traversable::class, true) || is_a($type->getClassName(), \ArrayAccess::class, true))) {
return Type::collection($type);
}

Expand Down Expand Up @@ -203,7 +201,7 @@ private function getTypeFromNode(TypeNode $node, ?TypeContext $typeContext): Typ
}
}

if ($type instanceof ObjectType && \in_array($type->getClassName(), self::COLLECTION_CLASS_NAMES, true)) {
if ($type instanceof ObjectType && (is_a($type->getClassName(), \Traversable::class, true) || is_a($type->getClassName(), \ArrayAccess::class, true))) {
return match (\count($variableTypes)) {
1 => Type::collection($type, $variableTypes[0]),
2 => Type::collection($type, $variableTypes[1], $variableTypes[0]),
Expand Down

0 comments on commit 95e8168

Please sign in to comment.