bug #28678 [DI] fix dumping setters before their inlined instances (nicolas-grekas)

This PR was merged into the 3.4 branch.

Discussion
----------

[DI] fix dumping setters before their inlined instances

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #28654
| License       | MIT
| Doc PR        | -

Commits
-------

d60eb1aa33 [DI] fix dumping setters before their inlined instances
This commit is contained in:
Nicolas Grekas 2018-10-02 13:48:40 +02:00
commit 8e1f3813e8
5 changed files with 170 additions and 1 deletions

View File

@ -780,8 +780,9 @@ EOTXT
$code = '';
$arguments = array($definition->getProperties(), $definition->getMethodCalls(), $definition->getConfigurator());
$hasSelfRef = $this->addInlineVariables($code, $tail, $id, $arguments, false) || $hasSelfRef;
$hasSelfRef = $this->addInlineVariables($code, $code, $id, $arguments, false) || $hasSelfRef;
$code .= '' !== $code ? "\n" : '';
$code .= $this->addServiceProperties($definition, $name);
$code .= $this->addServiceMethodCalls($definition, $name);
$code .= $this->addServiceConfigurator($definition, $name);

View File

@ -85,6 +85,7 @@ class Symfony_DI_PhpDumper_Test_Deep_Graph extends Container
$b = new \stdClass();
$c = new \stdClass();
$c->p3 = new \stdClass();
$b->p2 = $c;
return $this->services['foo'] = new \Symfony\Component\DependencyInjection\Tests\Dumper\FooForDeepGraph($a, $b);

View File

@ -0,0 +1,89 @@
<?php
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
/**
* This class has been auto-generated
* by the Symfony Dependency Injection Component.
*
* @final since Symfony 3.3
*/
class ProjectServiceContainer extends Container
{
private $parameters;
private $targetDirs = array();
public function __construct()
{
$this->services = array();
$this->normalizedIds = array(
'tsantos\\serializer\\serializerinterface' => 'TSantos\\Serializer\\SerializerInterface',
);
$this->methodMap = array(
'tsantos_serializer' => 'getTsantosSerializerService',
);
$this->aliases = array(
'TSantos\\Serializer\\SerializerInterface' => 'tsantos_serializer',
);
}
public function getRemovedIds()
{
return array(
'Psr\\Container\\ContainerInterface' => true,
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
);
}
public function compile()
{
throw new LogicException('You cannot compile a dumped container that was already compiled.');
}
public function isCompiled()
{
return true;
}
public function isFrozen()
{
@trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED);
return true;
}
/**
* Gets the public 'tsantos_serializer' shared service.
*
* @return \TSantos\Serializer\EventEmitterSerializer
*/
protected function getTsantosSerializerService()
{
$a = new \TSantos\Serializer\NormalizerRegistry();
$d = new \TSantos\Serializer\EventDispatcher\EventDispatcher();
$d->addSubscriber(new \TSantos\SerializerBundle\EventListener\StopwatchListener(new \Symfony\Component\Stopwatch\Stopwatch(true)));
$this->services['tsantos_serializer'] = $instance = new \TSantos\Serializer\EventEmitterSerializer(new \TSantos\Serializer\Encoder\JsonEncoder(), $a, $d);
$b = new \TSantos\Serializer\Normalizer\CollectionNormalizer();
$b->setSerializer($instance);
$c = new \TSantos\Serializer\Normalizer\JsonNormalizer();
$c->setSerializer($instance);
$a->add(new \TSantos\Serializer\Normalizer\ObjectNormalizer(new \TSantos\SerializerBundle\Serializer\CircularReferenceHandler()));
$a->add($b);
$a->add($c);
return $instance;
}
}

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="service_container" class="Symfony\Component\DependencyInjection\ContainerInterface" public="true" synthetic="true"/>
<service id="tsantos_serializer" class="TSantos\Serializer\EventEmitterSerializer" public="true">
<argument type="service">
<service class="TSantos\Serializer\Encoder\JsonEncoder" public="false">
<tag name="tsantos_serializer.encoder" format="json"/>
</service>
</argument>
<argument type="service">
<service class="TSantos\Serializer\NormalizerRegistry" public="false">
<call method="add">
<argument type="service">
<service class="TSantos\Serializer\Normalizer\ObjectNormalizer" public="false">
<tag name="tsantos_serializer.normalizer" priority="-800"/>
<argument type="service">
<service class="TSantos\SerializerBundle\Serializer\CircularReferenceHandler" public="false"/>
</argument>
</service>
</argument>
</call>
<call method="add">
<argument type="service">
<service class="TSantos\Serializer\Normalizer\CollectionNormalizer" public="false">
<tag name="tsantos_serializer.normalizer" priority="-900"/>
<call method="setSerializer">
<argument type="service" id="tsantos_serializer"/>
</call>
</service>
</argument>
</call>
<call method="add">
<argument type="service">
<service class="TSantos\Serializer\Normalizer\JsonNormalizer" public="false">
<tag name="tsantos_serializer.normalizer" priority="-1000"/>
<call method="setSerializer">
<argument type="service" id="tsantos_serializer"/>
</call>
</service>
</argument>
</call>
</service>
</argument>
<argument type="service">
<service class="TSantos\Serializer\EventDispatcher\EventDispatcher" public="false">
<call method="addSubscriber">
<argument type="service">
<service class="TSantos\SerializerBundle\EventListener\StopwatchListener" public="false">
<tag name="tsantos_serializer.event_subscriber"/>
<argument type="service">
<service class="Symfony\Component\Stopwatch\Stopwatch" public="false">
<tag name="kernel.reset" method="reset"/>
<argument>true</argument>
</service>
</argument>
</service>
</argument>
</call>
</service>
</argument>
</service>
<service id="TSantos\Serializer\SerializerInterface" alias="tsantos_serializer" public="true"/>
</services>
</container>

View File

@ -18,6 +18,7 @@ use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Config\Resource\GlobResource;
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
use Symfony\Component\DependencyInjection\Loader\IniFileLoader;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
@ -807,4 +808,16 @@ class XmlFileLoaderTest extends TestCase
'$factory' => 'factory',
), array_map(function ($v) { return $v->getValues()[0]; }, $definition->getBindings()));
}
public function testTsantosContainer()
{
$container = new ContainerBuilder();
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
$loader->load('services_tsantos.xml');
$container->compile();
$dumper = new PhpDumper($container);
$dump = $dumper->dump();
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services_tsantos.php', $dumper->dump());
}
}