-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
When available use AnnotationRegistry::registerUniqueLoader #25425
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
Conversation
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.
Once comment is addressed.
@@ -120,7 +120,11 @@ public function startTestSuite($suite) | |||
$this->state = 0; | |||
|
|||
if (!class_exists('Doctrine\Common\Annotations\AnnotationRegistry', false) && class_exists('Doctrine\Common\Annotations\AnnotationRegistry')) { | |||
AnnotationRegistry::registerLoader('class_exists'); | |||
if (method_exists(AnnotationRegistry::class, 'registerUniqueLoader')) { |
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 bridge is still PHP 5.3 compatible so this should be replaced by a regular string instead of:: 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.
But: does this actually do something? The first class_exists check just above already ensures unicity, 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.
Thanks, I made the string change.
The class now has two methods. In doctrine/annotations v1.6+ registerUniqueLoader
exists and should be used, but it requires PHP 7.1+. This should support both depending on the consumers version of this library.
There is another call to registerLoader in an XML file in FrameworkBundle, should be replaced also I believe when possible. |
I split into two PRs since this one could maintain BC and the change in the XML could not (as far as I can tell). |
Changing the registration in the XML file means you should alter the Definition object from the DI extension instead of registering it from the XML, to be able to choose the one being registered |
@@ -269,7 +273,7 @@ public function endTest($test, $time) | |||
putenv('SYMFONY_DEPRECATIONS_SERIALIZE'); | |||
foreach ($deprecations ? unserialize($deprecations) : array() as $deprecation) { | |||
if ($deprecation[0]) { | |||
trigger_error(serialize(array('deprecation' => $deprecation[1], 'class' => $className, 'method' => $test->getName(false))), E_USER_DEPRECATED); | |||
@trigger_error(serialize(array('deprecation' => $deprecation[1], 'class' => $className, 'method' => $test->getName(false))), E_USER_DEPRECATED); |
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 looks wrong to me, as it means the if
and else
blocks are now exactly the same.
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 was suggested by fabbot, but should be reverted indeed, that's a false-positive
XML file needs update (modify the Definition object from the DI extension instead of registering this call from the XML file.)
Thanks @stof and @nicolas-grekas. I reverted the false positive code style fix and moved the invocation on |
<argument type="service"> | ||
<!-- dummy arg to register class_exists as annotation loader only when required --> | ||
<service class="Doctrine\Common\Annotations\AnnotationRegistry"> | ||
<call method="registerLoader"> |
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.
you should keep this definition, and just replace "registerLoader" by "registerUniqueLoader" here.
THEN
in FrameworkExtension.php you need to fetch the "annotations.reader" definition using $container->getDefinition('annotations.reader')
, and tweak it as needed to replace the call by "registerLoader" when the previous method doesn't exist.
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.
Something like:
$container->getDefinition('annotations.reader')
->getMethodCalls()[0][1][1]
->setMethodCalls(array('registerLoader', array('class_exists')));
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.
Ah ok, thanks. I would never have thought of that. I will make that change now.
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.
Sorry @nicolas-grekas this is beyond my skill and understanding. $container->getDefinition('annotations.reader') ->getMethodCalls()[0][1][1]
returns a Symfony\Component\DependencyInjection\Reference
which doesn't have a setMethodCalls
method. That method does exist on the Definition
but I'm not sure how to duplicate the tiered structure in the XML or the call to a service.
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.
Instead of an inlined service, you may move the service on L15 as a named one. That may help you, and future readers.
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.
Looked back at the original code and doing this as a configurator was the suggested approach. Since I couldn't figure out how to do this another way I did it with a configurator. This has the added benefit of calling at static methods statically and not relying oh PHPs poor error control around calling them as instance methods.
I wasn't sure where to put the class though. I didn't want to create a special namespace just for it, so I shoehorned it into CacheWarmer which is probably doesn't belong.
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 reasonable, but actually we made it this way on purpose: to not add yet another class just for this.
I just pushed the change that makes this work as suggested :)
This method will only add 'class_exists' as an autoloader if it has not already been added. This helps alleviate a performance issue when the same loader is added many times in tests.
Thanks for the assist @nicolas-grekas! A rebase seems to have cleared up the test issues so I believe this is ready. |
Thank you @jrjohnson. |
…r (jrjohnson) This PR was merged into the 3.3 branch. Discussion ---------- When available use AnnotationRegistry::registerUniqueLoader | Q | A | ------------- | --- | Branch? | 3.3 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | References tickets | #24596 | License | MIT Take advantage of AnnotationRegistry::registerUniqueLoader which will only add 'class_exists' as an autoloader if it has not already been added. This helps alleviate a performance issue when the same loader is added many times in tests. Commits ------- 97c3f42 Take advantage of AnnotationRegistry::registerUniqueLoader
Take advantage of AnnotationRegistry::registerUniqueLoader which will only add 'class_exists' as an autoloader if it has not already been added. This helps alleviate a performance issue when the
same loader is added many times in tests.