-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Make constructor argument override the property docblock in PhpDocExtractor #30056
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
Make constructor argument override the property docblock in PhpDocExtractor #30056
Conversation
if (!$reflectionConstructor) { | ||
return null; | ||
} | ||
if (!preg_match('/\@param.+?\$'.$property.'/', $reflectionConstructor->getDocComment(), $matches)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we delegate the extraction of the parameter name to phpdocumentor/reflection-docblock
? It would make the code more solid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Now I parse the phpdoc params using reflection-docblock, then filter docblock.tags so that only the requested property param is kept and then recreate the docblock object. The code became more verbose though.
…s phpdoc instead of regex symfony#30056
Will this also solve the reported case where the constructor has real type hints instead of a docblock? If so, we should also add a test for that case. |
@xabbuh Nope, because PhpDocExtractor has higher priority than ReflectionExtractor. So if the constructor argument is not phpdoc-annotated, it'll return the property type. |
But how will this solve the linked issue then which is about a constructor not having a docblock. If I got you right, the |
The same kind of patch must be added to ReflectionExtractor. |
Yep, adding phpdoc to the constructor would solve the linked issue. @xabbuh How do you imagine this issue should be solved properly? Should we first check constructors for both PhpDocExtractor and ReflectionExtractor, and only after that properties? |
IMO we should only evaluate the property docblock (and in future PHP versions its type) if we were not able to infer the type from the constructor. The constructor is the gatekeeper here and can convey different information than the property if it performs some type conversion (like in the linked issue). |
…ctor and ReflectionExtractor. So that first attempt is to extract type from the constructor and otherwise from the property symfony#30056
@xabbuh Please take a look. I added ConstructorExtractor which has higher priority than PhpDocExtractor and ReflectionExtractor. So that first attempt is to extract the type from the constructor and otherwise from the property |
Travis passes on php5 but gets an error on 7.2 / 7.3:
I tried php 7.2 / 7.3 locally but I'm not able to reproduce this issue. Maybe autoloading / bytecode cache issue, or something else? |
Thanks @xabbuh this fixes tests for php 7.3 but the error is still there for 7.2. |
could you please squash all commits in one? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a lot of new public API for a bug fix, isn't this a new feature really?
How does that play with #25605?
src/Symfony/Component/PropertyInfo/ConstructorArgumentTypeExtractorInterface.php
Outdated
Show resolved
Hide resolved
I wonder if we really need all the new classes (I haven't had time to read the code yet). But shouldn't the existing extractors take into account the constructor by default if the property they analyse is private? |
Does it mean it should be targeted to master?
@nicolas-grekas Unfortunately, I haven't seen this code because I was working in 3.4 branch, but it's different:
@xabbuh Let's review it once again: Originally I modified That's why I added a separate extractor - So the flow of control looks like this:
|
5d94e8d
to
6eade3b
Compare
What type should be returned by
|
I'm not sure this is solvable as is... |
Yes, We knew there was some limitations to this system :/ IMHO, we need typed property to really fix this issue |
@fabpot I agree this is a new feature, yes |
FYI the same PR but targeted to 4.2 #30128 |
Closing this one then. |
…riority than PhpDocExtractor and ReflectionExtractor (karser) This PR was merged into the 5.2-dev branch. Discussion ---------- [PropertyInfo] ConstructorExtractor which has higher priority than PhpDocExtractor and ReflectionExtractor | Q | A | ------------- | --- | Branch? | master | Bug fix? | yes | New feature? | yes | BC breaks? | hopefully no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #30053 | License | MIT Supersedes #30056 #30128 In short, when using PhpDocExtractor, it ignores the constructor argument type, although `argument types from the constructor are the only types that are valid for the class instantiation`. This PR adds a separate extractor - `ConstructorExtractor` which is called first (-999) and it attempts to extract the type from constructor only, either from PhpDoc or using reflection. I added `getTypesFromConstructor` to `PhpDocExtractor` and `ReflectionExtractor` - they implement `ConstructorArgumentTypeExtractorInterface` interface. `ConstructorExtractor` aggregates those extractors using compiler pass. So the flow of control looks like this: ``` PropertyInfoExtractor::getTypes: - ConstructorExtractor::getTypes - PhpDocExtractor::getTypesFromConstructor - ReflectionExtractor::getTypesFromConstructor - PhpDocExtractor::getTypes - ReflectionExtractor::getTypes ``` Commits ------- 5049e25 Added ConstructorExtractor which has higher priority than PhpDocExtractor and ReflectionExtractor
The original ticket is #30053
In short, when using PhpDocExtractor, it ignores the constructor argument type, although
argument types from constructor are the only types that are valid for the class instantiation
.This PR adds the constructor phpdoc support to PhpDocExtractor.