Merge branch '3.4' into 4.0
* 3.4: [DI] Fix circular reference when using setters [DI] Clear service reference graph
This commit is contained in:
commit
ff87b4c939
@ -113,6 +113,8 @@ class Compiler
|
||||
}
|
||||
|
||||
throw $e;
|
||||
} finally {
|
||||
$this->getServiceReferenceGraph()->clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,9 @@ class ServiceReferenceGraph
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
foreach ($this->nodes as $node) {
|
||||
$node->clear();
|
||||
}
|
||||
$this->nodes = array();
|
||||
}
|
||||
|
||||
|
@ -107,4 +107,12 @@ class ServiceReferenceGraphNode
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all edges.
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->inEdges = $this->outEdges = array();
|
||||
}
|
||||
}
|
||||
|
@ -519,6 +519,14 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
*/
|
||||
public function get($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE)
|
||||
{
|
||||
return $this->doGet($id, $invalidBehavior);
|
||||
}
|
||||
|
||||
private function doGet($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, array &$inlineServices = array())
|
||||
{
|
||||
if (isset($inlineServices[$id])) {
|
||||
return $inlineServices[$id];
|
||||
}
|
||||
if (ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $invalidBehavior) {
|
||||
return parent::get($id, $invalidBehavior);
|
||||
}
|
||||
@ -527,7 +535,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
}
|
||||
|
||||
if (!isset($this->definitions[$id]) && isset($this->aliasDefinitions[$id])) {
|
||||
return $this->get((string) $this->aliasDefinitions[$id], $invalidBehavior);
|
||||
return $this->doGet((string) $this->aliasDefinitions[$id], $invalidBehavior, $inlineServices);
|
||||
}
|
||||
|
||||
try {
|
||||
@ -544,7 +552,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
$this->{$loading}[$id] = true;
|
||||
|
||||
try {
|
||||
$service = $this->createService($definition, new \SplObjectStorage(), $id);
|
||||
$service = $this->createService($definition, $inlineServices, $id);
|
||||
} finally {
|
||||
unset($this->{$loading}[$id]);
|
||||
}
|
||||
@ -978,10 +986,10 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
* @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) {
|
||||
@ -1002,11 +1010,11 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
->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;
|
||||
}
|
||||
@ -1017,7 +1025,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
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];
|
||||
@ -1025,7 +1033,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
|
||||
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));
|
||||
}
|
||||
@ -1051,16 +1059,16 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
|
||||
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()) {
|
||||
@ -1068,9 +1076,9 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
$callable[0] = $parameterBag->resolveValue($callable[0]);
|
||||
|
||||
if ($callable[0] instanceof Reference) {
|
||||
$callable[0] = $this->get((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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1094,14 +1102,14 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
*/
|
||||
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];
|
||||
@ -1117,7 +1125,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
}
|
||||
}
|
||||
foreach (self::getInitializedConditionals($v) as $s) {
|
||||
if (!$this->get($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE)) {
|
||||
if (!$this->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE)) {
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
@ -1133,7 +1141,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
}
|
||||
}
|
||||
foreach (self::getInitializedConditionals($v) as $s) {
|
||||
if (!$this->get($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE)) {
|
||||
if (!$this->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE)) {
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
@ -1144,9 +1152,9 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
return $count;
|
||||
});
|
||||
} elseif ($value instanceof Reference) {
|
||||
$value = $this->get((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));
|
||||
}
|
||||
@ -1443,7 +1451,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
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)) {
|
||||
@ -1451,12 +1459,12 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
}
|
||||
}
|
||||
foreach (self::getInitializedConditionals($call[1]) as $s) {
|
||||
if (!$this->get($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));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1466,14 +1474,11 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
* @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]);
|
||||
}
|
||||
|
@ -52,7 +52,6 @@ class PhpDumper extends Dumper
|
||||
*/
|
||||
const NON_FIRST_CHARS = 'abcdefghijklmnopqrstuvwxyz0123456789_';
|
||||
|
||||
private $inlinedDefinitions;
|
||||
private $definitionVariables;
|
||||
private $referenceVariables;
|
||||
private $variableCount;
|
||||
@ -85,8 +84,6 @@ class PhpDumper extends Dumper
|
||||
}
|
||||
|
||||
parent::__construct($container);
|
||||
|
||||
$this->inlinedDefinitions = new \SplObjectStorage();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -143,6 +140,7 @@ class PhpDumper extends Dumper
|
||||
$currentPath = array($id => $id);
|
||||
$this->analyzeCircularReferences($node->getOutEdges(), $checkedNodes, $currentPath);
|
||||
}
|
||||
$this->container->getCompiler()->getServiceReferenceGraph()->clear();
|
||||
|
||||
$this->docStar = $options['debug'] ? '*' : '';
|
||||
|
||||
@ -272,54 +270,46 @@ EOF;
|
||||
return $this->proxyDumper;
|
||||
}
|
||||
|
||||
private function addServiceLocalTempVariables(string $cId, Definition $definition, array $inlinedDefinitions): string
|
||||
private function addServiceLocalTempVariables(string $cId, Definition $definition, \SplObjectStorage $inlinedDefinitions, \SplObjectStorage $allInlinedDefinitions): string
|
||||
{
|
||||
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 ($callCount <= 1 && $allCalls[$id] <= 1) {
|
||||
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);
|
||||
}
|
||||
$name = $this->getNextVariableName();
|
||||
$this->referenceVariables[$id] = new Variable($name);
|
||||
|
||||
if ($callCount > 1) {
|
||||
$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 .= sprintf(<<<'EOTXT'
|
||||
|
||||
if (isset($this->%s['%s'])) {
|
||||
@ -333,14 +323,6 @@ EOTXT
|
||||
$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;
|
||||
}
|
||||
|
||||
@ -350,11 +332,6 @@ EOTXT
|
||||
$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])) {
|
||||
@ -362,10 +339,11 @@ EOTXT
|
||||
$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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -420,18 +398,39 @@ EOTXT
|
||||
}
|
||||
}
|
||||
|
||||
private function addServiceInclude(Definition $definition, array $inlinedDefinitions): string
|
||||
private function addServiceInclude(string $cId, Definition $definition, \SplObjectStorage $inlinedDefinitions): string
|
||||
{
|
||||
$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));
|
||||
}
|
||||
}
|
||||
|
||||
@ -448,54 +447,46 @@ EOTXT
|
||||
* @throws RuntimeException When the factory definition is incomplete
|
||||
* @throws ServiceCircularReferenceException When a circular reference is detected
|
||||
*/
|
||||
private function addServiceInlinedDefinitions(string $id, array $inlinedDefinitions): string
|
||||
private function addServiceInlinedDefinitions(string $id, Definition $definition, \SplObjectStorage $inlinedDefinitions, bool &$isSimpleInstance): string
|
||||
{
|
||||
$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 $sDefinition) {
|
||||
if ($processed->contains($sDefinition)) {
|
||||
foreach ($inlinedDefinitions as $def) {
|
||||
if ($definition === $def) {
|
||||
continue;
|
||||
}
|
||||
$processed->offsetSet($sDefinition);
|
||||
|
||||
$class = $this->dumpValue($sDefinition->getClass());
|
||||
if ($nbOccurrences->offsetGet($sDefinition) > 1 || $sDefinition->getMethodCalls() || $sDefinition->getProperties() || null !== $sDefinition->getConfigurator() || false !== strpos($class, '$')) {
|
||||
$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));
|
||||
}
|
||||
|
||||
$code .= $this->addNewInstance($sDefinition, '$'.$name, ' = ', $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 .= "\n";
|
||||
if ($inlinedDefinitions[$def] <= 1 && !$def->getMethodCalls() && !$def->getProperties() && !$def->getConfigurator() && false === strpos($this->dumpValue($def->getClass()), '$')) {
|
||||
continue;
|
||||
}
|
||||
if (isset($this->definitionVariables[$def])) {
|
||||
$name = $this->definitionVariables[$def];
|
||||
} else {
|
||||
$name = $this->getNextVariableName();
|
||||
$this->definitionVariables[$def] = 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, array($def->getArguments(), $def->getFactory()))) {
|
||||
throw new ServiceCircularReferenceException($id, array($id));
|
||||
}
|
||||
|
||||
$code .= $this->addNewInstance($def, '$'.$name, ' = ', $id);
|
||||
|
||||
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;
|
||||
@ -538,21 +529,6 @@ EOTXT
|
||||
return $code;
|
||||
}
|
||||
|
||||
private function isSimpleInstance(string $id, Definition $definition, array $inlinedDefinitions): bool
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
private function isTrivialInstance(Definition $definition): bool
|
||||
{
|
||||
if ($definition->isSynthetic() || $definition->getFile() || $definition->getMethodCalls() || $definition->getProperties() || $definition->getConfigurator()) {
|
||||
@ -623,19 +599,13 @@ EOTXT
|
||||
/**
|
||||
* @throws ServiceCircularReferenceException when the container contains a circular reference
|
||||
*/
|
||||
private function addServiceInlinedDefinitionsSetup(string $id, array $inlinedDefinitions, bool $isSimpleInstance): string
|
||||
private function addServiceInlinedDefinitionsSetup(string $id, Definition $definition, \SplObjectStorage $inlinedDefinitions, bool $isSimpleInstance): string
|
||||
{
|
||||
$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;
|
||||
}
|
||||
|
||||
@ -645,13 +615,13 @@ EOTXT
|
||||
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";
|
||||
}
|
||||
|
||||
@ -759,15 +729,28 @@ EOF;
|
||||
$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).
|
||||
@ -1085,11 +1068,10 @@ EOF;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -1298,16 +1280,16 @@ EOF;
|
||||
return implode(' && ', $conditions);
|
||||
}
|
||||
|
||||
private function getServiceCallsFromArguments(array $arguments, array &$calls, array &$behavior, bool $isPreInstantiation, string $callerId)
|
||||
private function getServiceCallsFromArguments(array $arguments, array &$calls, bool $isPreInstance, string $callerId, array &$behavior = array(), int $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();
|
||||
@ -1315,42 +1297,35 @@ EOF;
|
||||
$behavior[$id] = min($behavior[$id], $argument->getInvalidBehavior());
|
||||
}
|
||||
|
||||
++$calls[$id];
|
||||
$calls[$id] += $step;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getInlinedDefinitions(Definition $definition): array
|
||||
private function getDefinitionsFromArguments(array $arguments, \SplObjectStorage $definitions = null): \SplObjectStorage
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
private function getDefinitionsFromArguments(array $arguments): array
|
||||
{
|
||||
$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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1395,9 +1370,7 @@ EOF;
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -1473,7 +1446,7 @@ EOF;
|
||||
}
|
||||
} 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.');
|
||||
|
@ -1223,24 +1223,26 @@ class ContainerBuilderTest extends TestCase
|
||||
$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);
|
||||
|
||||
$foo2 = $container->get('foo2');
|
||||
$this->assertSame($foo2, $foo2->bar->foobar->foo);
|
||||
|
||||
$this->assertSame(array(), (array) $container->get('foobar4'));
|
||||
}
|
||||
|
||||
public function testAlmostCircularPublic()
|
||||
public function provideAlmostCircular()
|
||||
{
|
||||
$public = true;
|
||||
$container = include __DIR__.'/Fixtures/containers/container_almost_circular.php';
|
||||
|
||||
$foo = $container->get('foo');
|
||||
|
||||
$this->assertSame($foo, $foo->bar->foobar->foo);
|
||||
yield array('public');
|
||||
yield array('private');
|
||||
}
|
||||
|
||||
public function testRegisterForAutoconfiguration()
|
||||
|
@ -301,21 +301,6 @@ class PhpDumperTest extends TestCase
|
||||
$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';
|
||||
@ -773,38 +758,35 @@ class PhpDumperTest extends TestCase
|
||||
$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 $container();
|
||||
|
||||
$container = new \Symfony_DI_PhpDumper_Test_Almost_Circular_Private();
|
||||
$foo = $container->get('foo');
|
||||
|
||||
$this->assertSame($foo, $foo->bar->foobar->foo);
|
||||
|
||||
$foo2 = $container->get('foo2');
|
||||
$this->assertSame($foo2, $foo2->bar->foobar->foo);
|
||||
|
||||
$this->assertSame(array(), (array) $container->get('foobar4'));
|
||||
}
|
||||
|
||||
public function testAlmostCircularPublic()
|
||||
public function provideAlmostCircular()
|
||||
{
|
||||
$public = true;
|
||||
$container = include self::$fixturesPath.'/containers/container_almost_circular.php';
|
||||
$container->compile();
|
||||
$dumper = new PhpDumper($container);
|
||||
|
||||
$this->assertStringEqualsFile(self::$fixturesPath.'/php/container_almost_circular_public.php', $dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_Almost_Circular_Public')));
|
||||
|
||||
require self::$fixturesPath.'/php/container_almost_circular_public.php';
|
||||
|
||||
$container = new \Symfony_DI_PhpDumper_Test_Almost_Circular_Public();
|
||||
$foo = $container->get('foo');
|
||||
|
||||
$this->assertSame($foo, $foo->bar->foobar->foo);
|
||||
yield array('public');
|
||||
yield array('private');
|
||||
}
|
||||
|
||||
public function testHotPathOptimizations()
|
||||
@ -814,12 +796,12 @@ class PhpDumperTest extends TestCase
|
||||
$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()
|
||||
|
@ -5,8 +5,11 @@ use Symfony\Component\DependencyInjection\Definition;
|
||||
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('bar', BarCircular::class)->setPublic($public)
|
||||
$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;
|
||||
|
@ -66,11 +66,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(($this->services['baz'] ?? $this->load(__DIR__.'/getBazService.php')));
|
||||
|
||||
$this->services['configured_service'] = $instance = new \stdClass();
|
||||
|
||||
$a->configureStdClass($instance);
|
||||
|
||||
return $instance;
|
||||
@ -186,10 +186,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(($this->services['baz'] ?? $this->load(__DIR__.'/getBazService.php')));
|
||||
|
||||
|
@ -162,11 +162,11 @@ class ProjectServiceContainer extends Container
|
||||
*/
|
||||
protected function getConfiguredServiceService()
|
||||
{
|
||||
$this->services['configured_service'] = $instance = new \stdClass();
|
||||
|
||||
$a = new \ConfClass();
|
||||
$a->setFoo(($this->services['baz'] ?? $this->getBazService()));
|
||||
|
||||
$this->services['configured_service'] = $instance = new \stdClass();
|
||||
|
||||
$a->configureStdClass($instance);
|
||||
|
||||
return $instance;
|
||||
@ -292,10 +292,10 @@ class ProjectServiceContainer extends Container
|
||||
*/
|
||||
protected function getFooWithInlineService()
|
||||
{
|
||||
$a = new \Bar();
|
||||
|
||||
$this->services['foo_with_inline'] = $instance = new \Foo();
|
||||
|
||||
$a = new \Bar();
|
||||
|
||||
$a->pub = 'pub';
|
||||
$a->setBaz(($this->services['baz'] ?? $this->getBazService()));
|
||||
|
||||
|
@ -24,7 +24,11 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Private extends Container
|
||||
{
|
||||
$this->services = $this->privates = array();
|
||||
$this->methodMap = array(
|
||||
'bar2' => 'getBar2Service',
|
||||
'bar3' => 'getBar3Service',
|
||||
'foo' => 'getFooService',
|
||||
'foo2' => 'getFoo2Service',
|
||||
'foobar4' => 'getFoobar4Service',
|
||||
);
|
||||
|
||||
$this->aliases = array();
|
||||
@ -52,10 +56,43 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Private extends Container
|
||||
'Psr\\Container\\ContainerInterface' => true,
|
||||
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
|
||||
'bar' => true,
|
||||
'foo4' => true,
|
||||
'foobar' => true,
|
||||
'foobar2' => true,
|
||||
'foobar3' => true,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the public 'bar2' shared service.
|
||||
*
|
||||
* @return \BarCircular
|
||||
*/
|
||||
protected function getBar2Service()
|
||||
{
|
||||
$this->services['bar2'] = $instance = new \BarCircular();
|
||||
|
||||
$instance->addFoobar(new \FoobarCircular(($this->services['foo2'] ?? $this->getFoo2Service())));
|
||||
|
||||
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 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Private extends Container
|
||||
|
||||
$a->addFoobar(new \FoobarCircular($instance));
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the public 'foo2' shared service.
|
||||
*
|
||||
* @return \FooCircular
|
||||
*/
|
||||
protected function getFoo2Service()
|
||||
{
|
||||
$a = ($this->services['bar2'] ?? $this->getBar2Service());
|
||||
|
||||
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;
|
||||
}
|
@ -25,8 +25,14 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Public extends Container
|
||||
$this->services = $this->privates = 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();
|
||||
@ -53,6 +59,7 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Public extends Container
|
||||
return array(
|
||||
'Psr\\Container\\ContainerInterface' => true,
|
||||
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
|
||||
'bar2' => true,
|
||||
);
|
||||
}
|
||||
|
||||
@ -70,6 +77,22 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Public extends Container
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the public 'bar3' shared service.
|
||||
*
|
||||
* @return \BarCircular
|
||||
*/
|
||||
protected function getBar3Service()
|
||||
{
|
||||
$this->services['bar3'] = $instance = new \BarCircular();
|
||||
|
||||
$a = ($this->services['foobar3'] ?? $this->services['foobar3'] = new \FoobarCircular());
|
||||
|
||||
$instance->addFoobar($a, $a);
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the public 'foo' shared service.
|
||||
*
|
||||
@ -86,6 +109,36 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Public extends Container
|
||||
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(($this->services['foobar2'] ?? $this->getFoobar2Service()));
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the public 'foo4' service.
|
||||
*
|
||||
* @return \stdClass
|
||||
*/
|
||||
protected function getFoo4Service()
|
||||
{
|
||||
$instance = new \stdClass();
|
||||
|
||||
$instance->foobar = ($this->services['foobar4'] ?? $this->getFoobar4Service());
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the public 'foobar' shared service.
|
||||
*
|
||||
@ -101,4 +154,46 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Public extends Container
|
||||
|
||||
return $this->services['foobar'] = new \FoobarCircular($a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the public 'foobar2' shared service.
|
||||
*
|
||||
* @return \FoobarCircular
|
||||
*/
|
||||
protected function getFoobar2Service()
|
||||
{
|
||||
$a = ($this->services['foo2'] ?? $this->getFoo2Service());
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -95,8 +95,8 @@ class ProjectServiceContainer extends Container
|
||||
*/
|
||||
protected function getC2Service()
|
||||
{
|
||||
require_once $this->targetDirs[1].'/includes/HotPath/C2.php';
|
||||
require_once $this->targetDirs[1].'/includes/HotPath/C3.php';
|
||||
require_once $this->targetDirs[1].'/includes/HotPath/C2.php';
|
||||
|
||||
return $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C2'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C2(new \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C3());
|
||||
}
|
@ -156,12 +156,12 @@ class ProjectServiceContainer extends Container
|
||||
*/
|
||||
protected function getTranslator3Service()
|
||||
{
|
||||
$a = ($this->services['translator.loader_3'] ?? $this->services['translator.loader_3'] = new \stdClass());
|
||||
|
||||
$this->services['translator_3'] = $instance = new \Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator(new \Symfony\Component\DependencyInjection\ServiceLocator(array('translator.loader_3' => function () {
|
||||
return ($this->services['translator.loader_3'] ?? $this->services['translator.loader_3'] = new \stdClass());
|
||||
})));
|
||||
|
||||
$a = ($this->services['translator.loader_3'] ?? $this->services['translator.loader_3'] = new \stdClass());
|
||||
|
||||
$instance->addResource('db', $a, 'nl');
|
||||
$instance->addResource('db', $a, 'en');
|
||||
|
||||
|
Reference in New Issue
Block a user