annotate vendor/symfony/dependency-injection/Compiler/InlineServiceDefinitionsPass.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children 7a779792577d
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 /*
Chris@0 4 * This file is part of the Symfony package.
Chris@0 5 *
Chris@0 6 * (c) Fabien Potencier <fabien@symfony.com>
Chris@0 7 *
Chris@0 8 * For the full copyright and license information, please view the LICENSE
Chris@0 9 * file that was distributed with this source code.
Chris@0 10 */
Chris@0 11
Chris@0 12 namespace Symfony\Component\DependencyInjection\Compiler;
Chris@0 13
Chris@0 14 use Symfony\Component\DependencyInjection\Definition;
Chris@0 15 use Symfony\Component\DependencyInjection\Reference;
Chris@0 16 use Symfony\Component\DependencyInjection\ContainerBuilder;
Chris@0 17
Chris@0 18 /**
Chris@0 19 * Inline service definitions where this is possible.
Chris@0 20 *
Chris@0 21 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
Chris@0 22 */
Chris@0 23 class InlineServiceDefinitionsPass implements RepeatablePassInterface
Chris@0 24 {
Chris@0 25 private $repeatedPass;
Chris@0 26 private $graph;
Chris@0 27 private $compiler;
Chris@0 28 private $formatter;
Chris@0 29 private $currentId;
Chris@0 30
Chris@0 31 /**
Chris@0 32 * {@inheritdoc}
Chris@0 33 */
Chris@0 34 public function setRepeatedPass(RepeatedPass $repeatedPass)
Chris@0 35 {
Chris@0 36 $this->repeatedPass = $repeatedPass;
Chris@0 37 }
Chris@0 38
Chris@0 39 /**
Chris@0 40 * Processes the ContainerBuilder for inline service definitions.
Chris@0 41 *
Chris@0 42 * @param ContainerBuilder $container
Chris@0 43 */
Chris@0 44 public function process(ContainerBuilder $container)
Chris@0 45 {
Chris@0 46 $this->compiler = $container->getCompiler();
Chris@0 47 $this->formatter = $this->compiler->getLoggingFormatter();
Chris@0 48 $this->graph = $this->compiler->getServiceReferenceGraph();
Chris@0 49
Chris@0 50 $container->setDefinitions($this->inlineArguments($container, $container->getDefinitions(), true));
Chris@0 51 }
Chris@0 52
Chris@0 53 /**
Chris@0 54 * Processes inline arguments.
Chris@0 55 *
Chris@0 56 * @param ContainerBuilder $container The ContainerBuilder
Chris@0 57 * @param array $arguments An array of arguments
Chris@0 58 * @param bool $isRoot If we are processing the root definitions or not
Chris@0 59 *
Chris@0 60 * @return array
Chris@0 61 */
Chris@0 62 private function inlineArguments(ContainerBuilder $container, array $arguments, $isRoot = false)
Chris@0 63 {
Chris@0 64 foreach ($arguments as $k => $argument) {
Chris@0 65 if ($isRoot) {
Chris@0 66 $this->currentId = $k;
Chris@0 67 }
Chris@0 68 if (is_array($argument)) {
Chris@0 69 $arguments[$k] = $this->inlineArguments($container, $argument);
Chris@0 70 } elseif ($argument instanceof Reference) {
Chris@0 71 if (!$container->hasDefinition($id = (string) $argument)) {
Chris@0 72 continue;
Chris@0 73 }
Chris@0 74
Chris@0 75 if ($this->isInlineableDefinition($id, $definition = $container->getDefinition($id))) {
Chris@0 76 $this->compiler->addLogMessage($this->formatter->formatInlineService($this, $id, $this->currentId));
Chris@0 77
Chris@0 78 if ($definition->isShared()) {
Chris@0 79 $arguments[$k] = $definition;
Chris@0 80 } else {
Chris@0 81 $arguments[$k] = clone $definition;
Chris@0 82 }
Chris@0 83 }
Chris@0 84 } elseif ($argument instanceof Definition) {
Chris@0 85 $argument->setArguments($this->inlineArguments($container, $argument->getArguments()));
Chris@0 86 $argument->setMethodCalls($this->inlineArguments($container, $argument->getMethodCalls()));
Chris@0 87 $argument->setProperties($this->inlineArguments($container, $argument->getProperties()));
Chris@0 88
Chris@0 89 $configurator = $this->inlineArguments($container, array($argument->getConfigurator()));
Chris@0 90 $argument->setConfigurator($configurator[0]);
Chris@0 91
Chris@0 92 $factory = $this->inlineArguments($container, array($argument->getFactory()));
Chris@0 93 $argument->setFactory($factory[0]);
Chris@0 94 }
Chris@0 95 }
Chris@0 96
Chris@0 97 return $arguments;
Chris@0 98 }
Chris@0 99
Chris@0 100 /**
Chris@0 101 * Checks if the definition is inlineable.
Chris@0 102 *
Chris@0 103 * @param string $id
Chris@0 104 * @param Definition $definition
Chris@0 105 *
Chris@0 106 * @return bool If the definition is inlineable
Chris@0 107 */
Chris@0 108 private function isInlineableDefinition($id, Definition $definition)
Chris@0 109 {
Chris@0 110 if (!$definition->isShared()) {
Chris@0 111 return true;
Chris@0 112 }
Chris@0 113
Chris@0 114 if ($definition->isPublic() || $definition->isLazy()) {
Chris@0 115 return false;
Chris@0 116 }
Chris@0 117
Chris@0 118 if (!$this->graph->hasNode($id)) {
Chris@0 119 return true;
Chris@0 120 }
Chris@0 121
Chris@0 122 if ($this->currentId == $id) {
Chris@0 123 return false;
Chris@0 124 }
Chris@0 125
Chris@0 126 $ids = array();
Chris@0 127 foreach ($this->graph->getNode($id)->getInEdges() as $edge) {
Chris@0 128 $ids[] = $edge->getSourceNode()->getId();
Chris@0 129 }
Chris@0 130
Chris@0 131 if (count(array_unique($ids)) > 1) {
Chris@0 132 return false;
Chris@0 133 }
Chris@0 134
Chris@0 135 if (count($ids) > 1 && is_array($factory = $definition->getFactory()) && ($factory[0] instanceof Reference || $factory[0] instanceof Definition)) {
Chris@0 136 return false;
Chris@0 137 }
Chris@0 138
Chris@0 139 return true;
Chris@0 140 }
Chris@0 141 }