Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / vendor / symfony / dependency-injection / Compiler / AnalyzeServiceReferencesPass.php
1 <?php
2
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Symfony\Component\DependencyInjection\Compiler;
13
14 use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
15 use Symfony\Component\DependencyInjection\ContainerBuilder;
16 use Symfony\Component\DependencyInjection\ContainerInterface;
17 use Symfony\Component\DependencyInjection\Definition;
18 use Symfony\Component\DependencyInjection\Exception\RuntimeException;
19 use Symfony\Component\DependencyInjection\ExpressionLanguage;
20 use Symfony\Component\DependencyInjection\Reference;
21 use Symfony\Component\ExpressionLanguage\Expression;
22
23 /**
24  * Run this pass before passes that need to know more about the relation of
25  * your services.
26  *
27  * This class will populate the ServiceReferenceGraph with information. You can
28  * retrieve the graph in other passes from the compiler.
29  *
30  * @author Johannes M. Schmitt <schmittjoh@gmail.com>
31  */
32 class AnalyzeServiceReferencesPass extends AbstractRecursivePass implements RepeatablePassInterface
33 {
34     private $graph;
35     private $currentDefinition;
36     private $onlyConstructorArguments;
37     private $hasProxyDumper;
38     private $lazy;
39     private $expressionLanguage;
40
41     /**
42      * @param bool $onlyConstructorArguments Sets this Service Reference pass to ignore method calls
43      */
44     public function __construct($onlyConstructorArguments = false, $hasProxyDumper = true)
45     {
46         $this->onlyConstructorArguments = (bool) $onlyConstructorArguments;
47         $this->hasProxyDumper = (bool) $hasProxyDumper;
48     }
49
50     /**
51      * {@inheritdoc}
52      */
53     public function setRepeatedPass(RepeatedPass $repeatedPass)
54     {
55         // no-op for BC
56     }
57
58     /**
59      * Processes a ContainerBuilder object to populate the service reference graph.
60      */
61     public function process(ContainerBuilder $container)
62     {
63         $this->container = $container;
64         $this->graph = $container->getCompiler()->getServiceReferenceGraph();
65         $this->graph->clear();
66         $this->lazy = false;
67
68         foreach ($container->getAliases() as $id => $alias) {
69             $targetId = $this->getDefinitionId((string) $alias);
70             $this->graph->connect($id, $alias, $targetId, $this->getDefinition($targetId), null);
71         }
72
73         parent::process($container);
74     }
75
76     protected function processValue($value, $isRoot = false)
77     {
78         $lazy = $this->lazy;
79
80         if ($value instanceof ArgumentInterface) {
81             $this->lazy = true;
82             parent::processValue($value->getValues());
83             $this->lazy = $lazy;
84
85             return $value;
86         }
87         if ($value instanceof Expression) {
88             $this->getExpressionLanguage()->compile((string) $value, array('this' => 'container'));
89
90             return $value;
91         }
92         if ($value instanceof Reference) {
93             $targetId = $this->getDefinitionId((string) $value);
94             $targetDefinition = $this->getDefinition($targetId);
95
96             $this->graph->connect(
97                 $this->currentId,
98                 $this->currentDefinition,
99                 $targetId,
100                 $targetDefinition,
101                 $value,
102                 $this->lazy || ($this->hasProxyDumper && $targetDefinition && $targetDefinition->isLazy()),
103                 ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $value->getInvalidBehavior()
104             );
105
106             return $value;
107         }
108         if (!$value instanceof Definition) {
109             return parent::processValue($value, $isRoot);
110         }
111         if ($isRoot) {
112             if ($value->isSynthetic() || $value->isAbstract()) {
113                 return $value;
114             }
115             $this->currentDefinition = $value;
116         } elseif ($this->currentDefinition === $value) {
117             return $value;
118         }
119         $this->lazy = false;
120
121         $this->processValue($value->getFactory());
122         $this->processValue($value->getArguments());
123
124         if (!$this->onlyConstructorArguments) {
125             $this->processValue($value->getProperties());
126             $this->processValue($value->getMethodCalls());
127             $this->processValue($value->getConfigurator());
128         }
129         $this->lazy = $lazy;
130
131         return $value;
132     }
133
134     /**
135      * Returns a service definition given the full name or an alias.
136      *
137      * @param string $id A full id or alias for a service definition
138      *
139      * @return Definition|null The definition related to the supplied id
140      */
141     private function getDefinition($id)
142     {
143         return null === $id ? null : $this->container->getDefinition($id);
144     }
145
146     private function getDefinitionId($id)
147     {
148         while ($this->container->hasAlias($id)) {
149             $id = (string) $this->container->getAlias($id);
150         }
151
152         if (!$this->container->hasDefinition($id)) {
153             return;
154         }
155
156         return $this->container->normalizeId($id);
157     }
158
159     private function getExpressionLanguage()
160     {
161         if (null === $this->expressionLanguage) {
162             if (!class_exists(ExpressionLanguage::class)) {
163                 throw new RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
164             }
165
166             $providers = $this->container->getExpressionLanguageProviders();
167             $this->expressionLanguage = new ExpressionLanguage(null, $providers, function ($arg) {
168                 if ('""' === substr_replace($arg, '', 1, -1)) {
169                     $id = stripcslashes(substr($arg, 1, -1));
170                     $id = $this->getDefinitionId($id);
171
172                     $this->graph->connect(
173                         $this->currentId,
174                         $this->currentDefinition,
175                         $id,
176                         $this->getDefinition($id)
177                     );
178                 }
179
180                 return sprintf('$this->get(%s)', $arg);
181             });
182         }
183
184         return $this->expressionLanguage;
185     }
186 }