diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 1c94ac0401..cdbf9662cb 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -1400,29 +1400,37 @@ EOF; if ($this->hasReference($id, $argument, $deep, $visited)) { return true; } + + continue; } elseif ($argument instanceof Reference) { $argumentId = (string) $argument; if ($id === $argumentId) { return true; } - if ($deep && !isset($visited[$argumentId]) && 'service_container' !== $argumentId) { - $visited[$argumentId] = true; - - $service = $this->container->getDefinition($argumentId); - - // if the proxy manager is enabled, disable searching for references in lazy services, - // as these services will be instantiated lazily and don't have direct related references. - if ($service->isLazy() && !$this->getProxyDumper() instanceof NullDumper) { - continue; - } - - $arguments = array_merge($service->getMethodCalls(), $service->getArguments(), $service->getProperties()); - - if ($this->hasReference($id, $arguments, $deep, $visited)) { - return true; - } + if (!$deep || isset($visited[$argumentId]) || 'service_container' === $argumentId) { + continue; } + + $visited[$argumentId] = true; + + $service = $this->container->getDefinition($argumentId); + } elseif ($argument instanceof Definition) { + $service = $argument; + } else { + continue; + } + + // if the proxy manager is enabled, disable searching for references in lazy services, + // as these services will be instantiated lazily and don't have direct related references. + if ($service->isLazy() && !$this->getProxyDumper() instanceof NullDumper) { + continue; + } + + $arguments = array_merge($service->getMethodCalls(), $service->getArguments(), $service->getProperties()); + + if ($this->hasReference($id, $arguments, $deep, $visited)) { + return true; } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index 1ebb33d839..32eb4a3488 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -1177,8 +1177,19 @@ class ContainerBuilderTest extends TestCase $this->assertEquals(array('foo1' => new \stdClass(), 'foo3' => new \stdClass()), iterator_to_array($bar->iter)); } - public function testAlmostCircular() + public function testAlmostCircularPrivate() { + $public = false; + $container = include __DIR__.'/Fixtures/containers/container_almost_circular.php'; + + $foo = $container->get('foo'); + + $this->assertSame($foo, $foo->bar->foobar->foo); + } + + public function testAlmostCircularPublic() + { + $public = true; $container = include __DIR__.'/Fixtures/containers/container_almost_circular.php'; $foo = $container->get('foo'); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index c032501109..5d2a6fe67b 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -763,17 +763,35 @@ class PhpDumperTest extends TestCase $this->assertEquals(array('foo1' => new \stdClass(), 'foo3' => new \stdClass()), iterator_to_array($bar->iter)); } - public function xtestAlmostCircular() + public function testAlmostCircularPrivate() { + $public = false; $container = include self::$fixturesPath.'/containers/container_almost_circular.php'; $container->compile(); $dumper = new PhpDumper($container); - $this->assertStringEqualsFile(self::$fixturesPath.'/php/container_almost_circular.php', $dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_Almost_Circular'))); + $this->assertStringEqualsFile(self::$fixturesPath.'/php/container_almost_circular_private.php', $dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_Almost_Circular_Private'))); - require self::$fixturesPath.'/php/container_almost_circular.php'; + require self::$fixturesPath.'/php/container_almost_circular_private.php'; - $container = new \Symfony_DI_PhpDumper_Test_Almost_Circular(); + $container = new \Symfony_DI_PhpDumper_Test_Almost_Circular_Private(); + $foo = $container->get('foo'); + + $this->assertSame($foo, $foo->bar->foobar->foo); + } + + public function testAlmostCircularPublic() + { + $public = true; + $container = include self::$fixturesPath.'/containers/container_almost_circular.php'; + $container->compile(); + $dumper = new PhpDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/container_almost_circular_public.php', $dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_Almost_Circular_Public'))); + + require self::$fixturesPath.'/php/container_almost_circular_public.php'; + + $container = new \Symfony_DI_PhpDumper_Test_Almost_Circular_Public(); $foo = $container->get('foo'); $this->assertSame($foo, $foo->bar->foobar->foo); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_almost_circular.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_almost_circular.php index f4219187a5..eaef674a3e 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_almost_circular.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container_almost_circular.php @@ -10,10 +10,10 @@ $container = new ContainerBuilder(); $container->register('foo', FooCircular::class)->setPublic(true) ->addArgument(new Reference('bar')); -$container->register('bar', BarCircular::class) +$container->register('bar', BarCircular::class)->setPublic($public) ->addMethodCall('addFoobar', array(new Reference('foobar'))); -$container->register('foobar', FoobarCircular::class) +$container->register('foobar', FoobarCircular::class)->setPublic($public) ->addArgument(new Reference('foo')); return $container; diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/container_almost_circular.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/container_almost_circular_private.php similarity index 88% rename from src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/container_almost_circular.php rename to src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/container_almost_circular_private.php index ccd31997bb..3a3f753c1f 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/container_almost_circular.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/container_almost_circular_private.php @@ -14,7 +14,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; * * @final since Symfony 3.3 */ -class Symfony_DI_PhpDumper_Test_Almost_Circular extends Container +class Symfony_DI_PhpDumper_Test_Almost_Circular_Private extends Container { private $parameters; private $targetDirs = array(); @@ -64,8 +64,12 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular extends Container protected function getFooService() { $a = new \BarCircular(); - $a->addFoobar(new \FoobarCircular(($this->services['foo'] ?? $this->getFooService()))); - return $this->services['foo'] = new \FooCircular($a); + $this->services['foo'] = $instance = new \FooCircular($a); + + $a->addFoobar(new \FoobarCircular($instance)); + + + return $instance; } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/container_almost_circular_public.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/container_almost_circular_public.php new file mode 100644 index 0000000000..a306443e88 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/container_almost_circular_public.php @@ -0,0 +1,104 @@ +services = $this->privates = array(); + $this->methodMap = array( + 'bar' => 'getBarService', + 'foo' => 'getFooService', + 'foobar' => 'getFoobarService', + ); + + $this->aliases = array(); + } + + public function reset() + { + $this->privates = array(); + parent::reset(); + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function getRemovedIds() + { + return array( + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ); + } + + /** + * Gets the public 'bar' shared service. + * + * @return \BarCircular + */ + protected function getBarService() + { + $this->services['bar'] = $instance = new \BarCircular(); + + $instance->addFoobar(($this->services['foobar'] ?? $this->getFoobarService())); + + return $instance; + } + + /** + * Gets the public 'foo' shared service. + * + * @return \FooCircular + */ + protected function getFooService() + { + $a = ($this->services['bar'] ?? $this->getBarService()); + + if (isset($this->services['foo'])) { + return $this->services['foo']; + } + + return $this->services['foo'] = new \FooCircular($a); + } + + /** + * Gets the public 'foobar' shared service. + * + * @return \FoobarCircular + */ + protected function getFoobarService() + { + $a = ($this->services['foo'] ?? $this->getFooService()); + + if (isset($this->services['foobar'])) { + return $this->services['foobar']; + } + + return $this->services['foobar'] = new \FoobarCircular($a); + } +} diff --git a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php index 3133318494..212c3dc41f 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php @@ -41,20 +41,8 @@ class PhpDocExtractor implements PropertyDescriptionExtractorInterface, Property private $docBlockFactory; private $contextFactory; private $phpDocTypeHelper; - - /** - * @var string[] - */ private $mutatorPrefixes; - - /** - * @var string[] - */ private $accessorPrefixes; - - /** - * @var string[] - */ private $arrayMutatorPrefixes; /**