bug #27830 [Dependency-Injection] Fix issue where non-defined services were attempted to be removed (ciaranmcnulty)

This PR was squashed before being merged into the 4.2-dev branch (closes #27830).

Discussion
----------

[Dependency-Injection] Fix issue where non-defined services were attempted to be removed

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no     <!-- see https://symfony.com/bc -->
| Deprecations? | no <!-- don't forget to update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tests pass?   | yes    <!-- please add some, will be required by reviewers -->
| Fixed tickets | #27802   <!-- #-prefixed issue number(s), if any -->
| License       | MIT
| Doc PR        | symfony/symfony-docs#... <!-- required for new features -->

The RemoveUnusedServicesPass generates a graph of services that are connected, then removes services that are not part of the graph. To build this graph it creates a list of services then examines their definitions for more services.

The current scenario was causing an error, thrown by getDefinition (triggered in Behat):
 * Service was referenced by another service definition
 * Service was _not_ defined
 * Service was subsequently set() on the container

Commits
-------

53155c9800 [Dependency-Injection] Fix issue where non-defined services were attempted to be removed
This commit is contained in:
Nicolas Grekas 2018-07-03 20:20:23 +02:00
commit 26989d4e73
2 changed files with 16 additions and 1 deletions

View File

@ -60,7 +60,7 @@ class RemoveUnusedDefinitionsPass extends AbstractRecursivePass implements Repea
$ids = $this->connectedIds;
$this->connectedIds = array();
foreach ($ids as $id) {
if (!isset($connectedIds[$id]) && $container->has($id)) {
if (!isset($connectedIds[$id]) && $container->hasDefinition($id)) {
$connectedIds[$id] = true;
$this->processValue($container->getDefinition($id));
}

View File

@ -127,6 +127,21 @@ class RemoveUnusedDefinitionsPassTest extends TestCase
$this->assertSame(1, $envCounters['FOOBAR']);
}
public function testProcessDoesNotErrorOnServicesThatDoNotHaveDefinitions()
{
$container = new ContainerBuilder();
$container
->register('defined')
->addArgument(new Reference('not.defined'))
->setPublic(true);
$container->set('not.defined', new \StdClass());
$this->process($container);
$this->assertFalse($container->hasDefinition('not.defined'));
}
protected function process(ContainerBuilder $container)
{
(new RemoveUnusedDefinitionsPass())->process($container);