comparison vendor/symfony/dependency-injection/Compiler/InlineServiceDefinitionsPass.php @ 14:1fec387a4317

Update Drupal core to 8.5.2 via Composer
author Chris Cannam
date Mon, 23 Apr 2018 09:46:53 +0100
parents 7a779792577d
children c2387f117808
comparison
equal deleted inserted replaced
13:5fb285c0d0e3 14:1fec387a4317
9 * file that was distributed with this source code. 9 * file that was distributed with this source code.
10 */ 10 */
11 11
12 namespace Symfony\Component\DependencyInjection\Compiler; 12 namespace Symfony\Component\DependencyInjection\Compiler;
13 13
14 use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
14 use Symfony\Component\DependencyInjection\Definition; 15 use Symfony\Component\DependencyInjection\Definition;
16 use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
15 use Symfony\Component\DependencyInjection\Reference; 17 use Symfony\Component\DependencyInjection\Reference;
16 use Symfony\Component\DependencyInjection\ContainerBuilder;
17 18
18 /** 19 /**
19 * Inline service definitions where this is possible. 20 * Inline service definitions where this is possible.
20 * 21 *
21 * @author Johannes M. Schmitt <schmittjoh@gmail.com> 22 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
22 */ 23 */
23 class InlineServiceDefinitionsPass implements RepeatablePassInterface 24 class InlineServiceDefinitionsPass extends AbstractRecursivePass implements RepeatablePassInterface
24 { 25 {
25 private $repeatedPass; 26 private $cloningIds = array();
26 private $graph; 27 private $inlinedServiceIds = array();
27 private $compiler;
28 private $formatter;
29 private $currentId;
30 28
31 /** 29 /**
32 * {@inheritdoc} 30 * {@inheritdoc}
33 */ 31 */
34 public function setRepeatedPass(RepeatedPass $repeatedPass) 32 public function setRepeatedPass(RepeatedPass $repeatedPass)
35 { 33 {
36 $this->repeatedPass = $repeatedPass; 34 // no-op for BC
37 } 35 }
38 36
39 /** 37 /**
40 * Processes the ContainerBuilder for inline service definitions. 38 * Returns an array of all services inlined by this pass.
41 * 39 *
42 * @param ContainerBuilder $container 40 * The key is the inlined service id and its value is the list of services it was inlined into.
41 *
42 * @deprecated since version 3.4, to be removed in 4.0.
43 *
44 * @return array
43 */ 45 */
44 public function process(ContainerBuilder $container) 46 public function getInlinedServiceIds()
45 { 47 {
46 $this->compiler = $container->getCompiler(); 48 @trigger_error('Calling InlineServiceDefinitionsPass::getInlinedServiceIds() is deprecated since Symfony 3.4 and will be removed in 4.0.', E_USER_DEPRECATED);
47 $this->formatter = $this->compiler->getLoggingFormatter();
48 $this->graph = $this->compiler->getServiceReferenceGraph();
49 49
50 $container->setDefinitions($this->inlineArguments($container, $container->getDefinitions(), true)); 50 return $this->inlinedServiceIds;
51 } 51 }
52 52
53 /** 53 /**
54 * Processes inline arguments. 54 * {@inheritdoc}
55 *
56 * @param ContainerBuilder $container The ContainerBuilder
57 * @param array $arguments An array of arguments
58 * @param bool $isRoot If we are processing the root definitions or not
59 *
60 * @return array
61 */ 55 */
62 private function inlineArguments(ContainerBuilder $container, array $arguments, $isRoot = false) 56 protected function processValue($value, $isRoot = false)
63 { 57 {
64 foreach ($arguments as $k => $argument) { 58 if ($value instanceof ArgumentInterface) {
65 if ($isRoot) { 59 // Reference found in ArgumentInterface::getValues() are not inlineable
66 $this->currentId = $k; 60 return $value;
67 }
68 if (is_array($argument)) {
69 $arguments[$k] = $this->inlineArguments($container, $argument);
70 } elseif ($argument instanceof Reference) {
71 if (!$container->hasDefinition($id = (string) $argument)) {
72 continue;
73 }
74
75 if ($this->isInlineableDefinition($id, $definition = $container->getDefinition($id))) {
76 $this->compiler->addLogMessage($this->formatter->formatInlineService($this, $id, $this->currentId));
77
78 if ($definition->isShared()) {
79 $arguments[$k] = $definition;
80 } else {
81 $arguments[$k] = clone $definition;
82 }
83 }
84 } elseif ($argument instanceof Definition) {
85 $argument->setArguments($this->inlineArguments($container, $argument->getArguments()));
86 $argument->setMethodCalls($this->inlineArguments($container, $argument->getMethodCalls()));
87 $argument->setProperties($this->inlineArguments($container, $argument->getProperties()));
88
89 $configurator = $this->inlineArguments($container, array($argument->getConfigurator()));
90 $argument->setConfigurator($configurator[0]);
91
92 $factory = $this->inlineArguments($container, array($argument->getFactory()));
93 $argument->setFactory($factory[0]);
94 }
95 } 61 }
96 62
97 return $arguments; 63 if ($value instanceof Definition && $this->cloningIds) {
64 if ($value->isShared()) {
65 return $value;
66 }
67 $value = clone $value;
68 }
69
70 if (!$value instanceof Reference || !$this->container->hasDefinition($id = $this->container->normalizeId($value))) {
71 return parent::processValue($value, $isRoot);
72 }
73
74 $definition = $this->container->getDefinition($id);
75
76 if (!$this->isInlineableDefinition($id, $definition, $this->container->getCompiler()->getServiceReferenceGraph())) {
77 return $value;
78 }
79
80 $this->container->log($this, sprintf('Inlined service "%s" to "%s".', $id, $this->currentId));
81 $this->inlinedServiceIds[$id][] = $this->currentId;
82
83 if ($definition->isShared()) {
84 return $definition;
85 }
86
87 if (isset($this->cloningIds[$id])) {
88 $ids = array_keys($this->cloningIds);
89 $ids[] = $id;
90
91 throw new ServiceCircularReferenceException($id, array_slice($ids, array_search($id, $ids)));
92 }
93
94 $this->cloningIds[$id] = true;
95 try {
96 return $this->processValue($definition);
97 } finally {
98 unset($this->cloningIds[$id]);
99 }
98 } 100 }
99 101
100 /** 102 /**
101 * Checks if the definition is inlineable. 103 * Checks if the definition is inlineable.
102 * 104 *
103 * @param string $id
104 * @param Definition $definition
105 *
106 * @return bool If the definition is inlineable 105 * @return bool If the definition is inlineable
107 */ 106 */
108 private function isInlineableDefinition($id, Definition $definition) 107 private function isInlineableDefinition($id, Definition $definition, ServiceReferenceGraph $graph)
109 { 108 {
110 if (!$definition->isShared()) { 109 if (!$definition->isShared()) {
111 return true; 110 return true;
112 } 111 }
113 112
114 if ($definition->isDeprecated() || $definition->isPublic() || $definition->isLazy()) { 113 if ($definition->isDeprecated() || $definition->isPublic() || $definition->isPrivate() || $definition->isLazy()) {
115 return false; 114 return false;
116 } 115 }
117 116
118 if (!$this->graph->hasNode($id)) { 117 if (!$graph->hasNode($id)) {
119 return true; 118 return true;
120 } 119 }
121 120
122 if ($this->currentId == $id) { 121 if ($this->currentId == $id) {
123 return false; 122 return false;
124 } 123 }
125 124
126 $ids = array(); 125 $ids = array();
127 foreach ($this->graph->getNode($id)->getInEdges() as $edge) { 126 foreach ($graph->getNode($id)->getInEdges() as $edge) {
127 if ($edge->isWeak()) {
128 return false;
129 }
128 $ids[] = $edge->getSourceNode()->getId(); 130 $ids[] = $edge->getSourceNode()->getId();
129 } 131 }
130 132
131 if (count(array_unique($ids)) > 1) { 133 if (count(array_unique($ids)) > 1) {
132 return false; 134 return false;