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

Appearance settings

Commit 1a3d445

Browse filesBrowse files
committed
feature #26300 [PropertyInfo] Implement "Collection" types in PhpDocExtractor (popy-dev)
This PR was squashed before being merged into the 4.2-dev branch (closes #26300). Discussion ---------- [PropertyInfo] Implement "Collection" types in PhpDocExtractor | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #26299 | License | MIT | Doc PR | todo Here's a proposition of implementation of my feature request #26299 : I added few tests covering the requested feature, and I had to change a few things in the ```Symfony\Component\PropertyInfo\Util\PhpDocTypeHelper``` class (createType no longer gets a string, but a ```phpDocumentor\Reflection\Type``` instance) to be able to detect properly Collections and their subtypes. Of course a simpler implementation is possible, without changing the PhpDocTypeHelper internal behaviour, by matching the input string against ```/^([^>]+)</``` and extracting the classname alone. Commits ------- 12bafe4 [PropertyInfo] Implement \"Collection\" types in PhpDocExtractor
2 parents 2b9c142 + 12bafe4 commit 1a3d445
Copy full SHA for 1a3d445

File tree

4 files changed

+84
-10
lines changed
Filter options

4 files changed

+84
-10
lines changed

‎src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php
+34Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
1616
use Symfony\Component\PropertyInfo\Type;
17+
use phpDocumentor\Reflection\Types\Collection;
1718

1819
/**
1920
* @author Kévin Dunglas <dunglas@gmail.com>
@@ -77,6 +78,39 @@ public function typesProvider()
7778
);
7879
}
7980

81+
/**
82+
* @dataProvider provideCollectionTypes
83+
*/
84+
public function testExtractCollection($property, array $type = null, $shortDescription, $longDescription)
85+
{
86+
if (!class_exists(Collection::class)) {
87+
$this->markTestSkipped('Collections are not implemented in current phpdocumentor/type-resolver version');
88+
}
89+
90+
$this->testExtract($property, $type, $shortDescription, $longDescription);
91+
}
92+
93+
public function provideCollectionTypes()
94+
{
95+
return array(
96+
array('iteratorCollection', array(new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Iterator', true, null, new Type(Type::BUILTIN_TYPE_STRING))), null, null),
97+
array('iteratorCollectionWithKey', array(new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Iterator', true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_STRING))), null, null),
98+
array(
99+
'nestedIterators',
100+
array(new Type(
101+
Type::BUILTIN_TYPE_OBJECT,
102+
false,
103+
'Iterator',
104+
true,
105+
new Type(Type::BUILTIN_TYPE_INT),
106+
new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Iterator', true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_STRING))
107+
)),
108+
null,
109+
null,
110+
),
111+
);
112+
}
113+
80114
public function testParamTagTypeIsOmitted()
81115
{
82116
$this->assertNull($this->extractor->getTypes(OmittedParamTagTypeDocBlock::class, 'omittedType'));

‎src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ public function testGetProperties()
4242
'Guid',
4343
'array',
4444
'emptyVar',
45+
'iteratorCollection',
46+
'iteratorCollectionWithKey',
47+
'nestedIterators',
4548
'foo',
4649
'foo2',
4750
'foo3',
@@ -79,6 +82,9 @@ public function testGetPropertiesWithCustomPrefixes()
7982
'Guid',
8083
'array',
8184
'emptyVar',
85+
'iteratorCollection',
86+
'iteratorCollectionWithKey',
87+
'nestedIterators',
8288
'foo',
8389
'foo2',
8490
'foo3',
@@ -107,6 +113,9 @@ public function testGetPropertiesWithNoPrefixes()
107113
'Guid',
108114
'array',
109115
'emptyVar',
116+
'iteratorCollection',
117+
'iteratorCollectionWithKey',
118+
'nestedIterators',
110119
'foo',
111120
'foo2',
112121
'foo3',

‎src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php
+15Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,21 @@ class Dummy extends ParentDummy
7575
*/
7676
public $emptyVar;
7777

78+
/**
79+
* @var \Iterator<string>
80+
*/
81+
public $iteratorCollection;
82+
83+
/**
84+
* @var \Iterator<integer,string>
85+
*/
86+
public $iteratorCollectionWithKey;
87+
88+
/**
89+
* @var \Iterator<integer,\Iterator<integer,string>>
90+
*/
91+
public $nestedIterators;
92+
7893
public static function getStatic()
7994
{
8095
}

‎src/Symfony/Component/PropertyInfo/Util/PhpDocTypeHelper.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/PropertyInfo/Util/PhpDocTypeHelper.php
+26-10Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\PropertyInfo\Util;
1313

1414
use phpDocumentor\Reflection\Type as DocType;
15+
use phpDocumentor\Reflection\Types\Collection;
1516
use phpDocumentor\Reflection\Types\Compound;
1617
use phpDocumentor\Reflection\Types\Null_;
1718
use Symfony\Component\PropertyInfo\Type;
@@ -39,7 +40,7 @@ public function getTypes(DocType $varType): array
3940
$nullable = true;
4041
}
4142

42-
$type = $this->createType((string) $varType, $nullable);
43+
$type = $this->createType($varType, $nullable);
4344
if (null !== $type) {
4445
$types[] = $type;
4546
}
@@ -49,16 +50,15 @@ public function getTypes(DocType $varType): array
4950

5051
$varTypes = array();
5152
for ($typeIndex = 0; $varType->has($typeIndex); ++$typeIndex) {
52-
$varTypes[] = (string) $varType->get($typeIndex);
53-
}
53+
$type = $varType->get($typeIndex);
5454

55-
// If null is present, all types are nullable
56-
$nullKey = array_search(Type::BUILTIN_TYPE_NULL, $varTypes);
57-
$nullable = false !== $nullKey;
55+
// If null is present, all types are nullable
56+
if ($type instanceof Null_) {
57+
$nullable = true;
58+
continue;
59+
}
5860

59-
// Remove the null type from the type if other types are defined
60-
if ($nullable && count($varTypes) > 1) {
61-
unset($varTypes[$nullKey]);
61+
$varTypes[] = $type;
6262
}
6363

6464
foreach ($varTypes as $varType) {
@@ -74,8 +74,24 @@ public function getTypes(DocType $varType): array
7474
/**
7575
* Creates a {@see Type} from a PHPDoc type.
7676
*/
77-
private function createType(string $docType, bool $nullable): ?Type
77+
private function createType(DocType $type, bool $nullable): ?Type
7878
{
79+
$docType = (string) $type;
80+
81+
if ($type instanceof Collection) {
82+
list($phpType, $class) = $this->getPhpTypeAndClass((string) $type->getFqsen());
83+
84+
$key = $this->getTypes($type->getKeyType());
85+
$value = $this->getTypes($type->getValueType());
86+
87+
// More than 1 type returned means it is a Compound type, which is
88+
// not handled by Type, so better use a null value.
89+
$key = 1 === \count($key) ? $key[0] : null;
90+
$value = 1 === \count($value) ? $value[0] : null;
91+
92+
return new Type($phpType, $nullable, $class, true, $key, $value);
93+
}
94+
7995
// Cannot guess
8096
if (!$docType || 'mixed' === $docType) {
8197
return null;

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.