diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index b7381de7e581..b96426d48709 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -570,10 +570,13 @@ public function get($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INV return $this->doGet($id, $invalidBehavior); } - private function doGet($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE) + private function doGet($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, array &$inlineServices = array()) { $id = $this->normalizeId($id); + if (isset($inlineServices[$id])) { + return $inlineServices[$id]; + } if (ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $invalidBehavior) { return parent::get($id, $invalidBehavior); } @@ -582,7 +585,7 @@ private function doGet($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_ } if (!isset($this->definitions[$id]) && isset($this->aliasDefinitions[$id])) { - return $this->doGet((string) $this->aliasDefinitions[$id], $invalidBehavior); + return $this->doGet((string) $this->aliasDefinitions[$id], $invalidBehavior, $inlineServices); } try { @@ -599,7 +602,7 @@ private function doGet($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_ $this->{$loading}[$id] = true; try { - $service = $this->createService($definition, new \SplObjectStorage(), $id); + $service = $this->createService($definition, $inlineServices, $id); } finally { unset($this->{$loading}[$id]); } @@ -1054,10 +1057,10 @@ public function findDefinition($id) * @throws RuntimeException When the service is a synthetic service * @throws InvalidArgumentException When configure callable is not callable */ - private function createService(Definition $definition, \SplObjectStorage $inlinedDefinitions, $id = null, $tryProxy = true) + private function createService(Definition $definition, array &$inlineServices, $id = null, $tryProxy = true) { - if (null === $id && isset($inlinedDefinitions[$definition])) { - return $inlinedDefinitions[$definition]; + if (null === $id && isset($inlineServices[$h = spl_object_hash($definition)])) { + return $inlineServices[$h]; } if ($definition instanceof ChildDefinition) { @@ -1078,11 +1081,11 @@ private function createService(Definition $definition, \SplObjectStorage $inline ->instantiateProxy( $this, $definition, - $id, function () use ($definition, $inlinedDefinitions, $id) { - return $this->createService($definition, $inlinedDefinitions, $id, false); + $id, function () use ($definition, &$inlineServices, $id) { + return $this->createService($definition, $inlineServices, $id, false); } ); - $this->shareService($definition, $proxy, $id, $inlinedDefinitions); + $this->shareService($definition, $proxy, $id, $inlineServices); return $proxy; } @@ -1093,7 +1096,7 @@ private function createService(Definition $definition, \SplObjectStorage $inline require_once $parameterBag->resolveValue($definition->getFile()); } - $arguments = $this->doResolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getArguments())), $inlinedDefinitions); + $arguments = $this->doResolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getArguments())), $inlineServices); if (null !== $id && $definition->isShared() && isset($this->services[$id]) && ($tryProxy || !$definition->isLazy())) { return $this->services[$id]; @@ -1101,7 +1104,7 @@ private function createService(Definition $definition, \SplObjectStorage $inline if (null !== $factory = $definition->getFactory()) { if (is_array($factory)) { - $factory = array($this->doResolveServices($parameterBag->resolveValue($factory[0]), $inlinedDefinitions), $factory[1]); + $factory = array($this->doResolveServices($parameterBag->resolveValue($factory[0]), $inlineServices), $factory[1]); } elseif (!is_string($factory)) { throw new RuntimeException(sprintf('Cannot create service "%s" because of invalid factory', $id)); } @@ -1130,16 +1133,16 @@ private function createService(Definition $definition, \SplObjectStorage $inline if ($tryProxy || !$definition->isLazy()) { // share only if proxying failed, or if not a proxy - $this->shareService($definition, $service, $id, $inlinedDefinitions); + $this->shareService($definition, $service, $id, $inlineServices); } - $properties = $this->doResolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getProperties())), $inlinedDefinitions); + $properties = $this->doResolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getProperties())), $inlineServices); foreach ($properties as $name => $value) { $service->$name = $value; } foreach ($definition->getMethodCalls() as $call) { - $this->callMethod($service, $call, $inlinedDefinitions); + $this->callMethod($service, $call, $inlineServices); } if ($callable = $definition->getConfigurator()) { @@ -1147,9 +1150,9 @@ private function createService(Definition $definition, \SplObjectStorage $inline $callable[0] = $parameterBag->resolveValue($callable[0]); if ($callable[0] instanceof Reference) { - $callable[0] = $this->doGet((string) $callable[0], $callable[0]->getInvalidBehavior()); + $callable[0] = $this->doGet((string) $callable[0], $callable[0]->getInvalidBehavior(), $inlineServices); } elseif ($callable[0] instanceof Definition) { - $callable[0] = $this->createService($callable[0], $inlinedDefinitions); + $callable[0] = $this->createService($callable[0], $inlineServices); } } @@ -1173,14 +1176,14 @@ private function createService(Definition $definition, \SplObjectStorage $inline */ public function resolveServices($value) { - return $this->doResolveServices($value, new \SplObjectStorage()); + return $this->doResolveServices($value); } - private function doResolveServices($value, \SplObjectStorage $inlinedDefinitions) + private function doResolveServices($value, array &$inlineServices = array()) { if (is_array($value)) { foreach ($value as $k => $v) { - $value[$k] = $this->doResolveServices($v, $inlinedDefinitions); + $value[$k] = $this->doResolveServices($v, $inlineServices); } } elseif ($value instanceof ServiceClosureArgument) { $reference = $value->getValues()[0]; @@ -1223,9 +1226,9 @@ private function doResolveServices($value, \SplObjectStorage $inlinedDefinitions return $count; }); } elseif ($value instanceof Reference) { - $value = $this->doGet((string) $value, $value->getInvalidBehavior()); + $value = $this->doGet((string) $value, $value->getInvalidBehavior(), $inlineServices); } elseif ($value instanceof Definition) { - $value = $this->createService($value, $inlinedDefinitions); + $value = $this->createService($value, $inlineServices); } elseif ($value instanceof Expression) { $value = $this->getExpressionLanguage()->evaluate($value, array('container' => $this)); } @@ -1540,7 +1543,7 @@ private function getProxyInstantiator() return $this->proxyInstantiator; } - private function callMethod($service, $call, \SplObjectStorage $inlinedDefinitions) + private function callMethod($service, $call, array &$inlineServices) { foreach (self::getServiceConditionals($call[1]) as $s) { if (!$this->has($s)) { @@ -1548,12 +1551,12 @@ private function callMethod($service, $call, \SplObjectStorage $inlinedDefinitio } } foreach (self::getInitializedConditionals($call[1]) as $s) { - if (!$this->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE)) { + if (!$this->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE, $inlineServices)) { return; } } - call_user_func_array(array($service, $call[0]), $this->doResolveServices($this->getParameterBag()->unescapeValue($this->getParameterBag()->resolveValue($call[1])), $inlinedDefinitions)); + call_user_func_array(array($service, $call[0]), $this->doResolveServices($this->getParameterBag()->unescapeValue($this->getParameterBag()->resolveValue($call[1])), $inlineServices)); } /** @@ -1563,14 +1566,11 @@ private function callMethod($service, $call, \SplObjectStorage $inlinedDefinitio * @param object $service * @param string|null $id */ - private function shareService(Definition $definition, $service, $id, \SplObjectStorage $inlinedDefinitions) + private function shareService(Definition $definition, $service, $id, array &$inlineServices) { - if (!$definition->isShared()) { - return; - } - if (null === $id) { - $inlinedDefinitions[$definition] = $service; - } else { + $inlineServices[null !== $id ? $id : spl_object_hash($definition)] = $service; + + if (null !== $id && $definition->isShared()) { $this->services[$id] = $service; unset($this->loading[$id], $this->alreadyLoading[$id]); } diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 3d20c4227954..fb933ce757f5 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -51,7 +51,6 @@ class PhpDumper extends Dumper */ const NON_FIRST_CHARS = 'abcdefghijklmnopqrstuvwxyz0123456789_'; - private $inlinedDefinitions; private $definitionVariables; private $referenceVariables; private $variableCount; @@ -84,8 +83,6 @@ public function __construct(ContainerBuilder $container) } parent::__construct($container); - - $this->inlinedDefinitions = new \SplObjectStorage(); } /** @@ -271,60 +268,48 @@ private function getProxyDumper() /** * Generates Service local temp variables. * - * @param string $cId - * @param Definition $definition - * @param array $inlinedDefinitions - * * @return string */ - private function addServiceLocalTempVariables($cId, Definition $definition, array $inlinedDefinitions) + private function addServiceLocalTempVariables($cId, Definition $definition, \SplObjectStorage $inlinedDefinitions, \SplObjectStorage $allInlinedDefinitions) { - static $template = " \$%s = %s;\n"; + $allCalls = $calls = $behavior = array(); - array_unshift($inlinedDefinitions, $definition); + foreach ($allInlinedDefinitions as $def) { + $arguments = array($def->getArguments(), $def->getFactory(), $def->getProperties(), $def->getMethodCalls(), $def->getConfigurator()); + $this->getServiceCallsFromArguments($arguments, $allCalls, false, $cId, $behavior, $allInlinedDefinitions[$def]); + } - $collectLineage = $this->inlineRequires && !$this->isHotPath($definition); - $isNonLazyShared = isset($this->circularReferences[$cId]) && !$this->getProxyDumper()->isProxyCandidate($definition) && $definition->isShared(); - $lineage = $calls = $behavior = array(); - foreach ($inlinedDefinitions as $iDefinition) { - if ($collectLineage && !$iDefinition->isDeprecated() && $class = is_array($factory = $iDefinition->getFactory()) && is_string($factory[0]) ? $factory[0] : $iDefinition->getClass()) { - $this->collectLineage($class, $lineage); + $isPreInstance = isset($inlinedDefinitions[$definition]) && isset($this->circularReferences[$cId]) && !$this->getProxyDumper()->isProxyCandidate($definition) && $definition->isShared(); + foreach ($inlinedDefinitions as $def) { + $this->getServiceCallsFromArguments(array($def->getArguments(), $def->getFactory()), $calls, $isPreInstance, $cId); + if ($def !== $definition) { + $arguments = array($def->getProperties(), $def->getMethodCalls(), $def->getConfigurator()); + $this->getServiceCallsFromArguments($arguments, $calls, $isPreInstance && !$this->hasReference($cId, $arguments, true), $cId); } - $this->getServiceCallsFromArguments($iDefinition->getArguments(), $calls, $behavior, $isNonLazyShared, $cId); - $isPreInstantiation = $isNonLazyShared && $iDefinition !== $definition && !$this->hasReference($cId, $iDefinition->getMethodCalls(), true) && !$this->hasReference($cId, $iDefinition->getProperties(), true); - $this->getServiceCallsFromArguments($iDefinition->getMethodCalls(), $calls, $behavior, $isPreInstantiation, $cId); - $this->getServiceCallsFromArguments($iDefinition->getProperties(), $calls, $behavior, $isPreInstantiation, $cId); - $this->getServiceCallsFromArguments(array($iDefinition->getConfigurator()), $calls, $behavior, $isPreInstantiation, $cId); - $this->getServiceCallsFromArguments(array($iDefinition->getFactory()), $calls, $behavior, $isNonLazyShared, $cId); + } + if (!isset($inlinedDefinitions[$definition])) { + $arguments = array($definition->getProperties(), $definition->getMethodCalls(), $definition->getConfigurator()); + $this->getServiceCallsFromArguments($arguments, $calls, false, $cId); } $code = ''; foreach ($calls as $id => $callCount) { - if ('service_container' === $id || $id === $cId) { + if ('service_container' === $id || $id === $cId || isset($this->referenceVariables[$id])) { continue; } - - if ($collectLineage && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE !== $behavior[$id] && $this->container->has($id) - && $this->isTrivialInstance($iDefinition = $this->container->findDefinition($id)) - && $class = is_array($factory = $iDefinition->getFactory()) && is_string($factory[0]) ? $factory[0] : $iDefinition->getClass() - ) { - $this->collectLineage($class, $lineage); + if ($callCount <= 1 && $allCalls[$id] <= 1) { + continue; } - if ($callCount > 1) { - $name = $this->getNextVariableName(); - $this->referenceVariables[$id] = new Variable($name); + $name = $this->getNextVariableName(); + $this->referenceVariables[$id] = new Variable($name); - if (ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE === $behavior[$id]) { - $code .= sprintf($template, $name, $this->getServiceCall($id)); - } else { - $code .= sprintf($template, $name, $this->getServiceCall($id, new Reference($id, $behavior[$id]))); - } - } + $reference = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE === $behavior[$id] ? new Reference($id, $behavior[$id]) : null; + $code .= sprintf(" \$%s = %s;\n", $name, $this->getServiceCall($id, $reference)); } if ('' !== $code) { - if ($isNonLazyShared) { + if ($isPreInstance) { $code .= <<services['$cId'])) { @@ -337,14 +322,6 @@ private function addServiceLocalTempVariables($cId, Definition $definition, arra $code .= "\n"; } - if ($lineage && $lineage = array_diff_key(array_flip($lineage), $this->inlinedRequires)) { - $code = "\n".$code; - - foreach (array_reverse($lineage) as $file => $class) { - $code = sprintf(" require_once %s;\n", $file).$code; - } - } - return $code; } @@ -354,11 +331,6 @@ private function analyzeCircularReferences(array $edges, &$checkedNodes, &$curre $node = $edge->getDestNode(); $id = $node->getId(); - if (isset($checkedNodes[$id])) { - continue; - } - $checkedNodes[$id] = true; - if ($node->getValue() && ($edge->isLazy() || $edge->isWeak())) { // no-op } elseif (isset($currentPath[$id])) { @@ -366,10 +338,11 @@ private function analyzeCircularReferences(array $edges, &$checkedNodes, &$curre $this->circularReferences[$parentId][$id] = $id; $id = $parentId; } - } else { + } elseif (!isset($checkedNodes[$id])) { + $checkedNodes[$id] = true; $currentPath[$id] = $id; $this->analyzeCircularReferences($node->getOutEdges(), $checkedNodes, $currentPath); - array_pop($currentPath); + unset($currentPath[$id]); } } } @@ -429,18 +402,39 @@ private function generateProxyClasses() * * @return string */ - private function addServiceInclude(Definition $definition, array $inlinedDefinitions) + private function addServiceInclude($cId, Definition $definition, \SplObjectStorage $inlinedDefinitions) { - $template = " require_once %s;\n"; $code = ''; - if (null !== $file = $definition->getFile()) { - $code .= sprintf($template, $this->dumpValue($file)); + if ($this->inlineRequires && !$this->isHotPath($definition)) { + $lineage = $calls = $behavior = array(); + foreach ($inlinedDefinitions as $def) { + if (!$def->isDeprecated() && $class = is_array($factory = $def->getFactory()) && is_string($factory[0]) ? $factory[0] : $def->getClass()) { + $this->collectLineage($class, $lineage); + } + $arguments = array($def->getArguments(), $def->getFactory(), $def->getProperties(), $def->getMethodCalls(), $def->getConfigurator()); + $this->getServiceCallsFromArguments($arguments, $calls, false, $cId, $behavior, $inlinedDefinitions[$def]); + } + + foreach ($calls as $id => $callCount) { + if ('service_container' !== $id && $id !== $cId + && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE !== $behavior[$id] + && $this->container->has($id) + && $this->isTrivialInstance($def = $this->container->findDefinition($id)) + && $class = is_array($factory = $def->getFactory()) && is_string($factory[0]) ? $factory[0] : $def->getClass() + ) { + $this->collectLineage($class, $lineage); + } + } + + foreach (array_diff_key(array_flip($lineage), $this->inlinedRequires) as $file => $class) { + $code .= sprintf(" require_once %s;\n", $file); + } } - foreach ($inlinedDefinitions as $definition) { - if (null !== $file = $definition->getFile()) { - $code .= sprintf($template, $this->dumpValue($file)); + foreach ($inlinedDefinitions as $def) { + if ($file = $def->getFile()) { + $code .= sprintf(" require_once %s;\n", $this->dumpValue($file)); } } @@ -454,62 +448,51 @@ private function addServiceInclude(Definition $definition, array $inlinedDefinit /** * Generates the inline definition of a service. * - * @param string $id - * @param array $inlinedDefinitions - * * @return string * * @throws RuntimeException When the factory definition is incomplete * @throws ServiceCircularReferenceException When a circular reference is detected */ - private function addServiceInlinedDefinitions($id, array $inlinedDefinitions) + private function addServiceInlinedDefinitions($id, Definition $definition, \SplObjectStorage $inlinedDefinitions, &$isSimpleInstance) { $code = ''; - $variableMap = $this->definitionVariables; - $nbOccurrences = new \SplObjectStorage(); - $processed = new \SplObjectStorage(); - foreach ($inlinedDefinitions as $definition) { - if (false === $nbOccurrences->contains($definition)) { - $nbOccurrences->offsetSet($definition, 1); - } else { - $i = $nbOccurrences->offsetGet($definition); - $nbOccurrences->offsetSet($definition, $i + 1); + foreach ($inlinedDefinitions as $def) { + if ($definition === $def) { + continue; } - } - - foreach ($inlinedDefinitions as $sDefinition) { - if ($processed->contains($sDefinition)) { + if ($inlinedDefinitions[$def] <= 1 && !$def->getMethodCalls() && !$def->getProperties() && !$def->getConfigurator() && false === strpos($this->dumpValue($def->getClass()), '$')) { continue; } - $processed->offsetSet($sDefinition); - - $class = $this->dumpValue($sDefinition->getClass()); - if ($nbOccurrences->offsetGet($sDefinition) > 1 || $sDefinition->getMethodCalls() || $sDefinition->getProperties() || null !== $sDefinition->getConfigurator() || false !== strpos($class, '$')) { + if (isset($this->definitionVariables[$def])) { + $name = $this->definitionVariables[$def]; + } else { $name = $this->getNextVariableName(); - $variableMap->offsetSet($sDefinition, new Variable($name)); - - // a construct like: - // $a = new ServiceA(ServiceB $b); $b = new ServiceB(ServiceA $a); - // this is an indication for a wrong implementation, you can circumvent this problem - // by setting up your service structure like this: - // $b = new ServiceB(); - // $a = new ServiceA(ServiceB $b); - // $b->setServiceA(ServiceA $a); - if ($this->hasReference($id, $sDefinition->getArguments())) { - throw new ServiceCircularReferenceException($id, array($id)); - } + $this->definitionVariables[$def] = new Variable($name); + } - $code .= $this->addNewInstance($sDefinition, '$'.$name, ' = ', $id); + // a construct like: + // $a = new ServiceA(ServiceB $b); $b = new ServiceB(ServiceA $a); + // this is an indication for a wrong implementation, you can circumvent this problem + // by setting up your service structure like this: + // $b = new ServiceB(); + // $a = new ServiceA(ServiceB $b); + // $b->setServiceA(ServiceA $a); + if ($this->hasReference($id, array($def->getArguments(), $def->getFactory()))) { + throw new ServiceCircularReferenceException($id, array($id)); + } - if (!$this->hasReference($id, $sDefinition->getMethodCalls(), true) && !$this->hasReference($id, $sDefinition->getProperties(), true)) { - $code .= $this->addServiceProperties($sDefinition, $name); - $code .= $this->addServiceMethodCalls($sDefinition, $name); - $code .= $this->addServiceConfigurator($sDefinition, $name); - } + $code .= $this->addNewInstance($def, '$'.$name, ' = ', $id); - $code .= "\n"; + if (!$this->hasReference($id, array($def->getProperties(), $def->getMethodCalls(), $def->getConfigurator()), true)) { + $code .= $this->addServiceProperties($def, $name); + $code .= $this->addServiceMethodCalls($def, $name); + $code .= $this->addServiceConfigurator($def, $name); + } else { + $isSimpleInstance = false; } + + $code .= "\n"; } return $code; @@ -560,29 +543,6 @@ private function addServiceInstance($id, Definition $definition, $isSimpleInstan return $code; } - /** - * Checks if the definition is a simple instance. - * - * @param string $id - * @param Definition $definition - * - * @return bool - */ - private function isSimpleInstance($id, Definition $definition, array $inlinedDefinitions) - { - foreach (array_merge(array($definition), $inlinedDefinitions) as $sDefinition) { - if ($definition !== $sDefinition && !$this->hasReference($id, $sDefinition->getMethodCalls())) { - continue; - } - - if ($sDefinition->getMethodCalls() || $sDefinition->getProperties() || $sDefinition->getConfigurator()) { - return false; - } - } - - return true; - } - /** * Checks if the definition is a trivial instance. * @@ -668,27 +628,17 @@ private function addServiceProperties(Definition $definition, $variableName = 'i /** * Generates the inline definition setup. * - * @param string $id - * @param array $inlinedDefinitions - * @param bool $isSimpleInstance - * * @return string * * @throws ServiceCircularReferenceException when the container contains a circular reference */ - private function addServiceInlinedDefinitionsSetup($id, array $inlinedDefinitions, $isSimpleInstance) + private function addServiceInlinedDefinitionsSetup($id, Definition $definition, \SplObjectStorage $inlinedDefinitions, $isSimpleInstance) { $this->referenceVariables[$id] = new Variable('instance'); $code = ''; - $processed = new \SplObjectStorage(); - foreach ($inlinedDefinitions as $iDefinition) { - if ($processed->contains($iDefinition)) { - continue; - } - $processed->offsetSet($iDefinition); - - if (!$this->hasReference($id, $iDefinition->getMethodCalls(), true) && !$this->hasReference($id, $iDefinition->getProperties(), true)) { + foreach ($inlinedDefinitions as $def) { + if ($definition === $def || !$this->hasReference($id, array($def->getProperties(), $def->getMethodCalls(), $def->getConfigurator()), true)) { continue; } @@ -698,13 +648,13 @@ private function addServiceInlinedDefinitionsSetup($id, array $inlinedDefinition throw new ServiceCircularReferenceException($id, array($id)); } - $name = (string) $this->definitionVariables->offsetGet($iDefinition); - $code .= $this->addServiceProperties($iDefinition, $name); - $code .= $this->addServiceMethodCalls($iDefinition, $name); - $code .= $this->addServiceConfigurator($iDefinition, $name); + $name = (string) $this->definitionVariables[$def]; + $code .= $this->addServiceProperties($def, $name); + $code .= $this->addServiceMethodCalls($def, $name); + $code .= $this->addServiceConfigurator($def, $name); } - if ('' !== $code) { + if ('' !== $code && ($definition->getProperties() || $definition->getMethodCalls() || $definition->getConfigurator())) { $code .= "\n"; } @@ -829,15 +779,28 @@ protected function {$methodName}($lazyInitialization) $code .= sprintf(" @trigger_error(%s, E_USER_DEPRECATED);\n\n", $this->export($definition->getDeprecationMessage($id))); } - $inlinedDefinitions = $this->getInlinedDefinitions($definition); - $isSimpleInstance = $this->isSimpleInstance($id, $definition, $inlinedDefinitions); + $inlinedDefinitions = $this->getDefinitionsFromArguments(array($definition)); + $constructorDefinitions = $this->getDefinitionsFromArguments(array($definition->getArguments(), $definition->getFactory())); + $otherDefinitions = new \SplObjectStorage(); + + foreach ($inlinedDefinitions as $def) { + if ($def === $definition || isset($constructorDefinitions[$def])) { + $constructorDefinitions[$def] = $inlinedDefinitions[$def]; + } else { + $otherDefinitions[$def] = $inlinedDefinitions[$def]; + } + } + + $isSimpleInstance = !$definition->getProperties() && !$definition->getMethodCalls() && !$definition->getConfigurator(); $code .= - $this->addServiceInclude($definition, $inlinedDefinitions). - $this->addServiceLocalTempVariables($id, $definition, $inlinedDefinitions). - $this->addServiceInlinedDefinitions($id, $inlinedDefinitions). + $this->addServiceInclude($id, $definition, $inlinedDefinitions). + $this->addServiceLocalTempVariables($id, $definition, $constructorDefinitions, $inlinedDefinitions). + $this->addServiceInlinedDefinitions($id, $definition, $constructorDefinitions, $isSimpleInstance). $this->addServiceInstance($id, $definition, $isSimpleInstance). - $this->addServiceInlinedDefinitionsSetup($id, $inlinedDefinitions, $isSimpleInstance). + $this->addServiceLocalTempVariables($id, $definition, $otherDefinitions, $inlinedDefinitions). + $this->addServiceInlinedDefinitions($id, $definition, $otherDefinitions, $isSimpleInstance). + $this->addServiceInlinedDefinitionsSetup($id, $definition, $inlinedDefinitions, $isSimpleInstance). $this->addServiceProperties($definition). $this->addServiceMethodCalls($definition). $this->addServiceConfigurator($definition). @@ -1256,11 +1219,10 @@ private function addInlineRequires() foreach ($this->container->findTaggedServiceIds($this->hotPathTag) as $id => $tags) { $definition = $this->container->getDefinition($id); - $inlinedDefinitions = $this->getInlinedDefinitions($definition); - array_unshift($inlinedDefinitions, $definition); + $inlinedDefinitions = $this->getDefinitionsFromArguments(array($definition)); - foreach ($inlinedDefinitions as $iDefinition) { - if ($class = is_array($factory = $iDefinition->getFactory()) && is_string($factory[0]) ? $factory[0] : $iDefinition->getClass()) { + foreach ($inlinedDefinitions as $def) { + if ($class = is_array($factory = $def->getFactory()) && is_string($factory[0]) ? $factory[0] : $def->getClass()) { $this->collectLineage($class, $lineage); } } @@ -1540,16 +1502,16 @@ private function getServiceConditionals($value) /** * Builds service calls from arguments. */ - private function getServiceCallsFromArguments(array $arguments, array &$calls, array &$behavior, $isPreInstantiation, $callerId) + private function getServiceCallsFromArguments(array $arguments, array &$calls, $isPreInstance, $callerId, array &$behavior = array(), $step = 1) { foreach ($arguments as $argument) { if (is_array($argument)) { - $this->getServiceCallsFromArguments($argument, $calls, $behavior, $isPreInstantiation, $callerId); + $this->getServiceCallsFromArguments($argument, $calls, $isPreInstance, $callerId, $behavior, $step); } elseif ($argument instanceof Reference) { $id = (string) $argument; if (!isset($calls[$id])) { - $calls[$id] = (int) ($isPreInstantiation && isset($this->circularReferences[$callerId][$id])); + $calls[$id] = (int) ($isPreInstance && isset($this->circularReferences[$callerId][$id])); } if (!isset($behavior[$id])) { $behavior[$id] = $argument->getInvalidBehavior(); @@ -1557,52 +1519,35 @@ private function getServiceCallsFromArguments(array $arguments, array &$calls, a $behavior[$id] = min($behavior[$id], $argument->getInvalidBehavior()); } - ++$calls[$id]; + $calls[$id] += $step; } } } - /** - * Returns the inline definition. - * - * @return array - */ - private function getInlinedDefinitions(Definition $definition) + private function getDefinitionsFromArguments(array $arguments, \SplObjectStorage $definitions = null) { - if (false === $this->inlinedDefinitions->contains($definition)) { - $definitions = array_merge( - $this->getDefinitionsFromArguments($definition->getArguments()), - $this->getDefinitionsFromArguments($definition->getMethodCalls()), - $this->getDefinitionsFromArguments($definition->getProperties()), - $this->getDefinitionsFromArguments(array($definition->getConfigurator())), - $this->getDefinitionsFromArguments(array($definition->getFactory())) - ); - - $this->inlinedDefinitions->offsetSet($definition, $definitions); - - return $definitions; + if (null === $definitions) { + $definitions = new \SplObjectStorage(); } - return $this->inlinedDefinitions->offsetGet($definition); - } - - /** - * Gets the definition from arguments. - * - * @return array - */ - private function getDefinitionsFromArguments(array $arguments) - { - $definitions = array(); foreach ($arguments as $argument) { if (is_array($argument)) { - $definitions = array_merge($definitions, $this->getDefinitionsFromArguments($argument)); - } elseif ($argument instanceof Definition) { - $definitions = array_merge( - $definitions, - $this->getInlinedDefinitions($argument), - array($argument) - ); + $this->getDefinitionsFromArguments($argument, $definitions); + } elseif (!$argument instanceof Definition) { + // no-op + } elseif (isset($definitions[$argument])) { + $definitions[$argument] = 1 + $definitions[$argument]; + } else { + $definitions[$argument] = 1; + $this->getDefinitionsFromArguments($argument->getArguments(), $definitions); + $this->getDefinitionsFromArguments(array($argument->getFactory()), $definitions); + $this->getDefinitionsFromArguments($argument->getProperties(), $definitions); + $this->getDefinitionsFromArguments($argument->getMethodCalls(), $definitions); + $this->getDefinitionsFromArguments(array($argument->getConfigurator()), $definitions); + // move current definition last in the list + $nbOccurences = $definitions[$argument]; + unset($definitions[$argument]); + $definitions[$argument] = $nbOccurences; } } @@ -1657,9 +1602,7 @@ private function hasReference($id, array $arguments, $deep = false, array &$visi continue; } - $arguments = array_merge($service->getMethodCalls(), $service->getArguments(), $service->getProperties()); - - if ($this->hasReference($id, $arguments, $deep, $visited)) { + if ($this->hasReference($id, array($service->getArguments(), $service->getFactory(), $service->getProperties(), $service->getMethodCalls(), $service->getConfigurator()), $deep, $visited)) { return true; } } @@ -1741,7 +1684,7 @@ private function dumpValue($value, $interpolate = true) } } elseif ($value instanceof Definition) { if (null !== $this->definitionVariables && $this->definitionVariables->contains($value)) { - return $this->dumpValue($this->definitionVariables->offsetGet($value), $interpolate); + return $this->dumpValue($this->definitionVariables[$value], $interpolate); } if ($value->getMethodCalls()) { throw new RuntimeException('Cannot dump definitions which have method calls.'); diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index 0685b9238fbd..bbc2c01ef075 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -1249,24 +1249,26 @@ public function testUninitializedReference() $this->assertEquals(array('foo1' => new \stdClass(), 'foo3' => new \stdClass()), iterator_to_array($bar->iter)); } - public function testAlmostCircularPrivate() + /** + * @dataProvider provideAlmostCircular + */ + public function testAlmostCircular($visibility) { - $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'; + $foo2 = $container->get('foo2'); + $this->assertSame($foo2, $foo2->bar->foobar->foo); - $foo = $container->get('foo'); + $this->assertSame(array(), (array) $container->get('foobar4')); + } - $this->assertSame($foo, $foo->bar->foobar->foo); + public function provideAlmostCircular() + { + yield array('public'); + yield array('private'); } public function testRegisterForAutoconfiguration() diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 4e8da769f427..b70dc7b172b2 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -302,21 +302,6 @@ public function testOverrideServiceWhenUsingADumpedContainer() $this->assertSame($decorator, $container->get('decorator_service'), '->set() overrides an already defined service'); } - /** - * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException - */ - public function testCircularReference() - { - $container = new ContainerBuilder(); - $container->register('foo', 'stdClass')->addArgument(new Reference('bar'))->setPublic(true); - $container->register('bar', 'stdClass')->setPublic(false)->addMethodCall('setA', array(new Reference('baz'))); - $container->register('baz', 'stdClass')->addMethodCall('setA', array(new Reference('foo')))->setPublic(true); - $container->compile(); - - $dumper = new PhpDumper($container); - $dumper->dump(); - } - public function testDumpAutowireData() { $container = include self::$fixturesPath.'/containers/container24.php'; @@ -774,38 +759,35 @@ public function testUninitializedReference() $this->assertEquals(array('foo1' => new \stdClass(), 'foo3' => new \stdClass()), iterator_to_array($bar->iter)); } - public function testAlmostCircularPrivate() + /** + * @dataProvider provideAlmostCircular + */ + public function testAlmostCircular($visibility) { - $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_private.php', $dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_Almost_Circular_Private'))); + $container = 'Symfony_DI_PhpDumper_Test_Almost_Circular_'.ucfirst($visibility); + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_almost_circular_'.$visibility.'.php', $dumper->dump(array('class' => $container))); - require self::$fixturesPath.'/php/container_almost_circular_private.php'; + require self::$fixturesPath.'/php/services_almost_circular_'.$visibility.'.php'; - $container = new \Symfony_DI_PhpDumper_Test_Almost_Circular_Private(); - $foo = $container->get('foo'); + $container = new $container(); + $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); + $foo2 = $container->get('foo2'); + $this->assertSame($foo2, $foo2->bar->foobar->foo); - $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(array(), (array) $container->get('foobar4')); + } - $this->assertSame($foo, $foo->bar->foobar->foo); + public function provideAlmostCircular() + { + yield array('public'); + yield array('private'); } public function testHotPathOptimizations() @@ -815,12 +797,12 @@ public function testHotPathOptimizations() $container->compile(); $dumper = new PhpDumper($container); - $dump = $dumper->dump(array('hot_path_tag' => 'container.hot_path', 'inline_class_loader_parameter' => 'inline_requires', 'file' => self::$fixturesPath.'/php/container_inline_requires.php')); + $dump = $dumper->dump(array('hot_path_tag' => 'container.hot_path', 'inline_class_loader_parameter' => 'inline_requires', 'file' => self::$fixturesPath.'/php/services_inline_requires.php')); if ('\\' === DIRECTORY_SEPARATOR) { $dump = str_replace("'\\\\includes\\\\HotPath\\\\", "'/includes/HotPath/", $dump); } - $this->assertStringEqualsFile(self::$fixturesPath.'/php/container_inline_requires.php', $dump); + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_inline_requires.php', $dump); } public function testDumpHandlesLiteralClassWithRootNamespace() 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 eaef674a3ec5..6d73b3ec6c77 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 @@ -5,8 +5,11 @@ use Symfony\Component\DependencyInjection\Dumper\PhpDumper; use Symfony\Component\DependencyInjection\Reference; +$public = 'public' === $visibility; $container = new ContainerBuilder(); +// same visibility for deps + $container->register('foo', FooCircular::class)->setPublic(true) ->addArgument(new Reference('bar')); @@ -16,4 +19,31 @@ $container->register('foobar', FoobarCircular::class)->setPublic($public) ->addArgument(new Reference('foo')); +// mixed visibility for deps + +$container->register('foo2', FooCircular::class)->setPublic(true) + ->addArgument(new Reference('bar2')); + +$container->register('bar2', BarCircular::class)->setPublic(!$public) + ->addMethodCall('addFoobar', array(new Reference('foobar2'))); + +$container->register('foobar2', FoobarCircular::class)->setPublic($public) + ->addArgument(new Reference('foo2')); + +// simple inline setter with internal reference + +$container->register('bar3', BarCircular::class)->setPublic(true) + ->addMethodCall('addFoobar', array(new Reference('foobar3'), new Reference('foobar3'))); + +$container->register('foobar3', FoobarCircular::class)->setPublic($public); + +// loop with non-shared dep + +$container->register('foo4', 'stdClass')->setPublic($public) + ->setShared(false) + ->setProperty('foobar', new Reference('foobar4')); + +$container->register('foobar4', 'stdClass')->setPublic(true) + ->addArgument(new Reference('foo4')); + return $container; diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt index 8c76d4c7636f..6724846f8dd8 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt @@ -33,11 +33,11 @@ use Symfony\Component\DependencyInjection\Argument\RewindableGenerator; // This file has been auto-generated by the Symfony Dependency Injection Component for internal use. // Returns the public 'configured_service' shared service. +$this->services['configured_service'] = $instance = new \stdClass(); + $a = new \ConfClass(); $a->setFoo(${($_ = isset($this->services['baz']) ? $this->services['baz'] : $this->load(__DIR__.'/getBazService.php')) && false ?: '_'}); -$this->services['configured_service'] = $instance = new \stdClass(); - $a->configureStdClass($instance); return $instance; @@ -153,10 +153,10 @@ use Symfony\Component\DependencyInjection\Argument\RewindableGenerator; // This file has been auto-generated by the Symfony Dependency Injection Component for internal use. // Returns the public 'foo_with_inline' shared service. -$a = new \Bar(); - $this->services['foo_with_inline'] = $instance = new \Foo(); +$a = new \Bar(); + $a->pub = 'pub'; $a->setBaz(${($_ = isset($this->services['baz']) ? $this->services['baz'] : $this->load(__DIR__.'/getBazService.php')) && false ?: '_'}); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php index 403eb12954fe..ec0db041f438 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php @@ -129,11 +129,11 @@ protected function getBazService() */ protected function getConfiguredServiceService() { + $this->services['configured_service'] = $instance = new \stdClass(); + $a = new \ConfClass(); $a->setFoo(${($_ = isset($this->services['baz']) ? $this->services['baz'] : $this->getBazService()) && false ?: '_'}); - $this->services['configured_service'] = $instance = new \stdClass(); - $a->configureStdClass($instance); return $instance; @@ -259,10 +259,10 @@ protected function getFooBarService() */ protected function getFooWithInlineService() { - $a = new \Bar(); - $this->services['foo_with_inline'] = $instance = new \Foo(); + $a = new \Bar(); + $a->pub = 'pub'; $a->setBaz(${($_ = isset($this->services['baz']) ? $this->services['baz'] : $this->getBazService()) && false ?: '_'}); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/container_almost_circular_private.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php similarity index 53% rename from src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/container_almost_circular_private.php rename to src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php index 055f409a5318..1707f8912781 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/container_almost_circular_private.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php @@ -23,7 +23,11 @@ public function __construct() { $this->services = array(); $this->methodMap = array( + 'bar2' => 'getBar2Service', + 'bar3' => 'getBar3Service', 'foo' => 'getFooService', + 'foo2' => 'getFoo2Service', + 'foobar4' => 'getFoobar4Service', ); $this->aliases = array(); @@ -35,7 +39,10 @@ public function getRemovedIds() 'Psr\\Container\\ContainerInterface' => true, 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, 'bar' => true, + 'foo4' => true, 'foobar' => true, + 'foobar2' => true, + 'foobar3' => true, ); } @@ -56,6 +63,36 @@ public function isFrozen() return true; } + /** + * Gets the public 'bar2' shared service. + * + * @return \BarCircular + */ + protected function getBar2Service() + { + $this->services['bar2'] = $instance = new \BarCircular(); + + $instance->addFoobar(new \FoobarCircular(${($_ = isset($this->services['foo2']) ? $this->services['foo2'] : $this->getFoo2Service()) && false ?: '_'})); + + return $instance; + } + + /** + * Gets the public 'bar3' shared service. + * + * @return \BarCircular + */ + protected function getBar3Service() + { + $this->services['bar3'] = $instance = new \BarCircular(); + + $a = new \FoobarCircular(); + + $instance->addFoobar($a, $a); + + return $instance; + } + /** * Gets the public 'foo' shared service. * @@ -69,6 +106,37 @@ protected function getFooService() $a->addFoobar(new \FoobarCircular($instance)); + return $instance; + } + + /** + * Gets the public 'foo2' shared service. + * + * @return \FooCircular + */ + protected function getFoo2Service() + { + $a = ${($_ = isset($this->services['bar2']) ? $this->services['bar2'] : $this->getBar2Service()) && false ?: '_'}; + + if (isset($this->services['foo2'])) { + return $this->services['foo2']; + } + + return $this->services['foo2'] = new \FooCircular($a); + } + + /** + * Gets the public 'foobar4' shared service. + * + * @return \stdClass + */ + protected function getFoobar4Service() + { + $a = new \stdClass(); + + $this->services['foobar4'] = $instance = new \stdClass($a); + + $a->foobar = $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/services_almost_circular_public.php similarity index 54% rename from src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/container_almost_circular_public.php rename to src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php index 5c4057d7fa1a..5d4d9b0f29cf 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/container_almost_circular_public.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php @@ -24,8 +24,14 @@ public function __construct() $this->services = array(); $this->methodMap = array( 'bar' => 'getBarService', + 'bar3' => 'getBar3Service', 'foo' => 'getFooService', + 'foo2' => 'getFoo2Service', + 'foo4' => 'getFoo4Service', 'foobar' => 'getFoobarService', + 'foobar2' => 'getFoobar2Service', + 'foobar3' => 'getFoobar3Service', + 'foobar4' => 'getFoobar4Service', ); $this->aliases = array(); @@ -36,6 +42,7 @@ public function getRemovedIds() return array( 'Psr\\Container\\ContainerInterface' => true, 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + 'bar2' => true, ); } @@ -70,6 +77,22 @@ protected function getBarService() return $instance; } + /** + * Gets the public 'bar3' shared service. + * + * @return \BarCircular + */ + protected function getBar3Service() + { + $this->services['bar3'] = $instance = new \BarCircular(); + + $a = ${($_ = isset($this->services['foobar3']) ? $this->services['foobar3'] : $this->services['foobar3'] = new \FoobarCircular()) && false ?: '_'}; + + $instance->addFoobar($a, $a); + + return $instance; + } + /** * Gets the public 'foo' shared service. * @@ -86,6 +109,36 @@ protected function getFooService() return $this->services['foo'] = new \FooCircular($a); } + /** + * Gets the public 'foo2' shared service. + * + * @return \FooCircular + */ + protected function getFoo2Service() + { + $a = new \BarCircular(); + + $this->services['foo2'] = $instance = new \FooCircular($a); + + $a->addFoobar(${($_ = isset($this->services['foobar2']) ? $this->services['foobar2'] : $this->getFoobar2Service()) && false ?: '_'}); + + return $instance; + } + + /** + * Gets the public 'foo4' service. + * + * @return \stdClass + */ + protected function getFoo4Service() + { + $instance = new \stdClass(); + + $instance->foobar = ${($_ = isset($this->services['foobar4']) ? $this->services['foobar4'] : $this->getFoobar4Service()) && false ?: '_'}; + + return $instance; + } + /** * Gets the public 'foobar' shared service. * @@ -101,4 +154,46 @@ protected function getFoobarService() return $this->services['foobar'] = new \FoobarCircular($a); } + + /** + * Gets the public 'foobar2' shared service. + * + * @return \FoobarCircular + */ + protected function getFoobar2Service() + { + $a = ${($_ = isset($this->services['foo2']) ? $this->services['foo2'] : $this->getFoo2Service()) && false ?: '_'}; + + if (isset($this->services['foobar2'])) { + return $this->services['foobar2']; + } + + return $this->services['foobar2'] = new \FoobarCircular($a); + } + + /** + * Gets the public 'foobar3' shared service. + * + * @return \FoobarCircular + */ + protected function getFoobar3Service() + { + return $this->services['foobar3'] = new \FoobarCircular(); + } + + /** + * Gets the public 'foobar4' shared service. + * + * @return \stdClass + */ + protected function getFoobar4Service() + { + $a = new \stdClass(); + + $this->services['foobar4'] = $instance = new \stdClass($a); + + $a->foobar = $instance; + + return $instance; + } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/container_inline_requires.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_inline_requires.php similarity index 100% rename from src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/container_inline_requires.php rename to src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_inline_requires.php diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_locator.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_locator.php index f7e751113cfd..cd8456be3afc 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_locator.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_locator.php @@ -159,12 +159,12 @@ protected function getTranslator2Service() */ protected function getTranslator3Service() { - $a = ${($_ = isset($this->services['translator.loader_3']) ? $this->services['translator.loader_3'] : $this->services['translator.loader_3'] = new \stdClass()) && false ?: '_'}; - $this->services['translator_3'] = $instance = new \Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator(new \Symfony\Component\DependencyInjection\ServiceLocator(array('translator.loader_3' => function () { return ${($_ = isset($this->services['translator.loader_3']) ? $this->services['translator.loader_3'] : $this->services['translator.loader_3'] = new \stdClass()) && false ?: '_'}; }))); + $a = ${($_ = isset($this->services['translator.loader_3']) ? $this->services['translator.loader_3'] : $this->services['translator.loader_3'] = new \stdClass()) && false ?: '_'}; + $instance->addResource('db', $a, 'nl'); $instance->addResource('db', $a, 'en');