Mercurial > hg > cmmr2012-drupal-site
diff vendor/symfony/dependency-injection/Dumper/PhpDumper.php @ 4:a9cd425dd02b
Update, including to Drupal core 8.6.10
author | Chris Cannam |
---|---|
date | Thu, 28 Feb 2019 13:11:55 +0000 |
parents | 5311817fb629 |
children | 12f9dff5fda9 |
line wrap: on
line diff
--- a/vendor/symfony/dependency-injection/Dumper/PhpDumper.php Thu Feb 28 11:14:44 2019 +0000 +++ b/vendor/symfony/dependency-injection/Dumper/PhpDumper.php Thu Feb 28 13:11:55 2019 +0000 @@ -14,22 +14,23 @@ use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; use Symfony\Component\DependencyInjection\Argument\IteratorArgument; use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; -use Symfony\Component\DependencyInjection\Variable; +use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass; +use Symfony\Component\DependencyInjection\Compiler\CheckCircularReferencesPass; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Definition; -use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Container; -use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\DependencyInjection\Reference; -use Symfony\Component\DependencyInjection\TypedReference; -use Symfony\Component\DependencyInjection\Parameter; use Symfony\Component\DependencyInjection\Exception\EnvParameterException; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Exception\RuntimeException; use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use Symfony\Component\DependencyInjection\ExpressionLanguage; use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface as ProxyDumper; use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\NullDumper; -use Symfony\Component\DependencyInjection\ExpressionLanguage; +use Symfony\Component\DependencyInjection\Parameter; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\TypedReference; +use Symfony\Component\DependencyInjection\Variable; use Symfony\Component\ExpressionLanguage\Expression; use Symfony\Component\HttpKernel\Kernel; @@ -54,7 +55,9 @@ private $definitionVariables; private $referenceVariables; private $variableCount; - private $reservedVariables = array('instance', 'class'); + private $inlinedDefinitions; + private $serviceCalls; + private $reservedVariables = ['instance', 'class', 'this']; private $expressionLanguage; private $targetDirRegex; private $targetDirMaxMatches; @@ -65,8 +68,8 @@ private $asFiles; private $hotPathTag; private $inlineRequires; - private $inlinedRequires = array(); - private $circularReferences = array(); + private $inlinedRequires = []; + private $circularReferences = []; /** * @var ProxyDumper @@ -107,11 +110,11 @@ * * @throws EnvParameterException When an env var exists but has not been dumped */ - public function dump(array $options = array()) + public function dump(array $options = []) { $this->targetDirRegex = null; - $this->inlinedRequires = array(); - $options = array_merge(array( + $this->inlinedRequires = []; + $options = array_merge([ 'class' => 'ProjectServiceContainer', 'base_class' => 'Container', 'namespace' => '', @@ -120,7 +123,7 @@ 'hot_path_tag' => 'container.hot_path', 'inline_class_loader_parameter' => 'container.dumper.inline_class_loader', 'build_time' => time(), - ), $options); + ], $options); $this->namespace = $options['namespace']; $this->asFiles = $options['as_files']; @@ -138,24 +141,42 @@ $this->initializeMethodNamesMap('Container' === $baseClass ? Container::class : $baseClass); - (new AnalyzeServiceReferencesPass())->process($this->container); - $this->circularReferences = array(); - $checkedNodes = array(); + if ($this->getProxyDumper() instanceof NullDumper) { + (new AnalyzeServiceReferencesPass(true, false))->process($this->container); + try { + (new CheckCircularReferencesPass())->process($this->container); + } catch (ServiceCircularReferenceException $e) { + $path = $e->getPath(); + end($path); + $path[key($path)] .= '". Try running "composer require symfony/proxy-manager-bridge'; + + throw new ServiceCircularReferenceException($e->getServiceId(), $path); + } + } + + (new AnalyzeServiceReferencesPass(false, !$this->getProxyDumper() instanceof NullDumper))->process($this->container); + $checkedNodes = []; + $this->circularReferences = []; foreach ($this->container->getCompiler()->getServiceReferenceGraph()->getNodes() as $id => $node) { - $currentPath = array($id => $id); - $this->analyzeCircularReferences($node->getOutEdges(), $checkedNodes, $currentPath); + if (!$node->getValue() instanceof Definition) { + continue; + } + if (!isset($checkedNodes[$id])) { + $this->analyzeCircularReferences($id, $node->getOutEdges(), $checkedNodes); + } } $this->container->getCompiler()->getServiceReferenceGraph()->clear(); + $checkedNodes = []; $this->docStar = $options['debug'] ? '*' : ''; - if (!empty($options['file']) && is_dir($dir = dirname($options['file']))) { + if (!empty($options['file']) && is_dir($dir = \dirname($options['file']))) { // Build a regexp where the first root dirs are mandatory, // but every other sub-dir is optional up to the full path in $dir // Mandate at least 2 root dirs and not more that 5 optional dirs. - $dir = explode(DIRECTORY_SEPARATOR, realpath($dir)); - $i = count($dir); + $dir = explode(\DIRECTORY_SEPARATOR, realpath($dir)); + $i = \count($dir); if (3 <= $i) { $regex = ''; @@ -163,11 +184,11 @@ $this->targetDirMaxMatches = $i - $lastOptionalDir; while (--$i >= $lastOptionalDir) { - $regex = sprintf('(%s%s)?', preg_quote(DIRECTORY_SEPARATOR.$dir[$i], '#'), $regex); + $regex = sprintf('(%s%s)?', preg_quote(\DIRECTORY_SEPARATOR.$dir[$i], '#'), $regex); } do { - $regex = preg_quote(DIRECTORY_SEPARATOR.$dir[$i], '#').$regex; + $regex = preg_quote(\DIRECTORY_SEPARATOR.$dir[$i], '#').$regex; } while (0 < --$i); $this->targetDirRegex = '#'.preg_quote($dir[0], '#').$regex.'#'; @@ -190,15 +211,15 @@ // This file has been auto-generated by the Symfony Dependency Injection Component for internal use. EOF; - $files = array(); + $files = []; if ($ids = array_keys($this->container->getRemovedIds())) { sort($ids); - $c = "<?php\n\nreturn array(\n"; + $c = "<?php\n\nreturn [\n"; foreach ($ids as $id) { $c .= ' '.$this->doExport($id)." => true,\n"; } - $files['removed-ids.php'] = $c .= ");\n"; + $files['removed-ids.php'] = $c .= "];\n"; } foreach ($this->generateServiceFiles() as $file => $c) { @@ -209,7 +230,7 @@ } $files[$options['class'].'.php'] = $code; $hash = ucfirst(strtr(ContainerBuilder::hash($files), '._', 'xx')); - $code = array(); + $code = []; foreach ($files as $file => $c) { $code["Container{$hash}/{$file}"] = $c; @@ -237,11 +258,11 @@ \\class_alias(\\Container{$hash}\\{$options['class']}::class, {$options['class']}::class, false); } -return new \\Container{$hash}\\{$options['class']}(array( +return new \\Container{$hash}\\{$options['class']}([ 'container.build_hash' => '$hash', 'container.build_id' => '$id', 'container.build_time' => $time, -), __DIR__.\\DIRECTORY_SEPARATOR.'Container{$hash}'); +], __DIR__.\\DIRECTORY_SEPARATOR.'Container{$hash}'); EOF; } else { @@ -251,10 +272,10 @@ } $this->targetDirRegex = null; - $this->inlinedRequires = array(); - $this->circularReferences = array(); + $this->inlinedRequires = []; + $this->circularReferences = []; - $unusedEnvs = array(); + $unusedEnvs = []; foreach ($this->container->getEnvCounters() as $env => $use) { if (!$use) { $unusedEnvs[] = $env; @@ -281,86 +302,56 @@ return $this->proxyDumper; } - /** - * Generates Service local temp variables. - * - * @return string - */ - private function addServiceLocalTempVariables($cId, Definition $definition, \SplObjectStorage $inlinedDefinitions, \SplObjectStorage $allInlinedDefinitions) + private function analyzeCircularReferences($sourceId, array $edges, &$checkedNodes, &$currentPath = []) { - $allCalls = $calls = $behavior = array(); + $checkedNodes[$sourceId] = true; + $currentPath[$sourceId] = $sourceId; - 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]); - } - - $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); - } - } - 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 || isset($this->referenceVariables[$id])) { - continue; - } - if ($callCount <= 1 && $allCalls[$id] <= 1) { - continue; - } - - $name = $this->getNextVariableName(); - $this->referenceVariables[$id] = new Variable($name); - - $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 ($isPreInstance) { - $code .= <<<EOTXT - - if (isset(\$this->services['$cId'])) { - return \$this->services['$cId']; - } - -EOTXT; - } - - $code .= "\n"; - } - - return $code; - } - - private function analyzeCircularReferences(array $edges, &$checkedNodes, &$currentPath) - { foreach ($edges as $edge) { $node = $edge->getDestNode(); $id = $node->getId(); - if ($node->getValue() && ($edge->isLazy() || $edge->isWeak())) { + if (!$node->getValue() instanceof Definition || $sourceId === $id || $edge->isLazy() || $edge->isWeak()) { // no-op } elseif (isset($currentPath[$id])) { + $currentId = $id; foreach (array_reverse($currentPath) as $parentId) { - $this->circularReferences[$parentId][$id] = $id; - $id = $parentId; + $this->circularReferences[$parentId][$currentId] = $currentId; + if ($parentId === $id) { + break; + } + $currentId = $parentId; } } elseif (!isset($checkedNodes[$id])) { - $checkedNodes[$id] = true; - $currentPath[$id] = $id; - $this->analyzeCircularReferences($node->getOutEdges(), $checkedNodes, $currentPath); - unset($currentPath[$id]); + $this->analyzeCircularReferences($id, $node->getOutEdges(), $checkedNodes, $currentPath); + } elseif (isset($this->circularReferences[$id])) { + $this->connectCircularReferences($id, $currentPath); } } + unset($currentPath[$sourceId]); + } + + private function connectCircularReferences($sourceId, &$currentPath, &$subPath = []) + { + $subPath[$sourceId] = $sourceId; + $currentPath[$sourceId] = $sourceId; + + foreach ($this->circularReferences[$sourceId] as $id) { + if (isset($currentPath[$id])) { + $currentId = $id; + foreach (array_reverse($currentPath) as $parentId) { + $this->circularReferences[$parentId][$currentId] = $currentId; + if ($parentId === $id) { + break; + } + $currentId = $parentId; + } + } elseif (!isset($subPath[$id]) && isset($this->circularReferences[$id])) { + $this->connectCircularReferences($id, $currentPath, $subPath); + } + } + unset($currentPath[$sourceId]); + unset($subPath[$sourceId]); } private function collectLineage($class, array &$lineage) @@ -396,7 +387,7 @@ private function generateProxyClasses() { - $alreadyGenerated = array(); + $alreadyGenerated = []; $definitions = $this->container->getDefinitions(); $strip = '' === $this->docStar && method_exists('Symfony\Component\HttpKernel\Kernel', 'stripComments'); $proxyDumper = $this->getProxyDumper(); @@ -411,7 +402,9 @@ $alreadyGenerated[$class] = true; // register class' reflector for resource tracking $this->container->getReflectionClass($class); - $proxyCode = "\n".$proxyDumper->getProxyCode($definition); + if ("\n" === $proxyCode = "\n".$proxyDumper->getProxyCode($definition)) { + continue; + } if ($strip) { $proxyCode = "<?php\n".$proxyCode; $proxyCode = substr(Kernel::stripComments($proxyCode), 5); @@ -425,26 +418,24 @@ * * @return string */ - private function addServiceInclude($cId, Definition $definition, \SplObjectStorage $inlinedDefinitions) + private function addServiceInclude($cId, Definition $definition) { $code = ''; if ($this->inlineRequires && !$this->isHotPath($definition)) { - $lineage = $calls = $behavior = array(); - foreach ($inlinedDefinitions as $def) { - if (!$def->isDeprecated() && is_string($class = is_array($factory = $def->getFactory()) && is_string($factory[0]) ? $factory[0] : $def->getClass())) { + $lineage = []; + foreach ($this->inlinedDefinitions as $def) { + if (!$def->isDeprecated() && \is_string($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) { + foreach ($this->serviceCalls as $id => list($callCount, $behavior)) { if ('service_container' !== $id && $id !== $cId - && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE !== $behavior[$id] + && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE !== $behavior && $this->container->has($id) && $this->isTrivialInstance($def = $this->container->findDefinition($id)) - && is_string($class = is_array($factory = $def->getFactory()) && is_string($factory[0]) ? $factory[0] : $def->getClass()) + && \is_string($class = \is_array($factory = $def->getFactory()) && \is_string($factory[0]) ? $factory[0] : $def->getClass()) ) { $this->collectLineage($class, $lineage); } @@ -455,7 +446,7 @@ } } - foreach ($inlinedDefinitions as $def) { + foreach ($this->inlinedDefinitions as $def) { if ($file = $def->getFile()) { $code .= sprintf(" include_once %s;\n", $this->dumpValue($file)); } @@ -469,59 +460,6 @@ } /** - * Generates the inline definition of a service. - * - * @return string - * - * @throws RuntimeException When the factory definition is incomplete - * @throws ServiceCircularReferenceException When a circular reference is detected - */ - private function addServiceInlinedDefinitions($id, Definition $definition, \SplObjectStorage $inlinedDefinitions, &$isSimpleInstance) - { - $code = ''; - - foreach ($inlinedDefinitions as $def) { - if ($definition === $def) { - continue; - } - 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 (isset($inlinedDefinitions[$definition]) && $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; - } - - /** * Generates the service instance. * * @param string $id @@ -557,13 +495,7 @@ $instantiation .= ' = '; } - $code = $this->addNewInstance($definition, $return, $instantiation, $id); - - if (!$isSimpleInstance) { - $code .= "\n"; - } - - return $code; + return $this->addNewInstance($definition, $return, $instantiation, $id); } /** @@ -578,7 +510,7 @@ if ($definition->isSynthetic() || $definition->getFile() || $definition->getMethodCalls() || $definition->getProperties() || $definition->getConfigurator()) { return false; } - if ($definition->isDeprecated() || $definition->isLazy() || $definition->getFactory() || 3 < count($definition->getArguments())) { + if ($definition->isDeprecated() || $definition->isLazy() || $definition->getFactory() || 3 < \count($definition->getArguments())) { return false; } @@ -586,7 +518,7 @@ if (!$arg || $arg instanceof Parameter) { continue; } - if (is_array($arg) && 3 >= count($arg)) { + if (\is_array($arg) && 3 >= \count($arg)) { foreach ($arg as $k => $v) { if ($this->dumpValue($k) !== $this->dumpValue($k, false)) { return false; @@ -608,10 +540,6 @@ } } - if (false !== strpos($this->dumpLiteralClass($this->dumpValue($definition->getClass())), '$')) { - return false; - } - return true; } @@ -627,7 +555,7 @@ { $calls = ''; foreach ($definition->getMethodCalls() as $call) { - $arguments = array(); + $arguments = []; foreach ($call[1] as $value) { $arguments[] = $this->dumpValue($value); } @@ -649,42 +577,6 @@ } /** - * Generates the inline definition setup. - * - * @return string - * - * @throws ServiceCircularReferenceException when the container contains a circular reference - */ - private function addServiceInlinedDefinitionsSetup($id, Definition $definition, \SplObjectStorage $inlinedDefinitions, $isSimpleInstance) - { - $this->referenceVariables[$id] = new Variable('instance'); - - $code = ''; - foreach ($inlinedDefinitions as $def) { - if ($definition === $def || !$this->hasReference($id, array($def->getProperties(), $def->getMethodCalls(), $def->getConfigurator()), true)) { - continue; - } - - // if the instance is simple, the return statement has already been generated - // so, the only possible way to get there is because of a circular reference - if ($isSimpleInstance) { - throw new ServiceCircularReferenceException($id, array($id)); - } - - $name = (string) $this->definitionVariables[$def]; - $code .= $this->addServiceProperties($def, $name); - $code .= $this->addServiceMethodCalls($def, $name); - $code .= $this->addServiceConfigurator($def, $name); - } - - if ('' !== $code && ($definition->getProperties() || $definition->getMethodCalls() || $definition->getConfigurator())) { - $code .= "\n"; - } - - return $code; - } - - /** * Adds configurator definition. * * @param Definition $definition @@ -698,9 +590,10 @@ return ''; } - if (is_array($callable)) { + if (\is_array($callable)) { if ($callable[0] instanceof Reference - || ($callable[0] instanceof Definition && $this->definitionVariables->contains($callable[0]))) { + || ($callable[0] instanceof Definition && $this->definitionVariables->contains($callable[0])) + ) { return sprintf(" %s->%s(\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); } @@ -714,7 +607,7 @@ return sprintf(" (%s)->%s(\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); } - return sprintf(" \\call_user_func(array(%s, '%s'), \$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); + return sprintf(" \\call_user_func([%s, '%s'], \$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); } return sprintf(" %s(\$%s);\n", $callable, $variableName); @@ -732,29 +625,28 @@ private function addService($id, Definition $definition, &$file = null) { $this->definitionVariables = new \SplObjectStorage(); - $this->referenceVariables = array(); + $this->referenceVariables = []; $this->variableCount = 0; + $this->referenceVariables[$id] = new Variable('instance'); - $return = array(); + $return = []; if ($class = $definition->getClass()) { - $class = $this->container->resolveEnvPlaceholders($class); + $class = $class instanceof Parameter ? '%'.$class.'%' : $this->container->resolveEnvPlaceholders($class); $return[] = sprintf(0 === strpos($class, '%') ? '@return object A %1$s instance' : '@return \%s', ltrim($class, '\\')); } elseif ($definition->getFactory()) { $factory = $definition->getFactory(); - if (is_string($factory)) { + if (\is_string($factory)) { $return[] = sprintf('@return object An instance returned by %s()', $factory); - } elseif (is_array($factory) && (is_string($factory[0]) || $factory[0] instanceof Definition || $factory[0] instanceof Reference)) { - if (is_string($factory[0]) || $factory[0] instanceof Reference) { - $return[] = sprintf('@return object An instance returned by %s::%s()', (string) $factory[0], $factory[1]); - } elseif ($factory[0] instanceof Definition) { - $return[] = sprintf('@return object An instance returned by %s::%s()', $factory[0]->getClass(), $factory[1]); - } + } elseif (\is_array($factory) && (\is_string($factory[0]) || $factory[0] instanceof Definition || $factory[0] instanceof Reference)) { + $class = $factory[0] instanceof Definition ? $factory[0]->getClass() : (string) $factory[0]; + $class = $class instanceof Parameter ? '%'.$class.'%' : $this->container->resolveEnvPlaceholders($class); + $return[] = sprintf('@return object An instance returned by %s::%s()', $class, $factory[1]); } } if ($definition->isDeprecated()) { - if ($return && 0 === strpos($return[count($return) - 1], '@return')) { + if ($return && 0 === strpos($return[\count($return) - 1], '@return')) { $return[] = ''; } @@ -769,6 +661,7 @@ $autowired = $definition->isAutowired() ? ' autowired' : ''; if ($definition->isLazy()) { + unset($this->circularReferences[$id]); $lazyInitialization = '$lazyLoad = true'; } else { $lazyInitialization = ''; @@ -793,6 +686,11 @@ EOF; } + $this->serviceCalls = []; + $this->inlinedDefinitions = $this->getDefinitionsFromArguments([$definition], null, $this->serviceCalls); + + $code .= $this->addServiceInclude($id, $definition); + if ($this->getProxyDumper()->isProxyCandidate($definition)) { $factoryCode = $asFile ? "\$this->load('%s.php', false)" : '$this->%s(false)'; $code .= $this->getProxyDumper()->getProxyFactoryCode($definition, $id, sprintf($factoryCode, $methodName)); @@ -802,33 +700,7 @@ $code .= sprintf(" @trigger_error(%s, E_USER_DEPRECATED);\n\n", $this->export($definition->getDeprecationMessage($id))); } - $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($id, $definition, $inlinedDefinitions). - $this->addServiceLocalTempVariables($id, $definition, $constructorDefinitions, $inlinedDefinitions). - $this->addServiceInlinedDefinitions($id, $definition, $constructorDefinitions, $isSimpleInstance). - $this->addServiceInstance($id, $definition, $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). - (!$isSimpleInstance ? "\n return \$instance;\n" : '') - ; + $code .= $this->addInlineService($id, $definition); if ($asFile) { $code = implode("\n", array_map(function ($line) { return $line ? substr($line, 8) : $line; }, explode("\n", $code))); @@ -836,8 +708,123 @@ $code .= " }\n"; } - $this->definitionVariables = null; - $this->referenceVariables = null; + $this->definitionVariables = $this->inlinedDefinitions = null; + $this->referenceVariables = $this->serviceCalls = null; + + return $code; + } + + private function addInlineVariables($id, Definition $definition, array $arguments, $forConstructor) + { + $code = ''; + + foreach ($arguments as $argument) { + if (\is_array($argument)) { + $code .= $this->addInlineVariables($id, $definition, $argument, $forConstructor); + } elseif ($argument instanceof Reference) { + $code .= $this->addInlineReference($id, $definition, $this->container->normalizeId($argument), $forConstructor); + } elseif ($argument instanceof Definition) { + $code .= $this->addInlineService($id, $definition, $argument, $forConstructor); + } + } + + return $code; + } + + private function addInlineReference($id, Definition $definition, $targetId, $forConstructor) + { + list($callCount, $behavior) = $this->serviceCalls[$targetId]; + + while ($this->container->hasAlias($targetId)) { + $targetId = (string) $this->container->getAlias($targetId); + } + + if ($id === $targetId) { + return $this->addInlineService($id, $definition, $definition); + } + + if ('service_container' === $targetId || isset($this->referenceVariables[$targetId])) { + return ''; + } + + $hasSelfRef = isset($this->circularReferences[$id][$targetId]); + $forConstructor = $forConstructor && !isset($this->definitionVariables[$definition]); + $code = $hasSelfRef && !$forConstructor ? $this->addInlineService($id, $definition, $definition) : ''; + + if (isset($this->referenceVariables[$targetId]) || (2 > $callCount && (!$hasSelfRef || !$forConstructor))) { + return $code; + } + + $name = $this->getNextVariableName(); + $this->referenceVariables[$targetId] = new Variable($name); + + $reference = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE >= $behavior ? new Reference($targetId, $behavior) : null; + $code .= sprintf(" \$%s = %s;\n", $name, $this->getServiceCall($targetId, $reference)); + + if (!$hasSelfRef || !$forConstructor) { + return $code; + } + + $code .= sprintf(<<<'EOTXT' + + if (isset($this->%s['%s'])) { + return $this->%1$s['%2$s']; + } + +EOTXT + , + 'services', + $id + ); + + return $code; + } + + private function addInlineService($id, Definition $definition, Definition $inlineDef = null, $forConstructor = true) + { + $isSimpleInstance = $isRootInstance = null === $inlineDef; + + if (isset($this->definitionVariables[$inlineDef = $inlineDef ?: $definition])) { + return ''; + } + + $arguments = [$inlineDef->getArguments(), $inlineDef->getFactory()]; + + $code = $this->addInlineVariables($id, $definition, $arguments, $forConstructor); + + if ($arguments = array_filter([$inlineDef->getProperties(), $inlineDef->getMethodCalls(), $inlineDef->getConfigurator()])) { + $isSimpleInstance = false; + } elseif ($definition !== $inlineDef && 2 > $this->inlinedDefinitions[$inlineDef]) { + return $code; + } + + if (isset($this->definitionVariables[$inlineDef])) { + $isSimpleInstance = false; + } else { + $name = $definition === $inlineDef ? 'instance' : $this->getNextVariableName(); + $this->definitionVariables[$inlineDef] = new Variable($name); + $code .= '' !== $code ? "\n" : ''; + + if ('instance' === $name) { + $code .= $this->addServiceInstance($id, $definition, $isSimpleInstance); + } else { + $code .= $this->addNewInstance($inlineDef, '$'.$name, ' = ', $id); + } + + if ('' !== $inline = $this->addInlineVariables($id, $definition, $arguments, false)) { + $code .= "\n".$inline."\n"; + } elseif ($arguments && 'instance' === $name) { + $code .= "\n"; + } + + $code .= $this->addServiceProperties($inlineDef, $name); + $code .= $this->addServiceMethodCalls($inlineDef, $name); + $code .= $this->addServiceConfigurator($inlineDef, $name); + } + + if ($isRootInstance && !$isSimpleInstance) { + $code .= "\n return \$instance;\n"; + } return $code; } @@ -883,14 +870,14 @@ $class = $this->dumpValue($definition->getClass()); $return = ' '.$return.$instantiation; - $arguments = array(); + $arguments = []; foreach ($definition->getArguments() as $value) { $arguments[] = $this->dumpValue($value); } if (null !== $definition->getFactory()) { $callable = $definition->getFactory(); - if (is_array($callable)) { + if (\is_array($callable)) { if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $callable[1])) { throw new RuntimeException(sprintf('Cannot dump definition because of invalid factory method (%s)', $callable[1] ?: 'n/a')); } @@ -914,7 +901,7 @@ return $return.sprintf("(%s)->%s(%s);\n", $class, $callable[1], $arguments ? implode(', ', $arguments) : ''); } - return $return.sprintf("\\call_user_func(array(%s, '%s')%s);\n", $class, $callable[1], $arguments ? ', '.implode(', ', $arguments) : ''); + return $return.sprintf("\\call_user_func([%s, '%s']%s);\n", $class, $callable[1], $arguments ? ', '.implode(', ', $arguments) : ''); } return $return.sprintf("%s(%s);\n", $this->dumpLiteralClass($this->dumpValue($callable)), $arguments ? implode(', ', $arguments) : ''); @@ -961,7 +948,7 @@ class $class extends $baseClass { private \$parameters; - private \$targetDirs = array(); + private \$targetDirs = []; public function __construct() { @@ -979,7 +966,7 @@ } if ($this->asFiles) { $code = str_replace('$parameters', "\$buildParameters;\n private \$containerDir;\n private \$parameters", $code); - $code = str_replace('__construct()', '__construct(array $buildParameters = array(), $containerDir = __DIR__)', $code); + $code = str_replace('__construct()', '__construct(array $buildParameters = [], $containerDir = __DIR__)', $code); $code .= " \$this->buildParameters = \$buildParameters;\n"; $code .= " \$this->containerDir = \$containerDir;\n"; } @@ -1001,7 +988,7 @@ $code .= " \$this->parameters = \$this->getDefaultParameters();\n\n"; } - $code .= " \$this->services = array();\n"; + $code .= " \$this->services = [];\n"; } else { $arguments = $this->container->getParameterBag()->all() ? 'new ParameterBag($this->getDefaultParameters())' : null; $code .= " parent::__construct($arguments);\n"; @@ -1099,7 +1086,7 @@ } } - return $code ? " \$this->normalizedIds = array(\n".$code." );\n" : ''; + return $code ? " \$this->normalizedIds = [\n".$code." ];\n" : ''; } /** @@ -1118,7 +1105,7 @@ } } - return $code ? " \$this->syntheticIds = array(\n{$code} );\n" : ''; + return $code ? " \$this->syntheticIds = [\n{$code} ];\n" : ''; } /** @@ -1138,10 +1125,13 @@ $ids = array_keys($ids); sort($ids); foreach ($ids as $id) { + if (preg_match('/^\d+_[^~]++~[._a-zA-Z\d]{7}$/', $id)) { + continue; + } $code .= ' '.$this->doExport($id)." => true,\n"; } - $code = "array(\n{$code} )"; + $code = "[\n{$code} ]"; } return <<<EOF @@ -1170,7 +1160,7 @@ } } - return $code ? " \$this->methodMap = array(\n{$code} );\n" : ''; + return $code ? " \$this->methodMap = [\n{$code} ];\n" : ''; } /** @@ -1189,7 +1179,7 @@ } } - return $code ? " \$this->fileMap = array(\n{$code} );\n" : ''; + return $code ? " \$this->fileMap = [\n{$code} ];\n" : ''; } /** @@ -1221,9 +1211,9 @@ return ''; } - $out = " \$this->privates = array(\n"; + $out = " \$this->privates = [\n"; $out .= $code; - $out .= " );\n"; + $out .= " ];\n"; return $out; } @@ -1236,10 +1226,10 @@ private function addAliases() { if (!$aliases = $this->container->getAliases()) { - return $this->container->isCompiled() ? "\n \$this->aliases = array();\n" : ''; + return $this->container->isCompiled() ? "\n \$this->aliases = [];\n" : ''; } - $code = " \$this->aliases = array(\n"; + $code = " \$this->aliases = [\n"; ksort($aliases); foreach ($aliases as $alias => $id) { $id = $this->container->normalizeId($id); @@ -1249,7 +1239,7 @@ $code .= ' '.$this->doExport($alias).' => '.$this->doExport($id).",\n"; } - return $code." );\n"; + return $code." ];\n"; } private function addInlineRequires() @@ -1258,14 +1248,14 @@ return ''; } - $lineage = array(); + $lineage = []; foreach ($this->container->findTaggedServiceIds($this->hotPathTag) as $id => $tags) { $definition = $this->container->getDefinition($id); - $inlinedDefinitions = $this->getDefinitionsFromArguments(array($definition)); + $inlinedDefinitions = $this->getDefinitionsFromArguments([$definition]); foreach ($inlinedDefinitions as $def) { - if (is_string($class = is_array($factory = $def->getFactory()) && is_string($factory[0]) ? $factory[0] : $def->getClass())) { + if (\is_string($class = \is_array($factory = $def->getFactory()) && \is_string($factory[0]) ? $factory[0] : $def->getClass())) { $this->collectLineage($class, $lineage); } } @@ -1294,9 +1284,9 @@ return ''; } - $php = array(); - $dynamicPhp = array(); - $normalizedParams = array(); + $php = []; + $dynamicPhp = []; + $normalizedParams = []; foreach ($this->container->getParameterBag()->all() as $key => $value) { if ($key !== $resolvedKey = $this->container->resolveEnvPlaceholders($key)) { @@ -1305,8 +1295,8 @@ if ($key !== $lcKey = strtolower($key)) { $normalizedParams[] = sprintf(' %s => %s,', $this->export($lcKey), $this->export($key)); } - $export = $this->exportParameters(array($value)); - $export = explode('0 => ', substr(rtrim($export, " )\n"), 7, -1), 2); + $export = $this->exportParameters([$value]); + $export = explode('0 => ', substr(rtrim($export, " ]\n"), 2, -1), 2); if (preg_match("/\\\$this->(?:getEnv\('(?:\w++:)*+\w++'\)|targetDirs\[\d++\])/", $export[1])) { $dynamicPhp[$key] = sprintf('%scase %s: $value = %s; break;', $export[0], $this->export($key), $export[1]); @@ -1314,7 +1304,8 @@ $php[] = sprintf('%s%s => %s,', $export[0], $this->export($key), $export[1]); } } - $parameters = sprintf("array(\n%s\n%s)", implode("\n", $php), str_repeat(' ', 8)); + + $parameters = sprintf("[\n%s\n%s]", implode("\n", $php), str_repeat(' ', 8)); $code = ''; if ($this->container->isCompiled()) { @@ -1378,7 +1369,7 @@ } if ($dynamicPhp) { - $loadedDynamicParameters = $this->exportParameters(array_combine(array_keys($dynamicPhp), array_fill(0, count($dynamicPhp), false)), '', 8); + $loadedDynamicParameters = $this->exportParameters(array_combine(array_keys($dynamicPhp), array_fill(0, \count($dynamicPhp), false)), '', 8); $getDynamicParameter = <<<'EOF' switch ($name) { %s @@ -1390,19 +1381,19 @@ EOF; $getDynamicParameter = sprintf($getDynamicParameter, implode("\n", $dynamicPhp)); } else { - $loadedDynamicParameters = 'array()'; + $loadedDynamicParameters = '[]'; $getDynamicParameter = str_repeat(' ', 8).'throw new InvalidArgumentException(sprintf(\'The dynamic parameter "%s" must be defined.\', $name));'; } $code .= <<<EOF private \$loadedDynamicParameters = {$loadedDynamicParameters}; - private \$dynamicParameters = array(); + private \$dynamicParameters = []; /*{$this->docStar} * Computes a dynamic parameter. * - * @param string The name of the dynamic parameter to load + * @param string \$name The name of the dynamic parameter to load * * @return mixed The value of the dynamic parameter * @@ -1416,7 +1407,7 @@ EOF; - $code .= ' private $normalizedParameterNames = '.($normalizedParams ? sprintf("array(\n%s\n );", implode("\n", $normalizedParams)) : 'array();')."\n"; + $code .= ' private $normalizedParameterNames = '.($normalizedParams ? sprintf("[\n%s\n ];", implode("\n", $normalizedParams)) : '[];')."\n"; $code .= <<<'EOF' private function normalizeParameterName($name) @@ -1468,12 +1459,12 @@ */ private function exportParameters(array $parameters, $path = '', $indent = 12) { - $php = array(); + $php = []; foreach ($parameters as $key => $value) { - if (is_array($value)) { + if (\is_array($value)) { $value = $this->exportParameters($value, $path.'/'.$key, $indent + 4); } elseif ($value instanceof ArgumentInterface) { - throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain special arguments. "%s" found in "%s".', get_class($value), $path.'/'.$key)); + throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain special arguments. "%s" found in "%s".', \get_class($value), $path.'/'.$key)); } elseif ($value instanceof Variable) { throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain variable references. Variable "%s" found in "%s".', $value, $path.'/'.$key)); } elseif ($value instanceof Definition) { @@ -1489,7 +1480,7 @@ $php[] = sprintf('%s%s => %s,', str_repeat(' ', $indent), $this->export($key), $value); } - return sprintf("array(\n%s\n%s)", implode("\n", $php), str_repeat(' ', $indent - 4)); + return sprintf("[\n%s\n%s]", implode("\n", $php), str_repeat(' ', $indent - 4)); } /** @@ -1530,11 +1521,11 @@ * * @param string $value * - * @return null|string + * @return string|null */ private function getServiceConditionals($value) { - $conditions = array(); + $conditions = []; foreach (ContainerBuilder::getInitializedConditionals($value) as $service) { if (!$this->container->hasDefinition($service)) { return 'false'; @@ -1556,55 +1547,33 @@ return implode(' && ', $conditions); } - /** - * Builds service calls from arguments. - */ - 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, $isPreInstance, $callerId, $behavior, $step); - } elseif ($argument instanceof Reference) { - $id = $this->container->normalizeId($argument); - - if (!isset($calls[$id])) { - $calls[$id] = (int) ($isPreInstance && isset($this->circularReferences[$callerId][$id])); - } - if (!isset($behavior[$id])) { - $behavior[$id] = $argument->getInvalidBehavior(); - } else { - $behavior[$id] = min($behavior[$id], $argument->getInvalidBehavior()); - } - - $calls[$id] += $step; - } - } - } - - private function getDefinitionsFromArguments(array $arguments, \SplObjectStorage $definitions = null) + private function getDefinitionsFromArguments(array $arguments, \SplObjectStorage $definitions = null, array &$calls = []) { if (null === $definitions) { $definitions = new \SplObjectStorage(); } foreach ($arguments as $argument) { - if (is_array($argument)) { - $this->getDefinitionsFromArguments($argument, $definitions); + if (\is_array($argument)) { + $this->getDefinitionsFromArguments($argument, $definitions, $calls); + } elseif ($argument instanceof Reference) { + $id = $this->container->normalizeId($argument); + + if (!isset($calls[$id])) { + $calls[$id] = [0, $argument->getInvalidBehavior()]; + } else { + $calls[$id][1] = min($calls[$id][1], $argument->getInvalidBehavior()); + } + + ++$calls[$id][0]; } 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; + $arguments = [$argument->getArguments(), $argument->getFactory(), $argument->getProperties(), $argument->getMethodCalls(), $argument->getConfigurator()]; + $this->getDefinitionsFromArguments($arguments, $definitions, $calls); } } @@ -1612,62 +1581,6 @@ } /** - * Checks if a service id has a reference. - * - * @param string $id - * @param array $arguments - * @param bool $deep - * @param array $visited - * - * @return bool - */ - private function hasReference($id, array $arguments, $deep = false, array &$visited = array()) - { - if (!isset($this->circularReferences[$id])) { - return false; - } - - foreach ($arguments as $argument) { - if (is_array($argument)) { - if ($this->hasReference($id, $argument, $deep, $visited)) { - return true; - } - - continue; - } elseif ($argument instanceof Reference) { - $argumentId = $this->container->normalizeId($argument); - if ($id === $argumentId) { - return true; - } - - if (!$deep || isset($visited[$argumentId]) || !isset($this->circularReferences[$id][$argumentId])) { - continue; - } - - $visited[$argumentId] = true; - - $service = $this->container->getDefinition($argumentId); - } elseif ($argument instanceof Definition) { - $service = $argument; - } else { - continue; - } - - // if the proxy manager is enabled, disable searching for references in lazy services, - // as these services will be instantiated lazily and don't have direct related references. - if ($service->isLazy() && !$this->getProxyDumper() instanceof NullDumper) { - continue; - } - - if ($this->hasReference($id, array($service->getArguments(), $service->getFactory(), $service->getProperties(), $service->getMethodCalls(), $service->getConfigurator()), $deep, $visited)) { - return true; - } - } - - return false; - } - - /** * Dumps values. * * @param mixed $value @@ -1679,18 +1592,18 @@ */ private function dumpValue($value, $interpolate = true) { - if (is_array($value)) { + if (\is_array($value)) { if ($value && $interpolate && false !== $param = array_search($value, $this->container->getParameterBag()->all(), true)) { return $this->dumpValue("%$param%"); } - $code = array(); + $code = []; foreach ($value as $k => $v) { $code[] = sprintf('%s => %s', $this->dumpValue($k, $interpolate), $this->dumpValue($v, $interpolate)); } - return sprintf('array(%s)', implode(', ', $code)); + return sprintf('[%s]', implode(', ', $code)); } elseif ($value instanceof ArgumentInterface) { - $scope = array($this->definitionVariables, $this->referenceVariables, $this->variableCount); + $scope = [$this->definitionVariables, $this->referenceVariables]; $this->definitionVariables = $this->referenceVariables = null; try { @@ -1708,14 +1621,14 @@ } if ($value instanceof IteratorArgument) { - $operands = array(0); - $code = array(); + $operands = [0]; + $code = []; $code[] = 'new RewindableGenerator(function () {'; if (!$values = $value->getValues()) { $code[] = ' return new \EmptyIterator();'; } else { - $countCode = array(); + $countCode = []; $countCode[] = 'function () {'; foreach ($values as $k => $v) { @@ -1732,12 +1645,12 @@ $countCode[] = ' }'; } - $code[] = sprintf(' }, %s)', count($operands) > 1 ? implode("\n", $countCode) : $operands[0]); + $code[] = sprintf(' }, %s)', \count($operands) > 1 ? implode("\n", $countCode) : $operands[0]); return implode("\n", $code); } } finally { - list($this->definitionVariables, $this->referenceVariables, $this->variableCount) = $scope; + list($this->definitionVariables, $this->referenceVariables) = $scope; } } elseif ($value instanceof Definition) { if (null !== $this->definitionVariables && $this->definitionVariables->contains($value)) { @@ -1753,7 +1666,7 @@ throw new RuntimeException('Cannot dump definitions which have a configurator.'); } - $arguments = array(); + $arguments = []; foreach ($value->getArguments() as $argument) { $arguments[] = $this->dumpValue($argument); } @@ -1761,17 +1674,17 @@ if (null !== $value->getFactory()) { $factory = $value->getFactory(); - if (is_string($factory)) { + if (\is_string($factory)) { return sprintf('%s(%s)', $this->dumpLiteralClass($this->dumpValue($factory)), implode(', ', $arguments)); } - if (is_array($factory)) { + if (\is_array($factory)) { if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $factory[1])) { throw new RuntimeException(sprintf('Cannot dump definition because of invalid factory method (%s)', $factory[1] ?: 'n/a')); } $class = $this->dumpValue($factory[0]); - if (is_string($factory[0])) { + if (\is_string($factory[0])) { return sprintf('%s::%s(%s)', $this->dumpLiteralClass($class), $factory[1], implode(', ', $arguments)); } @@ -1780,7 +1693,7 @@ return sprintf('(%s)->%s(%s)', $class, $factory[1], implode(', ', $arguments)); } - return sprintf("\\call_user_func(array(%s, '%s')%s)", $class, $factory[1], count($arguments) > 0 ? ', '.implode(', ', $arguments) : ''); + return sprintf("\\call_user_func([%s, '%s']%s)", $class, $factory[1], \count($arguments) > 0 ? ', '.implode(', ', $arguments) : ''); } if ($factory[0] instanceof Reference) { @@ -1807,10 +1720,10 @@ return $this->getServiceCall($id, $value); } elseif ($value instanceof Expression) { - return $this->getExpressionLanguage()->compile((string) $value, array('this' => 'container')); + return $this->getExpressionLanguage()->compile((string) $value, ['this' => 'container']); } elseif ($value instanceof Parameter) { return $this->dumpParameter($value); - } elseif (true === $interpolate && is_string($value)) { + } elseif (true === $interpolate && \is_string($value)) { if (preg_match('/^%([^%]+)%$/', $value, $match)) { // we do this to deal with non string values (Boolean, integer, ...) // the preg_replace_callback converts them to strings @@ -1824,7 +1737,7 @@ return $code; } - } elseif (is_object($value) || is_resource($value)) { + } elseif (\is_object($value) || \is_resource($value)) { throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.'); } @@ -1867,7 +1780,7 @@ $value = $this->container->getParameter($name); $dumpedValue = $this->dumpValue($value, false); - if (!$value || !is_array($value)) { + if (!$value || !\is_array($value)) { return $dumpedValue; } @@ -1898,8 +1811,10 @@ return '$this'; } - if ($this->container->hasDefinition($id) && ($definition = $this->container->getDefinition($id)) && !$definition->isSynthetic()) { - if (null !== $reference && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $reference->getInvalidBehavior()) { + if ($this->container->hasDefinition($id) && $definition = $this->container->getDefinition($id)) { + if ($definition->isSynthetic()) { + $code = sprintf('$this->get(\'%s\'%s)', $id, null !== $reference ? ', '.$reference->getInvalidBehavior() : ''); + } elseif (null !== $reference && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $reference->getInvalidBehavior()) { $code = 'null'; if (!$definition->isShared()) { return $code; @@ -1909,6 +1824,7 @@ if ($definition->isShared()) { $code = sprintf('$this->services[\'%s\'] = %s', $id, $code); } + $code = "($code)"; } elseif ($this->asFiles && $definition->isShared() && !$this->isHotPath($definition)) { $code = sprintf("\$this->load('%s.php')", $this->generateMethodName($id)); } else { @@ -1934,8 +1850,8 @@ */ private function initializeMethodNamesMap($class) { - $this->serviceIdToMethodNameMap = array(); - $this->usedMethodNames = array(); + $this->serviceIdToMethodNameMap = []; + $this->usedMethodNames = []; if ($reflectionClass = $this->container->getReflectionClass($class)) { foreach ($reflectionClass->getMethods() as $method) { @@ -1984,9 +1900,9 @@ private function getNextVariableName() { $firstChars = self::FIRST_CHARS; - $firstCharsLength = strlen($firstChars); + $firstCharsLength = \strlen($firstChars); $nonFirstChars = self::NON_FIRST_CHARS; - $nonFirstCharsLength = strlen($nonFirstChars); + $nonFirstCharsLength = \strlen($nonFirstChars); while (true) { $name = ''; @@ -2006,7 +1922,7 @@ ++$this->variableCount; // check that the name is not reserved - if (in_array($name, $this->reservedVariables, true)) { + if (\in_array($name, $this->reservedVariables, true)) { continue; } @@ -2048,12 +1964,12 @@ private function export($value) { - if (null !== $this->targetDirRegex && is_string($value) && preg_match($this->targetDirRegex, $value, $matches, PREG_OFFSET_CAPTURE)) { + if (null !== $this->targetDirRegex && \is_string($value) && preg_match($this->targetDirRegex, $value, $matches, PREG_OFFSET_CAPTURE)) { $prefix = $matches[0][1] ? $this->doExport(substr($value, 0, $matches[0][1]), true).'.' : ''; - $suffix = $matches[0][1] + strlen($matches[0][0]); + $suffix = $matches[0][1] + \strlen($matches[0][0]); $suffix = isset($value[$suffix]) ? '.'.$this->doExport(substr($value, $suffix), true) : ''; $dirname = $this->asFiles ? '$this->containerDir' : '__DIR__'; - $offset = 1 + $this->targetDirMaxMatches - count($matches); + $offset = 1 + $this->targetDirMaxMatches - \count($matches); if ($this->asFiles || 0 < $offset) { $dirname = sprintf('$this->targetDirs[%d]', $offset); @@ -2071,7 +1987,7 @@ private function doExport($value, $resolveEnv = false) { - if (is_string($value) && false !== strpos($value, "\n")) { + if (\is_string($value) && false !== strpos($value, "\n")) { $cleanParts = explode("\n", $value); $cleanParts = array_map(function ($part) { return var_export($part, true); }, $cleanParts); $export = implode('."\n".', $cleanParts);