Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork9.7k
[DX][DI] Add compiler pass which check extistence of service class name#11315
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
[DX][DI] Add compiler pass which check extistence of service class name#11315
Uh oh!
There was an error while loading.Please reload this page.
Conversation
l3l0 commentedJul 5, 2014
| Q | A |
|---|---|
| Bug fix? | no |
| New feature? | yes |
| BC breaks? | not sure - I hope that no |
| Deprecations? | no |
| Tests pass? | yes |
| Fixed tickets | #11301 |
| License | MIT |
weaverryan commentedJul 5, 2014
Nice work! So, now the question is, does this break BC? Is there a situation where class will not exist during the compiler process but exist later at run-time? |
pyrech commentedJul 6, 2014
Just my 2 cents about naming :) I would use 'class' rather than 'name' to be consistent with the "class" configuration of the service : Anyway, good job! |
l3l0 commentedJul 6, 2014
@pyrech good catch :) I changed names. |
Nek- commentedJul 6, 2014
IMO it's not a BC break, but in reality it is for those who like hacking Sf, maybe somebody that read a lot of issue about DI will be able to confirm. 👍 Anyway, nice work :) . |
Koc commentedJul 6, 2014
How this change affects performance? Looks like it will loads all of the classes. If yes - imho better add console commands for checking. |
l3l0 commentedJul 7, 2014
@Koc all classes should be loaded when container is compiled (not on every request), so probably can affect stuff in dev/debug mode IHMO. For prod configuration it should be fine. But I have not done any performance checks, so I cannot answer the question how this can affect performance. |
Koc commentedJul 7, 2014
I forgot about this, sorry. It occurs only when tracked resources was changed. |
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 changing these tests ?
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.
Cause when we run all symfony test suites at once foo class exist (cause of this probablyhttps://github.com/l3l0/symfony/blob/feature/better-error-on-bad-service-class-name-issue-11301/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/ProjectExtension.php#L16)
stof commentedJul 8, 2014
I think this should run after the removing passes. It does not make sense to throw an exception for a service which gets removed |
l3l0 commentedJul 18, 2014
@stof I added checking class for factory_class. I moved compiler pass to part running after the removing passes - this somehow force me to resolve class name again using ParameterBag. |
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.
Please don't remove the trailing comma in multiline arrays. Our coding standards require them
l3l0 commentedJul 19, 2014
factory_class name (using class_exists() ) if that is possible - definition is not syntetic or isnot definition via factory method.
inso commentedJul 20, 2014
What about adding check for existence of factory method? |
linaori commentedJul 31, 2014
What if I use a factory method and my class is not a class but an interface? This is perfectly legit right now and can cause a BC break if not allowed any more. See#11279 services:session.flash_bag:class: Symfony\Component\HttpFoundation\Session\FlashBagInterfacefactory_service: sessionfactory_method: getFlashBag |
weaverryan commentedAug 4, 2014
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 be on one line.
jakzal commentedSep 11, 2014
I like to give interfaces in my factory service definitions, so I'd vote for adding The reason for configuring an interface instead of a class is proper autocompletion (coding against an interface yada yada yada). |
weaverryan commentedSep 22, 2014
The only pending issues that has been added on this PR are
@l3l0 Can you make those changes? We're in the last week before 2.6 feature freeze and I would love to see if we can get this considered for a merge :). |
fabpot commentedSep 24, 2014
We must also add support for the new way to register factories. See#12008 |
fabpot commentedSep 26, 2014
@l3l0 If you don't have time in the next coming days, I can also finish the PR for you, just let me know. |
fabpot commentedSep 26, 2014
The problem I can see is memory consumption as when compiling the container, it will load all classes referenced in the container. So, we should check that first as I fear it's going to slow down the very first request a lot. |
stof commentedSep 26, 2014
@fabpot this will likely have an impact in dev indeed. It needs to be measured. |
weaverryan commentedOct 1, 2014
Ah, good point about performance! I would love to have this better error message, but certainly not if it significantly increases memory or the loading of the container in the dev environment. |
l3l0 commentedOct 1, 2014
@fabpot Sure I haven't time recently and probably will be better if you take care about it :) |
fabpot commentedJan 2, 2015
I've just tested the impact on the memory and I think the increase is not acceptable. On a barebone Symfony Standard Edition project, it takes 20MB of memory to run So, except if we only run this when debug is enabled, I'm 👎 on this change. FWIW, the patch does not work as is as it does not take into account interfaces: diff --git a/src/Symfony/Component/DependencyInjection/Compiler/CheckServiceClassPass.php b/src/Symfony/Component/DependencyInjection/Compiler/CheckServiceClassPass.phpindex 1f0897e..71427b0 100644--- a/src/Symfony/Component/DependencyInjection/Compiler/CheckServiceClassPass.php+++ b/src/Symfony/Component/DependencyInjection/Compiler/CheckServiceClassPass.php@@ -31,11 +31,17 @@ class CheckServiceClassPass implements CompilerPassInterface { $parameterBag = $container->getParameterBag(); foreach ($container->getDefinitions() as $id => $definition) {- if ($this->allowsToCheckClassExistenceForClass($definition) && !class_exists($parameterBag->resolveValue($definition->getClass()))) {- throw new BadServiceClassException($id, $definition->getClass(), 'class');+ if ($this->allowsToCheckClassExistenceForClass($definition)) {+ $class = $parameterBag->resolveValue($definition->getClass());+ if (!class_exists($class) && !interface_exists($class) && !trait_exists($class)) {+ throw new BadServiceClassException($id, $definition->getClass(), 'class');+ } }- if ($this->allowsToCheckClassExistenceForFactoryClass($definition) && !class_exists($parameterBag->resolveValue($definition->getFactoryClass()))) {- throw new BadServiceClassException($id, $definition->getFactoryClass(), 'factory_class');+ if ($this->allowsToCheckClassExistenceForFactoryClass($definition)) {+ $class = $parameterBag->resolveValue($definition->getFactoryClass());+ if (!class_exists($class) && !interface_exists($class) && !trait_exists($class)) {+ throw new BadServiceClassException($id, $definition->getFactoryClass(), 'factory_class');+ } } } } |
stof commentedJan 2, 2015
I suggest closing this in favor ofhttps://github.com/matthiasnoback/symfony-service-definition-validator/ which covers this kind of validation already, as well as a bunch of other rules (it checks that the mandatory arguments are passed for instance). |