Skip to content

[PropertyInfo] Implement "Collection" types in PhpDocExtractor #26300

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 26, 2018
Merged

[PropertyInfo] Implement "Collection" types in PhpDocExtractor #26300

merged 1 commit into from
Jun 26, 2018

Conversation

popy-dev
Copy link
Contributor

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.

@@ -49,16 +50,15 @@ public function getTypes(DocType $varType): array

$varTypes = array();
for ($typeIndex = 0; $varType->has($typeIndex); ++$typeIndex) {
$varTypes[] = (string) $varType->get($typeIndex);
}
$t = $varType->get($typeIndex);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WDYT of using $type instead, it will be better for the readability ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got the habbit of using one-char variable names for variables having such a small scope in the function. But you're right, $type would be better.

// More than 1 type returned means it is a Compound type, which is
// not handled by Type, so better use a null value.
$key = 1 === count($key) ? $key[0] : null;
$value = 1 === count($value) ? $value[0] : null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

\count


// More than 1 type returned means it is a Compound type, which is
// not handled by Type, so better use a null value.
$key = 1 === count($key) ? $key[0] : null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

\count

@@ -39,7 +40,7 @@ public function getTypes(DocType $varType): array
$nullable = true;
}

$type = $this->createType((string) $varType, $nullable);
$type = $this->createType($varType, $nullable);
if (null !== $type) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can inline this IMO

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah since you are not modifying it, forgot about this ;). It will be harder to merge things back to master.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I tried to modify as few lines as possible, to keep diffs shorts.

@Simperfit
Copy link
Contributor

It seems that the broken tests are linked to this change, could you please check why ?

@popy-dev
Copy link
Contributor Author

My bad : the added properties in the Fixture made ReflectionExtractor->getProperties test fail (obviously), and i didn't notice as I didn't run tests on the whole component. Lesson learned.

Strange enougth, the travis check on php 7.1 didn't fail.

@popy-dev
Copy link
Contributor Author

Damn. I don't reproduce the issue on php 7.2
What I understand from the output is that somehow, one of these 2 lines retruns an array instead of a null

    $key = 1 === \count($key) ? $key[0] : null;
    $value = 1 === \count($value) ? $value[0] : null;

@Simperfit
Copy link
Contributor

Simperfit commented Feb 25, 2018 via email

@popy-dev
Copy link
Contributor Author

Indeed : the 7.2 is checked with "deps=low". I tested after loading lowest dependencies, and I reproduced.

@popy-dev
Copy link
Contributor Author

There's a "fix" : I updated the "conflicts" section, forcing phpdocumentor/type-resolver to, at least, version 0.5.0 where the Collection have been included.

The issue is now that it bumps phpdocumentor/reflection-docblock version to dev-master, as each version of it depends on a fixed version (^0.4.0 for instance) of phpdocumentor/type-resolver.

@nicolas-grekas nicolas-grekas added this to the 4.1 milestone Feb 25, 2018
composer.json Outdated
@@ -100,7 +100,7 @@
},
"conflict": {
"phpdocumentor/reflection-docblock": "<3.0||>=3.2.0,<3.2.2",
"phpdocumentor/type-resolver": "<0.2.1",
"phpdocumentor/type-resolver": "<0.5.0",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to bump: instead, just skip the tests that cannot run when applicable

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests are just new entries in an existing dataprovider. What would be the better way to skip them ? If thought of not adding them, but they won't show as skipped.

Copy link
Member

@nicolas-grekas nicolas-grekas Feb 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest to just create a new test case with separate provide method, + skipping logic inside

Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with minor comments
ping @dunglas for review, if you can

*/
public function testExtractCollection($property, array $type = null, $shortDescription, $longDescription)
{
if (!class_exists('phpDocumentor\\Reflection\\Types\\Collection')) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should use Collection::class instead

$this->testExtract($property, $type, $shortDescription, $longDescription);
}

public function collectionsTypesProvider()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

provideCollectionTypes

@@ -14,6 +14,7 @@
use phpDocumentor\Reflection\Type as DocType;
use phpDocumentor\Reflection\Types\Compound;
use phpDocumentor\Reflection\Types\Null_;
use phpDocumentor\Reflection\Types\Collection;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alpha order

$key = $this->getTypes($type->getKeyType());
$value = $this->getTypes($type->getValueType());

// More than 1 type returned means it is a Compound type, which is
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think we can improve the type VO (it's a final class exactly for this reason) to support this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it could be done without much shenanigans (adding a counpound internal type, and a property holding composing types).

But i'm afraid that would be a breaking change, as the component will start to return non-null types where it previously did.

@nicolas-grekas
Copy link
Member

@popy-dev would you mind taking care of the remaining comments please? I also invite you to squash your commit if possible. If you can't, please advise, we'll take over. Thanks.

@fabpot fabpot modified the milestones: 4.1, next Apr 22, 2018
@popy-dev
Copy link
Contributor Author

Sorry, I'll fix that ASAP.

@popy-dev
Copy link
Contributor Author

github warned about conflicts, so I rebased on upstream/master. That also fixed the Travis check (which was probably unrelated to the code)

@fabpot
Copy link
Member

fabpot commented Jun 26, 2018

Thank you @popy-dev.

@fabpot fabpot merged commit 12bafe4 into symfony:master Jun 26, 2018
fabpot added a commit that referenced this pull request Jun 26, 2018
…xtractor (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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants