Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork9.7k
[Debug] Support@final on methods#21465
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
| if ($parent) { | ||
| foreach ($refl->getMethods(\ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED)as$method) { | ||
| try { | ||
| $prototype =$method->getPrototype(); |
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.
Why isgetPrototype needed? (I'm not very familiar with it :) )
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.
I discovered it today, it is fetching the parent method, which is what we need, we could do that manually but we would have to support several edge cases (for instance a method of the parent of the parent extended).
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.
@GuilhemN Very cool find. I've needed something similar in the past.
nicolas-grekasJan 31, 2017 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
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.
Nice finding.
Then I'm wondering if we need it at all :)
Parent classes are always loaded before their children. This means each class should only look at methods that have$method->class === $class (let's use properties as much as possible, performance is critical here).
By populating theself::$finalMethods props, then children should have everything to decide quickly.
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.
@nicolas-grekas we would have to support the edge case I described above and maybe others i didn't think about, we would also have to parse every method doc blocks which is bad for perfs, imo it is better this way.
This means each class should only look at methods that have $method->class === $class
It looks like I forgot this check...
nicolas-grekasJan 31, 2017 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
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.
parsing the docblock (doing an strpos preflight really) should be faster than trying getPrototype, then fall in the catch block, which involves instanciating a ReflectionException behind the scene - especially since this situation is going to happen quite often (since many methods don't have a "protototype")
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.
I tried it and the code is clearer too so 👍
| if ($parent &&isset(self::$finalMethods[$parent][$method->name])) { | ||
| // Fetch the real class declaring the parent method | ||
| $prototype =$method->getPrototype(); |
nicolas-grekasJan 31, 2017 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
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.
I guess you don't need this call if you compute the message when populatingself::$finalMethods[$name][$method->name]?
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.
Good point 👍
| } | ||
| $doc =$method->getDocComment(); | ||
| // No @final annotation |
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.
the code says it :)
| self::$finalMethods[$name] =$parent &&isset(self::$finalMethods[$parent]) ?self::$finalMethods[$parent] :array(); | ||
| foreach ($refl->getMethods(\ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED)as$method) { | ||
| // It's not the declaring class |
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.
ueless to me :)
@final on methods| $xError =array( | ||
| 'type' =>E_USER_DEPRECATED, | ||
| 'message' =>'The Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod() method is considered final since version 3.3. It may change without further notice as of its next major version. You should not extend it from Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod.', |
nicolas-grekasJan 31, 2017 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
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.
would it be possible to turn this into an@expectedDeprecation annotation?
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.
Sure, I just followed the rest of the file, I guess it was done to not add thelegacy group.
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.
indeed!
| } | ||
| // Not an interface nor a trait | ||
| if (class_exists($name,false)) { |
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.
this should also apply to@final on the class above, isn't it?
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.
Yes but I think we should wait for this to be merged before doing it, to avoid conflicts.
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.
I don't see why?
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.
In fact it's not a big deal, I can just rebase this PR if we do it in another PR.
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
nicolas-grekas left a comment
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.
👍
fabpot commentedFeb 12, 2017
Thank you@GuilhemN. |
This PR was squashed before being merged into the 3.3-dev branch (closes#21465).Discussion----------[Debug] Support `@final` on methods| Q | A| ------------- | ---| Branch? | master| Bug fix? | no| New feature? | yes| BC breaks? | no| Deprecations? | no| Tests pass? | yes| Fixed tickets |#21461 (comment)| License | MIT| Doc PR |This adds support for `@final` on methods:```phpclass Foo { /** *@Final since version 2.0. */ public function bar() { }}```ping@nicolas-grekasCommits-------1b0a6b6 [Debug] Support on methods
This PR was merged into the 3.3-dev branch.Discussion----------[HttpFoundation] Fix bad merge| Q | A| ------------- | ---| Branch? | master| Bug fix? | no| New feature? | no| BC breaks? | no| Deprecations? | no| Tests pass? | yes| Fixed tickets | -| License | MIT| Doc PR | -Bad merge, code had been removed in#21465Commits-------af1eed9 [HttpFoundation] Fix bad merge
This adds support for
@finalon methods:ping@nicolas-grekas