diff --git a/Compiler/AnalyzeServiceReferencesPass.php b/Compiler/AnalyzeServiceReferencesPass.php index 38a172074..d537b693c 100644 --- a/Compiler/AnalyzeServiceReferencesPass.php +++ b/Compiler/AnalyzeServiceReferencesPass.php @@ -37,6 +37,7 @@ class AnalyzeServiceReferencesPass extends AbstractRecursivePass implements Repe private $hasProxyDumper; private $lazy; private $expressionLanguage; + private $byConstructor; /** * @param bool $onlyConstructorArguments Sets this Service Reference pass to ignore method calls @@ -64,6 +65,7 @@ public function process(ContainerBuilder $container) $this->graph = $container->getCompiler()->getServiceReferenceGraph(); $this->graph->clear(); $this->lazy = false; + $this->byConstructor = false; foreach ($container->getAliases() as $id => $alias) { $targetId = $this->getDefinitionId((string) $alias); @@ -100,7 +102,8 @@ protected function processValue($value, $isRoot = false) $targetDefinition, $value, $this->lazy || ($this->hasProxyDumper && $targetDefinition && $targetDefinition->isLazy()), - ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $value->getInvalidBehavior() + ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $value->getInvalidBehavior(), + $this->byConstructor ); return $value; @@ -118,8 +121,11 @@ protected function processValue($value, $isRoot = false) } $this->lazy = false; + $byConstructor = $this->byConstructor; + $this->byConstructor = true; $this->processValue($value->getFactory()); $this->processValue($value->getArguments()); + $this->byConstructor = $byConstructor; if (!$this->onlyConstructorArguments) { $this->processValue($value->getProperties()); diff --git a/Compiler/AutowirePass.php b/Compiler/AutowirePass.php index e858d14fa..e832685ab 100644 --- a/Compiler/AutowirePass.php +++ b/Compiler/AutowirePass.php @@ -351,7 +351,17 @@ private function set(string $type, string $id) private function createTypeNotFoundMessage(TypedReference $reference, $label) { - if (!$r = $this->container->getReflectionClass($type = $reference->getType(), false)) { + $trackResources = $this->container->isTrackingResources(); + $this->container->setResourceTracking(false); + try { + if ($r = $this->container->getReflectionClass($type = $reference->getType(), false)) { + $alternatives = $this->createTypeAlternatives($reference); + } + } finally { + $this->container->setResourceTracking($trackResources); + } + + if (!$r) { // either $type does not exist or a parent class does not exist try { $resource = new ClassExistenceResource($type, false); @@ -364,7 +374,6 @@ private function createTypeNotFoundMessage(TypedReference $reference, $label) $message = sprintf('has type "%s" but this class %s.', $type, $parentMsg ? sprintf('is missing a parent class (%s)', $parentMsg) : 'was not found'); } else { - $alternatives = $this->createTypeAlternatives($reference); $message = $this->container->has($type) ? 'this service is abstract' : 'no such service exists'; $message = sprintf('references %s "%s" but %s.%s', $r->isInterface() ? 'interface' : 'class', $type, $message, $alternatives); diff --git a/Compiler/ServiceReferenceGraph.php b/Compiler/ServiceReferenceGraph.php index 721e87568..4e82e5486 100644 --- a/Compiler/ServiceReferenceGraph.php +++ b/Compiler/ServiceReferenceGraph.php @@ -73,7 +73,7 @@ public function clear() /** * Connects 2 nodes together in the Graph. */ - public function connect(?string $sourceId, $sourceValue, ?string $destId, $destValue = null, $reference = null, bool $lazy = false, bool $weak = false) + public function connect(?string $sourceId, $sourceValue, ?string $destId, $destValue = null, $reference = null, bool $lazy = false, bool $weak = false, bool $byConstructor = false) { if (null === $sourceId || null === $destId) { return; @@ -81,7 +81,7 @@ public function connect(?string $sourceId, $sourceValue, ?string $destId, $destV $sourceNode = $this->createNode($sourceId, $sourceValue); $destNode = $this->createNode($destId, $destValue); - $edge = new ServiceReferenceGraphEdge($sourceNode, $destNode, $reference, $lazy, $weak); + $edge = new ServiceReferenceGraphEdge($sourceNode, $destNode, $reference, $lazy, $weak, $byConstructor); $sourceNode->addOutEdge($edge); $destNode->addInEdge($edge); diff --git a/Compiler/ServiceReferenceGraphEdge.php b/Compiler/ServiceReferenceGraphEdge.php index 3e5b9c92c..986145606 100644 --- a/Compiler/ServiceReferenceGraphEdge.php +++ b/Compiler/ServiceReferenceGraphEdge.php @@ -25,14 +25,16 @@ class ServiceReferenceGraphEdge private $value; private $lazy; private $weak; + private $byConstructor; - public function __construct(ServiceReferenceGraphNode $sourceNode, ServiceReferenceGraphNode $destNode, $value = null, bool $lazy = false, bool $weak = false) + public function __construct(ServiceReferenceGraphNode $sourceNode, ServiceReferenceGraphNode $destNode, $value = null, bool $lazy = false, bool $weak = false, bool $byConstructor = false) { $this->sourceNode = $sourceNode; $this->destNode = $destNode; $this->value = $value; $this->lazy = $lazy; $this->weak = $weak; + $this->byConstructor = $byConstructor; } /** @@ -84,4 +86,14 @@ public function isWeak() { return $this->weak; } + + /** + * Returns true if the edge links with a constructor argument. + * + * @return bool + */ + public function isReferencedByConstructor() + { + return $this->byConstructor; + } } diff --git a/ContainerBuilder.php b/ContainerBuilder.php index 03e848026..cff36860c 100644 --- a/ContainerBuilder.php +++ b/ContainerBuilder.php @@ -344,11 +344,11 @@ public function getReflectionClass(?string $class, bool $throw = true): ?\Reflec try { if (isset($this->classReflectors[$class])) { $classReflector = $this->classReflectors[$class]; - } elseif ($this->trackResources) { + } elseif (class_exists(ClassExistenceResource::class)) { $resource = new ClassExistenceResource($class, false); $classReflector = $resource->isFresh(0) ? false : new \ReflectionClass($class); } else { - $classReflector = new \ReflectionClass($class); + $classReflector = class_exists($class) ? new \ReflectionClass($class) : false; } } catch (\ReflectionException $e) { if ($throw) { diff --git a/Definition.php b/Definition.php index 45d823273..9aa916a49 100644 --- a/Definition.php +++ b/Definition.php @@ -406,7 +406,7 @@ public function getMethodCalls() /** * Sets the definition templates to conditionally apply on the current definition, keyed by parent interface/class. * - * @param $instanceof ChildDefinition[] + * @param ChildDefinition[] $instanceof * * @return $this */ diff --git a/Dumper/GraphvizDumper.php b/Dumper/GraphvizDumper.php index 9c35e066e..8cef0549b 100644 --- a/Dumper/GraphvizDumper.php +++ b/Dumper/GraphvizDumper.php @@ -132,6 +132,14 @@ private function findEdges(string $id, array $arguments, bool $required, string $edges[] = array('name' => $name, 'required' => $required, 'to' => $argument, 'lazy' => $lazyEdge); } elseif ($argument instanceof ArgumentInterface) { $edges = array_merge($edges, $this->findEdges($id, $argument->getValues(), $required, $name, true)); + } elseif ($argument instanceof Definition) { + $edges = array_merge($edges, + $this->findEdges($id, $argument->getArguments(), $required, ''), + $this->findEdges($id, $argument->getProperties(), false, '') + ); + foreach ($argument->getMethodCalls() as $call) { + $edges = array_merge($edges, $this->findEdges($id, $call[1], false, $call[0].'()')); + } } elseif (\is_array($argument)) { $edges = array_merge($edges, $this->findEdges($id, $argument, $required, $name, $lazy)); } diff --git a/Dumper/PhpDumper.php b/Dumper/PhpDumper.php index a26aae77b..d9a9c9c82 100644 --- a/Dumper/PhpDumper.php +++ b/Dumper/PhpDumper.php @@ -155,12 +155,16 @@ public function dump(array $options = array()) } } - (new AnalyzeServiceReferencesPass(false))->process($this->container); + (new AnalyzeServiceReferencesPass(false, !$this->getProxyDumper() instanceof NullDumper))->process($this->container); $this->circularReferences = array(); - $checkedNodes = array(); - foreach ($this->container->getCompiler()->getServiceReferenceGraph()->getNodes() as $id => $node) { - $currentPath = array($id => $id); - $this->analyzeCircularReferences($node->getOutEdges(), $checkedNodes, $currentPath); + foreach (array(true, false) as $byConstructor) { + foreach ($this->container->getCompiler()->getServiceReferenceGraph()->getNodes() as $id => $node) { + if (!$node->getValue() instanceof Definition) { + continue; + } + $currentPath = array($id => true); + $this->analyzeCircularReferences($node->getOutEdges(), $currentPath, $id, $byConstructor); + } } $this->container->getCompiler()->getServiceReferenceGraph()->clear(); @@ -303,23 +307,31 @@ private function getProxyDumper(): ProxyDumper return $this->proxyDumper; } - private function analyzeCircularReferences(array $edges, &$checkedNodes, &$currentPath) + private function analyzeCircularReferences(array $edges, &$currentPath, $sourceId, $byConstructor) { foreach ($edges as $edge) { + if ($byConstructor && !$edge->isReferencedByConstructor()) { + continue; + } $node = $edge->getDestNode(); $id = $node->getId(); - if ($node->getValue() && ($edge->isLazy() || $edge->isWeak())) { + if (!$node->getValue() instanceof Definition || $sourceId === $id || $edge->isLazy() || $edge->isWeak()) { // no-op } elseif (isset($currentPath[$id])) { + $currentId = $id; foreach (array_reverse($currentPath) as $parentId) { - $this->circularReferences[$parentId][$id] = $id; - $id = $parentId; + if (!isset($this->circularReferences[$parentId][$currentId])) { + $this->circularReferences[$parentId][$currentId] = $byConstructor; + } + if ($parentId === $id) { + break; + } + $currentId = $parentId; } - } elseif (!isset($checkedNodes[$id])) { - $checkedNodes[$id] = true; + } else { $currentPath[$id] = $id; - $this->analyzeCircularReferences($node->getOutEdges(), $checkedNodes, $currentPath); + $this->analyzeCircularReferences($node->getOutEdges(), $currentPath, $id, $byConstructor); unset($currentPath[$id]); } } @@ -429,7 +441,7 @@ private function addServiceInclude(string $cId, Definition $definition): string * @throws InvalidArgumentException * @throws RuntimeException */ - private function addServiceInstance(string $id, Definition $definition, string $isSimpleInstance): string + private function addServiceInstance(string $id, Definition $definition, bool $isSimpleInstance): string { $class = $this->dumpValue($definition->getClass()); @@ -552,7 +564,7 @@ private function addService(string $id, Definition $definition, string &$file = $this->definitionVariables = new \SplObjectStorage(); $this->referenceVariables = array(); $this->variableCount = 0; - $this->definitionVariables[$definition] = $this->referenceVariables[$id] = new Variable('instance'); + $this->referenceVariables[$id] = new Variable('instance'); $return = array(); @@ -630,22 +642,7 @@ protected function {$methodName}($lazyInitialization) $code .= sprintf(" @trigger_error(%s, E_USER_DEPRECATED);\n\n", $this->export($definition->getDeprecationMessage($id))); } - $head = $tail = ''; - $arguments = array($definition->getArguments(), $definition->getFactory()); - $this->addInlineVariables($head, $tail, $id, $arguments, true); - $code .= '' !== $head ? $head."\n" : ''; - - if ($arguments = array_filter(array($definition->getProperties(), $definition->getMethodCalls(), $definition->getConfigurator()))) { - $this->addInlineVariables($tail, $tail, $id, $arguments, false); - - $tail .= '' !== $tail ? "\n" : ''; - $tail .= $this->addServiceProperties($definition); - $tail .= $this->addServiceMethodCalls($definition); - $tail .= $this->addServiceConfigurator($definition); - } - - $code .= $this->addServiceInstance($id, $definition, '' === $tail) - .('' !== $tail ? "\n".$tail."\n return \$instance;\n" : ''); + $code .= $this->addInlineService($id, $definition); if ($asFile) { $code = implode("\n", array_map(function ($line) { return $line ? substr($line, 8) : $line; }, explode("\n", $code))); @@ -659,35 +656,45 @@ protected function {$methodName}($lazyInitialization) return $code; } - private function addInlineVariables(string &$head, string &$tail, string $id, array $arguments, bool $forConstructor): bool + private function addInlineVariables(string $id, Definition $definition, array $arguments, bool $forConstructor): string { - $hasSelfRef = false; + $code = ''; foreach ($arguments as $argument) { if (\is_array($argument)) { - $hasSelfRef = $this->addInlineVariables($head, $tail, $id, $argument, $forConstructor) || $hasSelfRef; + $code .= $this->addInlineVariables($id, $definition, $argument, $forConstructor); } elseif ($argument instanceof Reference) { - $hasSelfRef = $this->addInlineReference($head, $id, $argument, $forConstructor) || $hasSelfRef; + $code .= $this->addInlineReference($id, $definition, $argument, $forConstructor); } elseif ($argument instanceof Definition) { - $hasSelfRef = $this->addInlineService($head, $tail, $id, $argument, $forConstructor) || $hasSelfRef; + $code .= $this->addInlineService($id, $definition, $argument, $forConstructor); } } - return $hasSelfRef; + return $code; } - private function addInlineReference(string &$code, string $id, string $targetId, bool $forConstructor): bool + private function addInlineReference(string $id, Definition $definition, string $targetId, bool $forConstructor): string { - $hasSelfRef = isset($this->circularReferences[$id][$targetId]); + list($callCount, $behavior) = $this->serviceCalls[$targetId]; + + while ($this->container->hasAlias($targetId)) { + $targetId = (string) $this->container->getAlias($targetId); + } + + if ($id === $targetId) { + return $this->addInlineService($id, $definition, $definition); + } if ('service_container' === $targetId || isset($this->referenceVariables[$targetId])) { - return $hasSelfRef; + return ''; } - list($callCount, $behavior) = $this->serviceCalls[$targetId]; + $hasSelfRef = isset($this->circularReferences[$id][$targetId]); + $forConstructor = $forConstructor && !isset($this->definitionVariables[$definition]); + $code = $hasSelfRef && $this->circularReferences[$id][$targetId] && !$forConstructor ? $this->addInlineService($id, $definition, $definition) : ''; - if (2 > $callCount && (!$hasSelfRef || !$forConstructor)) { - return $hasSelfRef; + if (isset($this->referenceVariables[$targetId]) || (2 > $callCount && (!$hasSelfRef || !$forConstructor))) { + return $code; } $name = $this->getNextVariableName(); @@ -697,7 +704,7 @@ private function addInlineReference(string &$code, string $id, string $targetId, $code .= sprintf(" \$%s = %s;\n", $name, $this->getServiceCall($targetId, $reference)); if (!$hasSelfRef || !$forConstructor) { - return $hasSelfRef; + return $code; } $code .= sprintf(<<<'EOTXT' @@ -712,46 +719,56 @@ private function addInlineReference(string &$code, string $id, string $targetId, $id ); - return false; + return $code; } - private function addInlineService(string &$head, string &$tail, string $id, Definition $definition, bool $forConstructor): bool + private function addInlineService(string $id, Definition $definition, Definition $inlineDef = null, bool $forConstructor = true): string { - if (isset($this->definitionVariables[$definition])) { - return false; + $isSimpleInstance = $isRootInstance = null === $inlineDef; + + if (isset($this->definitionVariables[$inlineDef = $inlineDef ?: $definition])) { + return ''; } - $arguments = array($definition->getArguments(), $definition->getFactory()); + $arguments = array($inlineDef->getArguments(), $inlineDef->getFactory()); - if (2 > $this->inlinedDefinitions[$definition] && !$definition->getMethodCalls() && !$definition->getProperties() && !$definition->getConfigurator()) { - return $this->addInlineVariables($head, $tail, $id, $arguments, $forConstructor); - } + $code = $this->addInlineVariables($id, $definition, $arguments, $forConstructor); - $name = $this->getNextVariableName(); - $this->definitionVariables[$definition] = new Variable($name); + if ($arguments = array_filter(array($inlineDef->getProperties(), $inlineDef->getMethodCalls(), $inlineDef->getConfigurator()))) { + $isSimpleInstance = false; + } elseif ($definition !== $inlineDef && 2 > $this->inlinedDefinitions[$inlineDef]) { + return $code; + } - $code = ''; - if ($forConstructor) { - $hasSelfRef = $this->addInlineVariables($code, $tail, $id, $arguments, $forConstructor); + if (isset($this->definitionVariables[$inlineDef])) { + $isSimpleInstance = false; } else { - $hasSelfRef = $this->addInlineVariables($code, $code, $id, $arguments, $forConstructor); - } - $code .= $this->addNewInstance($definition, '$'.$name, ' = ', $id); - $hasSelfRef && !$forConstructor ? $tail .= ('' !== $tail ? "\n" : '').$code : $head .= ('' !== $head ? "\n" : '').$code; + $name = $definition === $inlineDef ? 'instance' : $this->getNextVariableName(); + $this->definitionVariables[$inlineDef] = new Variable($name); + $code .= '' !== $code ? "\n" : ''; - $code = ''; - $arguments = array($definition->getProperties(), $definition->getMethodCalls(), $definition->getConfigurator()); - $hasSelfRef = $this->addInlineVariables($code, $code, $id, $arguments, false) || $hasSelfRef; + if ('instance' === $name) { + $code .= $this->addServiceInstance($id, $definition, $isSimpleInstance); + } else { + $code .= $this->addNewInstance($inlineDef, '$'.$name, ' = ', $id); + } - $code .= '' !== $code ? "\n" : ''; - $code .= $this->addServiceProperties($definition, $name); - $code .= $this->addServiceMethodCalls($definition, $name); - $code .= $this->addServiceConfigurator($definition, $name); - if ('' !== $code) { - $hasSelfRef ? $tail .= ('' !== $tail ? "\n" : '').$code : $head .= $code; + if ('' !== $inline = $this->addInlineVariables($id, $definition, $arguments, false)) { + $code .= "\n".$inline."\n"; + } elseif ($arguments && 'instance' === $name) { + $code .= "\n"; + } + + $code .= $this->addServiceProperties($inlineDef, $name); + $code .= $this->addServiceMethodCalls($inlineDef, $name); + $code .= $this->addServiceConfigurator($inlineDef, $name); } - return $hasSelfRef; + if ($isRootInstance && !$isSimpleInstance) { + $code .= "\n return \$instance;\n"; + } + + return $code; } private function addServices(): string @@ -1217,7 +1234,7 @@ public function getParameterBag() /*{$this->docStar} * Computes a dynamic parameter. * - * @param string The name of the dynamic parameter to load + * @param string \$name The name of the dynamic parameter to load * * @return mixed The value of the dynamic parameter * diff --git a/Loader/IniFileLoader.php b/Loader/IniFileLoader.php index ed3709104..2ee9ea8ff 100644 --- a/Loader/IniFileLoader.php +++ b/Loader/IniFileLoader.php @@ -70,7 +70,9 @@ public function supports($resource, $type = null) private function phpize($value) { // trim on the right as comments removal keep whitespaces - $value = rtrim($value); + if ($value !== $v = rtrim($value)) { + $value = '""' === substr_replace($v, '', 1, -1) ? substr($v, 1, -1) : $v; + } $lowercaseValue = strtolower($value); switch (true) { diff --git a/Tests/ContainerBuilderTest.php b/Tests/ContainerBuilderTest.php index 0a4b8bc0c..82a4921e7 100644 --- a/Tests/ContainerBuilderTest.php +++ b/Tests/ContainerBuilderTest.php @@ -1362,6 +1362,8 @@ public function testAlmostCircular($visibility) $foo6 = $container->get('foo6'); $this->assertEquals((object) array('bar6' => (object) array()), $foo6); + + $this->assertInstanceOf(\stdClass::class, $container->get('root')); } public function provideAlmostCircular() diff --git a/Tests/Dumper/GraphvizDumperTest.php b/Tests/Dumper/GraphvizDumperTest.php index ffdd0730c..3c40bb550 100644 --- a/Tests/Dumper/GraphvizDumperTest.php +++ b/Tests/Dumper/GraphvizDumperTest.php @@ -13,7 +13,9 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Dumper\GraphvizDumper; +use Symfony\Component\DependencyInjection\Reference; class GraphvizDumperTest extends TestCase { @@ -32,11 +34,11 @@ public function testDump() $container = include self::$fixturesPath.'/containers/container9.php'; $dumper = new GraphvizDumper($container); - $this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services9.dot')), $dumper->dump(), '->dump() dumps services'); + $this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services9.dot', $dumper->dump(), '->dump() dumps services'); $container = include self::$fixturesPath.'/containers/container10.php'; $dumper = new GraphvizDumper($container); - $this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services10.dot')), $dumper->dump(), '->dump() dumps services'); + $this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services10.dot', $dumper->dump(), '->dump() dumps services'); $container = include self::$fixturesPath.'/containers/container10.php'; $dumper = new GraphvizDumper($container); @@ -47,21 +49,21 @@ public function testDump() 'node.instance' => array('fillcolor' => 'green', 'style' => 'empty'), 'node.definition' => array('fillcolor' => 'grey'), 'node.missing' => array('fillcolor' => 'red', 'style' => 'empty'), - )), str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services10-1.dot')), '->dump() dumps services'); + )), file_get_contents(self::$fixturesPath.'/graphviz/services10-1.dot'), '->dump() dumps services'); } public function testDumpWithFrozenContainer() { $container = include self::$fixturesPath.'/containers/container13.php'; $dumper = new GraphvizDumper($container); - $this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services13.dot')), $dumper->dump(), '->dump() dumps services'); + $this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services13.dot', $dumper->dump(), '->dump() dumps services'); } public function testDumpWithFrozenCustomClassContainer() { $container = include self::$fixturesPath.'/containers/container14.php'; $dumper = new GraphvizDumper($container); - $this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services14.dot')), $dumper->dump(), '->dump() dumps services'); + $this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services14.dot', $dumper->dump(), '->dump() dumps services'); } public function testDumpWithUnresolvedParameter() @@ -69,6 +71,18 @@ public function testDumpWithUnresolvedParameter() $container = include self::$fixturesPath.'/containers/container17.php'; $dumper = new GraphvizDumper($container); - $this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services17.dot')), $dumper->dump(), '->dump() dumps services'); + $this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services17.dot', $dumper->dump(), '->dump() dumps services'); + } + + public function testDumpWithInlineDefinition() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass')->addArgument( + (new Definition('stdClass'))->addArgument(new Reference('bar')) + ); + $container->register('bar', 'stdClass'); + $dumper = new GraphvizDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services_inline.dot', $dumper->dump(), '->dump() dumps nested references'); } } diff --git a/Tests/Dumper/PhpDumperTest.php b/Tests/Dumper/PhpDumperTest.php index 8cb11568f..962137e73 100644 --- a/Tests/Dumper/PhpDumperTest.php +++ b/Tests/Dumper/PhpDumperTest.php @@ -873,6 +873,8 @@ public function testAlmostCircular($visibility) $foo6 = $container->get('foo6'); $this->assertEquals((object) array('bar6' => (object) array()), $foo6); + + $this->assertInstanceOf(\stdClass::class, $container->get('root')); } public function provideAlmostCircular() diff --git a/Tests/Fixtures/FooForCircularWithAddCalls.php b/Tests/Fixtures/FooForCircularWithAddCalls.php new file mode 100644 index 000000000..a8331dc3e --- /dev/null +++ b/Tests/Fixtures/FooForCircularWithAddCalls.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Fixtures; + +class FooForCircularWithAddCalls +{ + public function call(\stdClass $argument) + { + } +} diff --git a/Tests/Fixtures/containers/container_almost_circular.php b/Tests/Fixtures/containers/container_almost_circular.php index 3286f3d02..4c9906f7a 100644 --- a/Tests/Fixtures/containers/container_almost_circular.php +++ b/Tests/Fixtures/containers/container_almost_circular.php @@ -4,6 +4,7 @@ use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Dumper\PhpDumper; use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls; $public = 'public' === $visibility; $container = new ContainerBuilder(); @@ -115,4 +116,33 @@ ->setPublic(true) ->setProperty('bar6', new Reference('bar6')); +// provided by Christian Schiffler + +$container + ->register('root', 'stdClass') + ->setArguments([new Reference('level2'), new Reference('multiuse1')]) + ->setPublic(true); + +$container + ->register('level2', FooForCircularWithAddCalls::class) + ->addMethodCall('call', [new Reference('level3')]); + +$container->register('multiuse1', 'stdClass'); + +$container + ->register('level3', 'stdClass') + ->addArgument(new Reference('level4')); + +$container + ->register('level4', 'stdClass') + ->setArguments([new Reference('multiuse1'), new Reference('level5')]); + +$container + ->register('level5', 'stdClass') + ->addArgument(new Reference('level6')); + +$container + ->register('level6', FooForCircularWithAddCalls::class) + ->addMethodCall('call', [new Reference('level5')]); + return $container; diff --git a/Tests/Fixtures/graphviz/services_inline.dot b/Tests/Fixtures/graphviz/services_inline.dot new file mode 100644 index 000000000..b430b186d --- /dev/null +++ b/Tests/Fixtures/graphviz/services_inline.dot @@ -0,0 +1,10 @@ +digraph sc { + ratio="compress" + node [fontsize="11" fontname="Arial" shape="record"]; + edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"]; + + node_service_container [label="service_container (Psr\Container\ContainerInterface, Symfony\Component\DependencyInjection\ContainerInterface)\nSymfony\\Component\\DependencyInjection\\ContainerInterface\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_foo [label="foo\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_bar [label="bar\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_foo -> node_bar [label="" style="filled"]; +} diff --git a/Tests/Fixtures/ini/types.ini b/Tests/Fixtures/ini/types.ini index 19cc5b3b3..75840907d 100644 --- a/Tests/Fixtures/ini/types.ini +++ b/Tests/Fixtures/ini/types.ini @@ -11,9 +11,10 @@ constant = PHP_VERSION 12 = 12 12_string = '12' + 12_quoted_number = "12" 12_comment = 12 ; comment 12_string_comment = '12' ; comment - 12_string_comment_again = "12" ; comment + 12_quoted_number_comment = "12" ; comment -12 = -12 0 = 0 1 = 1 diff --git a/Tests/Fixtures/php/services10.php b/Tests/Fixtures/php/services10.php index 31c4475ec..19e4f9c5c 100644 --- a/Tests/Fixtures/php/services10.php +++ b/Tests/Fixtures/php/services10.php @@ -115,7 +115,7 @@ public function getParameterBag() /** * Computes a dynamic parameter. * - * @param string The name of the dynamic parameter to load + * @param string $name The name of the dynamic parameter to load * * @return mixed The value of the dynamic parameter * diff --git a/Tests/Fixtures/php/services12.php b/Tests/Fixtures/php/services12.php index d4f872f94..c64a2130d 100644 --- a/Tests/Fixtures/php/services12.php +++ b/Tests/Fixtures/php/services12.php @@ -122,7 +122,7 @@ public function getParameterBag() /** * Computes a dynamic parameter. * - * @param string The name of the dynamic parameter to load + * @param string $name The name of the dynamic parameter to load * * @return mixed The value of the dynamic parameter * diff --git a/Tests/Fixtures/php/services19.php b/Tests/Fixtures/php/services19.php index 73e1c4cc1..91880ff30 100644 --- a/Tests/Fixtures/php/services19.php +++ b/Tests/Fixtures/php/services19.php @@ -132,7 +132,7 @@ public function getParameterBag() /** * Computes a dynamic parameter. * - * @param string The name of the dynamic parameter to load + * @param string $name The name of the dynamic parameter to load * * @return mixed The value of the dynamic parameter * diff --git a/Tests/Fixtures/php/services26.php b/Tests/Fixtures/php/services26.php index 942eb0eb7..53c0242a8 100644 --- a/Tests/Fixtures/php/services26.php +++ b/Tests/Fixtures/php/services26.php @@ -138,7 +138,7 @@ public function getParameterBag() /** * Computes a dynamic parameter. * - * @param string The name of the dynamic parameter to load + * @param string $name The name of the dynamic parameter to load * * @return mixed The value of the dynamic parameter * diff --git a/Tests/Fixtures/php/services8.php b/Tests/Fixtures/php/services8.php index eeeb37a07..5e809b845 100644 --- a/Tests/Fixtures/php/services8.php +++ b/Tests/Fixtures/php/services8.php @@ -102,7 +102,7 @@ public function getParameterBag() /** * Computes a dynamic parameter. * - * @param string The name of the dynamic parameter to load + * @param string $name The name of the dynamic parameter to load * * @return mixed The value of the dynamic parameter * diff --git a/Tests/Fixtures/php/services9_as_files.txt b/Tests/Fixtures/php/services9_as_files.txt index 2b92c5838..7f9c5cec2 100644 --- a/Tests/Fixtures/php/services9_as_files.txt +++ b/Tests/Fixtures/php/services9_as_files.txt @@ -230,7 +230,6 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException; $this->services['foo_with_inline'] = $instance = new \Foo(); $a = new \Bar(); - $a->pub = 'pub'; $a->setBaz(($this->services['baz'] ?? $this->load('getBazService.php'))); @@ -536,7 +535,7 @@ class ProjectServiceContainer extends Container /** * Computes a dynamic parameter. * - * @param string The name of the dynamic parameter to load + * @param string $name The name of the dynamic parameter to load * * @return mixed The value of the dynamic parameter * diff --git a/Tests/Fixtures/php/services9_compiled.php b/Tests/Fixtures/php/services9_compiled.php index 6231dab53..407a908d9 100644 --- a/Tests/Fixtures/php/services9_compiled.php +++ b/Tests/Fixtures/php/services9_compiled.php @@ -301,7 +301,6 @@ protected function getFooWithInlineService() $this->services['foo_with_inline'] = $instance = new \Foo(); $a = new \Bar(); - $a->pub = 'pub'; $a->setBaz(($this->services['baz'] ?? $this->getBazService())); @@ -476,7 +475,7 @@ public function getParameterBag() /** * Computes a dynamic parameter. * - * @param string The name of the dynamic parameter to load + * @param string $name The name of the dynamic parameter to load * * @return mixed The value of the dynamic parameter * diff --git a/Tests/Fixtures/php/services_adawson.php b/Tests/Fixtures/php/services_adawson.php index f2d4cebdd..1123e095e 100644 --- a/Tests/Fixtures/php/services_adawson.php +++ b/Tests/Fixtures/php/services_adawson.php @@ -76,14 +76,13 @@ protected function getBusService() $this->services['App\Bus'] = $instance = new \App\Bus($a); $b = ($this->privates['App\Schema'] ?? $this->getSchemaService()); + $c = new \App\Registry(); + $c->processor = array(0 => $a, 1 => $instance); - $d = new \App\Registry(); + $d = new \App\Processor($c, $a); - $d->processor = array(0 => $a, 1 => $instance); - $c = new \App\Processor($d, $a); - - $instance->handler1 = new \App\Handler1($a, $b, $c); - $instance->handler2 = new \App\Handler2($a, $b, $c); + $instance->handler1 = new \App\Handler1($a, $b, $d); + $instance->handler2 = new \App\Handler2($a, $b, $d); return $instance; } diff --git a/Tests/Fixtures/php/services_almost_circular_private.php b/Tests/Fixtures/php/services_almost_circular_private.php index 6b3e44738..079447092 100644 --- a/Tests/Fixtures/php/services_almost_circular_private.php +++ b/Tests/Fixtures/php/services_almost_circular_private.php @@ -41,6 +41,7 @@ public function __construct() 'logger' => 'getLoggerService', 'manager' => 'getManagerService', 'manager2' => 'getManager2Service', + 'root' => 'getRootService', 'subscriber' => 'getSubscriberService', ); @@ -79,7 +80,13 @@ public function getRemovedIds() 'foobar' => true, 'foobar2' => true, 'foobar3' => true, + 'level2' => true, + 'level3' => true, + 'level4' => true, + 'level5' => true, + 'level6' => true, 'logger2' => true, + 'multiuse1' => true, 'subscriber2' => true, ); } @@ -141,10 +148,10 @@ protected function getConnectionService() $this->services['connection'] = $instance = new \stdClass($a, $b); - $a->subscriber = ($this->services['subscriber'] ?? $this->getSubscriberService()); - $b->logger = ($this->services['logger'] ?? $this->getLoggerService()); + $a->subscriber = ($this->services['subscriber'] ?? $this->getSubscriberService()); + return $instance; } @@ -157,19 +164,19 @@ protected function getConnection2Service() { $a = new \stdClass(); - $c = new \stdClass(); + $b = new \stdClass(); - $this->services['connection2'] = $instance = new \stdClass($a, $c); + $this->services['connection2'] = $instance = new \stdClass($a, $b); - $b = ($this->services['manager2'] ?? $this->getManager2Service()); + $c = new \stdClass($instance); - $a->subscriber2 = new \stdClass($b); + $d = ($this->services['manager2'] ?? $this->getManager2Service()); - $d = new \stdClass($instance); + $c->handler2 = new \stdClass($d); - $d->handler2 = new \stdClass($b); + $b->logger2 = $c; - $c->logger2 = $d; + $a->subscriber2 = new \stdClass($d); return $instance; } @@ -216,7 +223,6 @@ protected function getFoo5Service() $this->services['foo5'] = $instance = new \stdClass(); $a = new \stdClass($instance); - $a->foo = $instance; $instance->bar = $a; @@ -306,6 +312,22 @@ protected function getManager2Service() return $this->services['manager2'] = new \stdClass($a); } + /** + * Gets the public 'root' shared service. + * + * @return \stdClass + */ + protected function getRootService() + { + $a = new \Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls(); + + $b = new \stdClass(); + + $a->call(new \stdClass(new \stdClass($b, ($this->privates['level5'] ?? $this->getLevel5Service())))); + + return $this->services['root'] = new \stdClass($a, $b); + } + /** * Gets the public 'subscriber' shared service. * @@ -337,4 +359,20 @@ protected function getBar6Service() return $this->privates['bar6'] = new \stdClass($a); } + + /** + * Gets the private 'level5' shared service. + * + * @return \stdClass + */ + protected function getLevel5Service() + { + $a = new \Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls(); + + $this->privates['level5'] = $instance = new \stdClass($a); + + $a->call($instance); + + return $instance; + } } diff --git a/Tests/Fixtures/php/services_almost_circular_public.php b/Tests/Fixtures/php/services_almost_circular_public.php index 93cb7ae74..7923ae879 100644 --- a/Tests/Fixtures/php/services_almost_circular_public.php +++ b/Tests/Fixtures/php/services_almost_circular_public.php @@ -48,6 +48,7 @@ public function __construct() 'logger' => 'getLoggerService', 'manager' => 'getManagerService', 'manager2' => 'getManager2Service', + 'root' => 'getRootService', 'subscriber' => 'getSubscriberService', ); @@ -79,7 +80,13 @@ public function getRemovedIds() 'bar6' => true, 'config' => true, 'config2' => true, + 'level2' => true, + 'level3' => true, + 'level4' => true, + 'level5' => true, + 'level6' => true, 'logger2' => true, + 'multiuse1' => true, 'subscriber2' => true, ); } @@ -155,11 +162,16 @@ protected function getBaz6Service() */ protected function getConnectionService() { - $a = new \stdClass(); + $a = ($this->services['dispatcher'] ?? $this->getDispatcherService()); + + if (isset($this->services['connection'])) { + return $this->services['connection']; + } + $b = new \stdClass(); - $this->services['connection'] = $instance = new \stdClass(($this->services['dispatcher'] ?? $this->getDispatcherService()), $a); + $this->services['connection'] = $instance = new \stdClass($a, $b); - $a->logger = ($this->services['logger'] ?? $this->getLoggerService()); + $b->logger = ($this->services['logger'] ?? $this->getLoggerService()); return $instance; } @@ -171,15 +183,19 @@ protected function getConnectionService() */ protected function getConnection2Service() { - $a = new \stdClass(); + $a = ($this->services['dispatcher2'] ?? $this->getDispatcher2Service()); - $this->services['connection2'] = $instance = new \stdClass(($this->services['dispatcher2'] ?? $this->getDispatcher2Service()), $a); + if (isset($this->services['connection2'])) { + return $this->services['connection2']; + } + $b = new \stdClass(); - $b = new \stdClass($instance); + $this->services['connection2'] = $instance = new \stdClass($a, $b); - $b->handler2 = new \stdClass(($this->services['manager2'] ?? $this->getManager2Service())); + $c = new \stdClass($instance); + $c->handler2 = new \stdClass(($this->services['manager2'] ?? $this->getManager2Service())); - $a->logger2 = $b; + $b->logger2 = $c; return $instance; } @@ -396,6 +412,22 @@ protected function getManager2Service() return $this->services['manager2'] = new \stdClass($a); } + /** + * Gets the public 'root' shared service. + * + * @return \stdClass + */ + protected function getRootService() + { + $a = new \Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls(); + + $b = new \stdClass(); + + $a->call(new \stdClass(new \stdClass($b, ($this->privates['level5'] ?? $this->getLevel5Service())))); + + return $this->services['root'] = new \stdClass($a, $b); + } + /** * Gets the public 'subscriber' shared service. * @@ -403,7 +435,13 @@ protected function getManager2Service() */ protected function getSubscriberService() { - return $this->services['subscriber'] = new \stdClass(($this->services['manager'] ?? $this->getManagerService())); + $a = ($this->services['manager'] ?? $this->getManagerService()); + + if (isset($this->services['subscriber'])) { + return $this->services['subscriber']; + } + + return $this->services['subscriber'] = new \stdClass($a); } /** @@ -421,4 +459,20 @@ protected function getBar6Service() return $this->privates['bar6'] = new \stdClass($a); } + + /** + * Gets the private 'level5' shared service. + * + * @return \stdClass + */ + protected function getLevel5Service() + { + $a = new \Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls(); + + $this->privates['level5'] = $instance = new \stdClass($a); + + $a->call($instance); + + return $instance; + } } diff --git a/Tests/Fixtures/php/services_array_params.php b/Tests/Fixtures/php/services_array_params.php index d72e6fd00..71ee501c6 100644 --- a/Tests/Fixtures/php/services_array_params.php +++ b/Tests/Fixtures/php/services_array_params.php @@ -125,7 +125,7 @@ public function getParameterBag() /** * Computes a dynamic parameter. * - * @param string The name of the dynamic parameter to load + * @param string $name The name of the dynamic parameter to load * * @return mixed The value of the dynamic parameter * diff --git a/Tests/Fixtures/php/services_base64_env.php b/Tests/Fixtures/php/services_base64_env.php index 8af802f70..db13b59f5 100644 --- a/Tests/Fixtures/php/services_base64_env.php +++ b/Tests/Fixtures/php/services_base64_env.php @@ -104,7 +104,7 @@ public function getParameterBag() /** * Computes a dynamic parameter. * - * @param string The name of the dynamic parameter to load + * @param string $name The name of the dynamic parameter to load * * @return mixed The value of the dynamic parameter * diff --git a/Tests/Fixtures/php/services_csv_env.php b/Tests/Fixtures/php/services_csv_env.php index 99215f5fd..b32b88e81 100644 --- a/Tests/Fixtures/php/services_csv_env.php +++ b/Tests/Fixtures/php/services_csv_env.php @@ -104,7 +104,7 @@ public function getParameterBag() /** * Computes a dynamic parameter. * - * @param string The name of the dynamic parameter to load + * @param string $name The name of the dynamic parameter to load * * @return mixed The value of the dynamic parameter * diff --git a/Tests/Fixtures/php/services_deep_graph.php b/Tests/Fixtures/php/services_deep_graph.php index 1cb602431..ee05e3934 100644 --- a/Tests/Fixtures/php/services_deep_graph.php +++ b/Tests/Fixtures/php/services_deep_graph.php @@ -85,8 +85,8 @@ protected function getFooService() if (isset($this->services['foo'])) { return $this->services['foo']; } - $b = new \stdClass(); + $c = new \stdClass(); $c->p3 = new \stdClass(); diff --git a/Tests/Fixtures/php/services_env_in_id.php b/Tests/Fixtures/php/services_env_in_id.php index 4100dcdd2..93063503b 100644 --- a/Tests/Fixtures/php/services_env_in_id.php +++ b/Tests/Fixtures/php/services_env_in_id.php @@ -128,7 +128,7 @@ public function getParameterBag() /** * Computes a dynamic parameter. * - * @param string The name of the dynamic parameter to load + * @param string $name The name of the dynamic parameter to load * * @return mixed The value of the dynamic parameter * diff --git a/Tests/Fixtures/php/services_errored_definition.php b/Tests/Fixtures/php/services_errored_definition.php index 34a38dfc4..c3351a208 100644 --- a/Tests/Fixtures/php/services_errored_definition.php +++ b/Tests/Fixtures/php/services_errored_definition.php @@ -301,7 +301,6 @@ protected function getFooWithInlineService() $this->services['foo_with_inline'] = $instance = new \Foo(); $a = new \Bar(); - $a->pub = 'pub'; $a->setBaz(($this->services['baz'] ?? $this->getBazService())); @@ -476,7 +475,7 @@ public function getParameterBag() /** * Computes a dynamic parameter. * - * @param string The name of the dynamic parameter to load + * @param string $name The name of the dynamic parameter to load * * @return mixed The value of the dynamic parameter * diff --git a/Tests/Fixtures/php/services_inline_requires.php b/Tests/Fixtures/php/services_inline_requires.php index 029967067..11552d0fd 100644 --- a/Tests/Fixtures/php/services_inline_requires.php +++ b/Tests/Fixtures/php/services_inline_requires.php @@ -152,7 +152,7 @@ public function getParameterBag() /** * Computes a dynamic parameter. * - * @param string The name of the dynamic parameter to load + * @param string $name The name of the dynamic parameter to load * * @return mixed The value of the dynamic parameter * diff --git a/Tests/Fixtures/php/services_inline_self_ref.php b/Tests/Fixtures/php/services_inline_self_ref.php index d28ee816c..e66332ec8 100644 --- a/Tests/Fixtures/php/services_inline_self_ref.php +++ b/Tests/Fixtures/php/services_inline_self_ref.php @@ -65,14 +65,14 @@ public function getRemovedIds() */ protected function getFooService() { - $b = new \App\Bar(); - $a = new \App\Baz($b); + $a = new \App\Bar(); - $this->services['App\Foo'] = $instance = new \App\Foo($a); + $b = new \App\Baz($a); + $b->bar = $a; - $b->foo = $instance; + $this->services['App\Foo'] = $instance = new \App\Foo($b); - $a->bar = $b; + $a->foo = $instance; return $instance; } diff --git a/Tests/Fixtures/php/services_json_env.php b/Tests/Fixtures/php/services_json_env.php index dd2930a42..de70c12a3 100644 --- a/Tests/Fixtures/php/services_json_env.php +++ b/Tests/Fixtures/php/services_json_env.php @@ -105,7 +105,7 @@ public function getParameterBag() /** * Computes a dynamic parameter. * - * @param string The name of the dynamic parameter to load + * @param string $name The name of the dynamic parameter to load * * @return mixed The value of the dynamic parameter * diff --git a/Tests/Fixtures/php/services_rot13_env.php b/Tests/Fixtures/php/services_rot13_env.php index 012a36023..76ce9e553 100644 --- a/Tests/Fixtures/php/services_rot13_env.php +++ b/Tests/Fixtures/php/services_rot13_env.php @@ -130,7 +130,7 @@ public function getParameterBag() /** * Computes a dynamic parameter. * - * @param string The name of the dynamic parameter to load + * @param string $name The name of the dynamic parameter to load * * @return mixed The value of the dynamic parameter * diff --git a/Tests/Fixtures/php/services_tsantos.php b/Tests/Fixtures/php/services_tsantos.php index 30efad829..b922a51fa 100644 --- a/Tests/Fixtures/php/services_tsantos.php +++ b/Tests/Fixtures/php/services_tsantos.php @@ -68,22 +68,20 @@ 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\EventDispatcher\EventDispatcher(); + $c->addSubscriber(new \TSantos\SerializerBundle\EventListener\StopwatchListener(new \Symfony\Component\Stopwatch\Stopwatch(true))); - $c = new \TSantos\Serializer\Normalizer\JsonNormalizer(); + $this->services['tsantos_serializer'] = $instance = new \TSantos\Serializer\EventEmitterSerializer(new \TSantos\Serializer\Encoder\JsonEncoder(), $a, $c); - $c->setSerializer($instance); + $b->setSerializer($instance); + $d = new \TSantos\Serializer\Normalizer\JsonNormalizer(); + $d->setSerializer($instance); $a->add(new \TSantos\Serializer\Normalizer\ObjectNormalizer(new \TSantos\SerializerBundle\Serializer\CircularReferenceHandler())); $a->add($b); - $a->add($c); + $a->add($d); return $instance; } diff --git a/Tests/Loader/IniFileLoaderTest.php b/Tests/Loader/IniFileLoaderTest.php index cb124bcc8..49e08be94 100644 --- a/Tests/Loader/IniFileLoaderTest.php +++ b/Tests/Loader/IniFileLoaderTest.php @@ -53,7 +53,6 @@ public function testTypeConversionsWithNativePhp($key, $value, $supported) $this->markTestSkipped(sprintf('Converting the value "%s" to "%s" is not supported by the IniFileLoader.', $key, $value)); } - $this->loader->load('types.ini'); $expected = parse_ini_file(__DIR__.'/../Fixtures/ini/types.ini', true, INI_SCANNER_TYPED); $this->assertSame($value, $expected['parameters'][$key], '->load() converts values to PHP types'); } @@ -73,9 +72,10 @@ public function getTypeConversions() array('constant', PHP_VERSION, true), array('12', 12, true), array('12_string', '12', true), + array('12_quoted_number', 12, false), // INI_SCANNER_RAW removes the double quotes array('12_comment', 12, true), array('12_string_comment', '12', true), - array('12_string_comment_again', '12', true), + array('12_quoted_number_comment', 12, false), // INI_SCANNER_RAW removes the double quotes array('-12', -12, true), array('1', 1, true), array('0', 0, true), diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 781f767d5..21dee2a80 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,7 +1,7 @@